示例#1
0
  private static void sendInThreadNotification(Context context, Recipients recipients) {
    try {
      if (!SMSSecurePreferences.isInThreadNotifications(context)) {
        return;
      }

      Uri uri = recipients != null ? recipients.getRingtone() : null;

      if (uri == null) {
        String ringtone = SMSSecurePreferences.getNotificationRingtone(context);

        if (ringtone == null) {
          Log.w(TAG, "ringtone preference was null.");
          return;
        } else {
          uri = Uri.parse(ringtone);
        }
      }

      if (uri == null) {
        Log.w(
            TAG,
            "couldn't parse ringtone uri " + SMSSecurePreferences.getNotificationRingtone(context));
        return;
      }

      MediaPlayer player = new MediaPlayer();
      player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
      player.setDataSource(context, uri);
      player.setLooping(false);
      player.setVolume(0.25f, 0.25f);
      player.prepare();

      final AudioManager audioManager =
          ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE));

      audioManager.requestAudioFocus(
          null, AudioManager.STREAM_NOTIFICATION, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

      player.setOnCompletionListener(
          new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
              audioManager.abandonAudioFocus(null);
            }
          });

      player.start();
    } catch (IOException ioe) {
      Log.w("MessageNotifier", ioe);
    }
  }
示例#2
0
  public static void updateNotification(Context context, MasterSecret masterSecret) {
    if (!SMSSecurePreferences.isNotificationsEnabled(context)) {
      return;
    }

    updateNotification(context, masterSecret, false, 0);
  }
示例#3
0
  private static void sendMultipleThreadNotification(
      Context context, NotificationState notificationState, boolean signal) {
    MultipleRecipientNotificationBuilder builder =
        new MultipleRecipientNotificationBuilder(
            context, SMSSecurePreferences.getNotificationPrivacy(context));
    List<NotificationItem> notifications = notificationState.getNotifications();

    builder.setMessageCount(
        notificationState.getMessageCount(), notificationState.getThreadCount());
    builder.setMostRecentSender(notifications.get(0).getIndividualRecipient());

    long timestamp = notifications.get(0).getTimestamp();
    if (timestamp != 0) builder.setWhen(timestamp);

    builder.addActions(notificationState.getMarkAsReadIntent(context));

    ListIterator<NotificationItem> iterator = notifications.listIterator(0);

    while (iterator.hasNext()) {
      NotificationItem item = iterator.next();
      builder.addMessageBody(item.getIndividualRecipient(), item.getText());
    }

    if (signal) {
      builder.setAlarms(notificationState.getRingtone(), notificationState.getVibrate());
      builder.setTicker(notifications.get(0).getText());
    }

    ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
        .notify(NOTIFICATION_ID, builder.build());
  }
示例#4
0
  public void setTransport(TransportOption transport) {
    final String enterKeyType = SMSSecurePreferences.getEnterKeyType(getContext());

    int imeOptions = (getImeOptions() & ~EditorInfo.IME_MASK_ACTION) | EditorInfo.IME_ACTION_SEND;
    int inputType = getInputType();

    if (isLandscape()) setImeActionLabel(transport.getComposeHint(), EditorInfo.IME_ACTION_SEND);
    else setImeActionLabel(null, 0);

    inputType =
        !isLandscape() && enterKeyType.equals("send")
            ? inputType & ~InputType.TYPE_TEXT_FLAG_MULTI_LINE
            : inputType | InputType.TYPE_TEXT_FLAG_MULTI_LINE;

    inputType =
        enterKeyType.equals("emoji")
            ? inputType | InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE
            : inputType & ~InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE;

    imeOptions =
        enterKeyType.equals("send")
            ? imeOptions & ~EditorInfo.IME_FLAG_NO_ENTER_ACTION
            : imeOptions | EditorInfo.IME_FLAG_NO_ENTER_ACTION;

    setInputType(inputType);
    setImeOptions(imeOptions);
    setHint(transport.getComposeHint());
  }
示例#5
0
  private static NotificationState constructNotificationState(
      Context context, MasterSecret masterSecret, Cursor cursor) {
    NotificationState notificationState = new NotificationState();
    MessageRecord record;
    MmsSmsDatabase.Reader reader;

    if (masterSecret == null) reader = DatabaseFactory.getMmsSmsDatabase(context).readerFor(cursor);
    else reader = DatabaseFactory.getMmsSmsDatabase(context).readerFor(cursor, masterSecret);

    while ((record = reader.getNext()) != null) {
      Recipient recipient = record.getIndividualRecipient();
      Recipients recipients = record.getRecipients();
      long threadId = record.getThreadId();
      CharSequence body = record.getDisplayBody();
      Recipients threadRecipients = null;
      ListenableFutureTask<SlideDeck> slideDeck = null;
      long timestamp;

      if (SMSSecurePreferences.showSentTime(context)) timestamp = record.getDateSent();
      else timestamp = record.getDateReceived();

      if (threadId != -1) {
        threadRecipients =
            DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);
      }

      if (SmsDatabase.Types.isDecryptInProgressType(record.getType())
          || !record.getBody().isPlaintext()) {
        body = SpanUtil.italic(context.getString(R.string.MessageNotifier_encrypted_message));
      } else if (record.isMms() && TextUtils.isEmpty(body)) {
        body = SpanUtil.italic(context.getString(R.string.MessageNotifier_media_message));
        slideDeck = ((MediaMmsMessageRecord) record).getSlideDeckFuture();
      } else if (record.isMms() && !record.isMmsNotification()) {
        String message = context.getString(R.string.MessageNotifier_media_message_with_text, body);
        int italicLength = message.length() - body.length();
        body = SpanUtil.italic(message, italicLength);
        slideDeck = ((MediaMmsMessageRecord) record).getSlideDeckFuture();
      }

      if (threadRecipients == null || !threadRecipients.isMuted()) {
        notificationState.addNotification(
            new NotificationItem(
                recipient, recipients, threadRecipients, threadId, body, timestamp, slideDeck));
      }
    }

    reader.close();
    return notificationState;
  }
示例#6
0
  private static void scheduleReminder(Context context, int count) {
    if (count >= SMSSecurePreferences.getRepeatAlertsCount(context)) {
      return;
    }

    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent alarmIntent = new Intent(ReminderReceiver.REMINDER_ACTION);
    alarmIntent.putExtra("reminder_count", count);

    PendingIntent pendingIntent =
        PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    long timeout = TimeUnit.MINUTES.toMillis(2);

    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent);
  }
示例#7
0
  private static JobParameters constructParameters(Context context, String name) {
    JobParameters.Builder builder =
        JobParameters.newBuilder()
            .withPersistence()
            .withRequirement(new MasterSecretRequirement(context))
            .withRetryCount(15)
            .withGroupId(name);

    if (SMSSecurePreferences.isWifiSmsEnabled(context)) {
      builder.withRequirement(new NetworkOrServiceRequirement(context));
    } else {
      builder.withRequirement(new ServiceRequirement(context));
    }

    return builder.create();
  }
示例#8
0
  private ArrayList<PendingIntent> constructDeliveredIntents(
      long messageId, long type, ArrayList<String> messages) {
    if (!SMSSecurePreferences.isSmsDeliveryReportsEnabled(context)) {
      return null;
    }

    ArrayList<PendingIntent> deliveredIntents = new ArrayList<>(messages.size());

    for (String ignored : messages) {
      deliveredIntents.add(
          PendingIntent.getBroadcast(
              context, 0, constructDeliveredIntent(context, messageId, type), 0));
    }

    return deliveredIntents;
  }
示例#9
0
  public static void notifyMessageDeliveryFailed(
      Context context, Recipients recipients, long threadId) {
    if (visibleThread == threadId) {
      sendInThreadNotification(context, recipients);
    } else {
      Intent intent = new Intent(context, ConversationActivity.class);
      intent.putExtra(ConversationActivity.RECIPIENTS_EXTRA, recipients.getIds());
      intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, threadId);
      intent.setData((Uri.parse("custom://" + System.currentTimeMillis())));

      FailedNotificationBuilder builder =
          new FailedNotificationBuilder(
              context, SMSSecurePreferences.getNotificationPrivacy(context), intent);
      ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
          .notify((int) threadId, builder.build());
    }
  }
示例#10
0
  private static void sendSingleThreadNotification(
      Context context,
      MasterSecret masterSecret,
      NotificationState notificationState,
      boolean signal) {
    if (notificationState.getNotifications().isEmpty()) {
      ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
          .cancel(NOTIFICATION_ID);
      return;
    }

    SingleRecipientNotificationBuilder builder =
        new SingleRecipientNotificationBuilder(
            context, masterSecret, SMSSecurePreferences.getNotificationPrivacy(context));
    List<NotificationItem> notifications = notificationState.getNotifications();

    builder.setSender(notifications.get(0).getIndividualRecipient());
    builder.setMessageCount(notificationState.getMessageCount());
    builder.setPrimaryMessageBody(
        notifications.get(0).getText(), notifications.get(0).getSlideDeck());
    builder.setContentIntent(notifications.get(0).getPendingIntent(context));

    long timestamp = notifications.get(0).getTimestamp();
    if (timestamp != 0) builder.setWhen(timestamp);

    builder.addActions(
        masterSecret,
        notificationState.getMarkAsReadIntent(context),
        notificationState.getQuickReplyIntent(context, notifications.get(0).getRecipients()),
        notificationState.getWearableReplyIntent(context, notifications.get(0).getRecipients()));

    ListIterator<NotificationItem> iterator = notifications.listIterator(notifications.size());

    while (iterator.hasPrevious()) {
      builder.addMessageBody(iterator.previous().getText());
    }

    if (signal) {
      builder.setAlarms(notificationState.getRingtone(), notificationState.getVibrate());
      builder.setTicker(
          notifications.get(0).getIndividualRecipient(), notifications.get(0).getText());
    }

    ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
        .notify(NOTIFICATION_ID, builder.build());
  }
示例#11
0
  public static void updateNotification(Context context, MasterSecret masterSecret, long threadId) {
    Recipients recipients =
        DatabaseFactory.getThreadDatabase(context).getRecipientsForThreadId(threadId);

    if (!SMSSecurePreferences.isNotificationsEnabled(context)
        || (recipients != null && recipients.isMuted())) {
      return;
    }

    if (visibleThread == threadId) {
      ThreadDatabase threads = DatabaseFactory.getThreadDatabase(context);
      threads.setRead(threadId);
      sendInThreadNotification(context, threads.getRecipientsForThreadId(threadId));
    } else {
      updateNotification(context, masterSecret, true, 0);
    }
  }