Пример #1
0
  private long getThreadIdFor(IncomingMediaMessage retrieved)
      throws RecipientFormattingException, MmsException {
    if (retrieved.getGroupId() != null) {
      Recipients groupRecipients =
          RecipientFactory.getRecipientsFromString(context, retrieved.getGroupId(), true);
      return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipients);
    }

    String localNumber;
    Set<String> group = new HashSet<>();

    if (retrieved.getAddresses().getFrom() == null) {
      throw new MmsException("FROM value in PduHeaders did not exist.");
    }

    group.add(retrieved.getAddresses().getFrom());

    if (TextSecurePreferences.isPushRegistered(context)) {
      localNumber = TextSecurePreferences.getLocalNumber(context);
    } else {
      localNumber = ServiceUtil.getTelephonyManager(context).getLine1Number();
    }

    for (String cc : retrieved.getAddresses().getCc()) {
      PhoneNumberUtil.MatchType match;

      if (localNumber == null) match = PhoneNumberUtil.MatchType.NO_MATCH;
      else match = PhoneNumberUtil.getInstance().isNumberMatch(localNumber, cc);

      if (match == PhoneNumberUtil.MatchType.NO_MATCH
          || match == PhoneNumberUtil.MatchType.NOT_A_NUMBER) {
        group.add(cc);
      }
    }

    if (retrieved.getAddresses().getTo().size() > 1) {
      for (String to : retrieved.getAddresses().getTo()) {
        PhoneNumberUtil.MatchType match;

        if (localNumber == null) match = PhoneNumberUtil.MatchType.NO_MATCH;
        else match = PhoneNumberUtil.getInstance().isNumberMatch(localNumber, to);

        if (match == PhoneNumberUtil.MatchType.NO_MATCH
            || match == PhoneNumberUtil.MatchType.NOT_A_NUMBER) {
          group.add(to);
        }
      }
    }

    String recipientsList = Util.join(group, ",");
    Recipients recipients =
        RecipientFactory.getRecipientsFromString(context, recipientsList, false);

    return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
  }
Пример #2
0
 private long getThreadIdFor(@NonNull NotificationInd notification) {
   String fromString =
       notification.getFrom() != null && notification.getFrom().getTextString() != null
           ? Util.toIsoString(notification.getFrom().getTextString())
           : "";
   Recipients recipients = RecipientFactory.getRecipientsFromString(context, fromString, false);
   if (recipients.isEmpty())
     recipients =
         RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), false);
   return DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
 }
Пример #3
0
    private Recipients getRecipientsFor(String address) {
      if (TextUtils.isEmpty(address) || address.equals("insert-address-token")) {
        return RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), true);
      }

      Recipients recipients = RecipientFactory.getRecipientsFromString(context, address, true);

      if (recipients == null || recipients.isEmpty()) {
        return RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), true);
      }

      return recipients;
    }
Пример #4
0
    private Recipients getRecipientsFor(String address) {
      if (address != null) {
        Recipients recipients = RecipientFactory.getRecipientsFromString(context, address, true);

        if (recipients == null || recipients.isEmpty()) {
          return RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), true);
        }

        return recipients;
      } else {
        Log.w(TAG, "getRecipientsFor() address is null");
        return RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), true);
      }
    }
Пример #5
0
    public ThreadRecord getCurrent() {
      long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
      String recipientId =
          cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.RECIPIENT_IDS));
      Recipients recipients = RecipientFactory.getRecipientsForIds(context, recipientId, true);

      DisplayRecord.Body body = getPlaintextBody(cursor);
      long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
      long count = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.MESSAGE_COUNT));
      long read = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.READ));
      long type = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.SNIPPET_TYPE));
      int distributionType = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.TYPE));
      boolean archived = cursor.getInt(cursor.getColumnIndex(ThreadDatabase.ARCHIVED)) != 0;
      int status = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.STATUS));
      int receiptCount = cursor.getInt(cursor.getColumnIndexOrThrow(ThreadDatabase.RECEIPT_COUNT));
      Uri snippetUri = getSnippetUri(cursor);

      return new ThreadRecord(
          context,
          body,
          snippetUri,
          recipients,
          date,
          count,
          read == 1,
          threadId,
          receiptCount,
          status,
          type,
          distributionType,
          archived);
    }
  @Override
  public List<Integer> getSubDeviceSessions(String name) {
    long recipientId =
        RecipientFactory.getRecipientsFromString(context, name, true)
            .getPrimaryRecipient()
            .getRecipientId();
    List<Integer> results = new LinkedList<>();
    File parent = getSessionDirectory();
    String[] children = parent.list();

    if (children == null) return results;

    for (String child : children) {
      try {
        String[] parts = child.split("[.]", 2);
        long sessionRecipientId = Long.parseLong(parts[0]);

        if (sessionRecipientId == recipientId && parts.length > 1) {
          results.add(Integer.parseInt(parts[1]));
        }
      } catch (NumberFormatException e) {
        Log.w(TAG, e);
      }
    }

    return results;
  }
Пример #7
0
  private @NonNull Pair<Long, Long> insertCallLog(
      @NonNull String number, long type, boolean unread) {
    Recipients recipients = RecipientFactory.getRecipientsFromString(context, number, true);
    long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);

    ContentValues values = new ContentValues(6);
    values.put(ADDRESS, number);
    values.put(ADDRESS_DEVICE_ID, 1);
    values.put(DATE_RECEIVED, System.currentTimeMillis());
    values.put(DATE_SENT, System.currentTimeMillis());
    values.put(READ, unread ? 0 : 1);
    values.put(TYPE, type);
    values.put(THREAD_ID, threadId);

    SQLiteDatabase db = databaseHelper.getWritableDatabase();
    long messageId = db.insert(TABLE_NAME, null, values);

    DatabaseFactory.getThreadDatabase(context).update(threadId, true);
    notifyConversationListeners(threadId);
    jobManager.add(new TrimThreadJob(context, threadId));

    if (unread) {
      DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
    }

    return new Pair<>(messageId, threadId);
  }
Пример #8
0
  private void handleCommonRegistration(
      MasterSecret masterSecret, TextSecureAccountManager accountManager, String number)
      throws IOException {
    setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number));
    Recipient self =
        RecipientFactory.getRecipientsFromString(this, number, false).getPrimaryRecipient();
    IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(this, masterSecret);
    List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(this, masterSecret);
    PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this, masterSecret);
    SignedPreKeyRecord signedPreKey =
        PreKeyUtil.generateSignedPreKey(this, masterSecret, identityKey);
    accountManager.setPreKeys(identityKey.getPublicKey(), lastResort, signedPreKey, records);

    setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));

    String gcmRegistrationId = "";
    accountManager.setGcmId(Optional.of(gcmRegistrationId));

    TextSecurePreferences.setGcmRegistrationId(this, gcmRegistrationId);
    TextSecurePreferences.setWebsocketRegistered(this, true);

    DatabaseFactory.getIdentityDatabase(this)
        .saveIdentity(masterSecret, self.getRecipientId(), identityKey.getPublicKey());
    DirectoryHelper.refreshDirectory(this, accountManager, number);

    DirectoryRefreshListener.schedule(this);
  }
Пример #9
0
  private boolean isBlocked(IncomingTextMessage message) {
    if (message.getSender() != null) {
      Recipients recipients =
          RecipientFactory.getRecipientsFromString(context, message.getSender(), false);
      return recipients.isBlocked();
    }

    return false;
  }
  private String getSessionName(AxolotlAddress axolotlAddress) {
    Recipient recipient =
        RecipientFactory.getRecipientsFromString(context, axolotlAddress.getName(), true)
            .getPrimaryRecipient();
    long recipientId = recipient.getRecipientId();
    int deviceId = axolotlAddress.getDeviceId();

    return recipientId + (deviceId == TextSecureAddress.DEFAULT_DEVICE_ID ? "" : "." + deviceId);
  }
 @Override
 protected Recipients doInBackground(Void... params) {
   try {
     String groupId = recipients.getPrimaryRecipient().getNumber();
     return DatabaseFactory.getGroupDatabase(context)
         .getGroupMembers(GroupUtil.getDecodedId(groupId), true);
   } catch (IOException e) {
     Log.w(TAG, e);
     return RecipientFactory.getRecipientsFor(context, new LinkedList<Recipient>(), true);
   }
 }
Пример #12
0
  public OutgoingMediaMessage getOutgoingMessage(MasterSecret masterSecret, long messageId)
      throws MmsException, NoSuchMessageException {
    MmsAddressDatabase addr = DatabaseFactory.getMmsAddressDatabase(context);
    AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context);
    Cursor cursor = null;

    try {
      cursor = rawQuery(RAW_ID_WHERE, new String[] {String.valueOf(messageId)});

      if (cursor != null && cursor.moveToNext()) {
        long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
        String messageText = cursor.getString(cursor.getColumnIndexOrThrow(BODY));
        long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT));
        List<Attachment> attachments =
            new LinkedList<Attachment>(attachmentDatabase.getAttachmentsForMessage(messageId));
        MmsAddresses addresses = addr.getAddressesForId(messageId);
        List<String> destinations = new LinkedList<>();
        String body = getDecryptedBody(masterSecret, messageText, outboxType);

        destinations.addAll(addresses.getBcc());
        destinations.addAll(addresses.getCc());
        destinations.addAll(addresses.getTo());

        Recipients recipients =
            RecipientFactory.getRecipientsFromStrings(context, destinations, false);

        if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
          return new OutgoingGroupMediaMessage(recipients, body, attachments, timestamp);
        }

        OutgoingMediaMessage message =
            new OutgoingMediaMessage(
                recipients,
                body,
                attachments,
                timestamp,
                !addresses.getBcc().isEmpty()
                    ? ThreadDatabase.DistributionTypes.BROADCAST
                    : ThreadDatabase.DistributionTypes.DEFAULT);
        if (Types.isSecureType(outboxType)) {
          return new OutgoingSecureMediaMessage(message);
        }

        return message;
      }

      throw new NoSuchMessageException("No record found for id: " + messageId);
    } catch (IOException e) {
      throw new MmsException(e);
    } finally {
      if (cursor != null) cursor.close();
    }
  }
Пример #13
0
    public GroupDescription(@NonNull Context context, @Nullable GroupContext groupContext) {
      this.context = context.getApplicationContext();
      this.groupContext = groupContext;

      if (groupContext == null || groupContext.getMembersList().isEmpty()) {
        this.members = null;
      } else {
        this.members =
            RecipientFactory.getRecipientsFromString(
                context, Util.join(groupContext.getMembersList(), ", "), true);
      }
    }
  private @Nullable AxolotlAddress getAddressName(File sessionFile) {
    try {
      String[] parts = sessionFile.getName().split("[.]");
      Recipient recipient =
          RecipientFactory.getRecipientForId(context, Integer.valueOf(parts[0]), true);

      int deviceId;

      if (parts.length > 1) deviceId = Integer.parseInt(parts[1]);
      else deviceId = TextSecureAddress.DEFAULT_DEVICE_ID;

      return new AxolotlAddress(recipient.getNumber(), deviceId);
    } catch (NumberFormatException e) {
      Log.w(TAG, e);
      return null;
    }
  }
Пример #15
0
  public @Nullable Recipients getRecipientsForThreadId(long threadId) {
    SQLiteDatabase db = databaseHelper.getReadableDatabase();
    Cursor cursor = null;

    try {
      cursor =
          db.query(TABLE_NAME, null, ID + " = ?", new String[] {threadId + ""}, null, null, null);

      if (cursor != null && cursor.moveToFirst()) {
        String recipientIds = cursor.getString(cursor.getColumnIndexOrThrow(RECIPIENT_IDS));
        return RecipientFactory.getRecipientsForIds(context, recipientIds, false);
      }
    } finally {
      if (cursor != null) cursor.close();
    }

    return null;
  }
Пример #16
0
  private void initializeResources() {
    recipients =
        RecipientFactory.getRecipientsForIds(
            this, getIntent().getStringExtra(RECIPIENTS_EXTRA), true);
    threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
    distributionType =
        getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
    sendButton = (ImageButton) findViewById(R.id.send_button);
    composeText = (EditText) findViewById(R.id.embedded_text_editor);
    masterSecret = getIntent().getParcelableExtra(MASTER_SECRET_EXTRA);
    charactersLeft = (TextView) findViewById(R.id.space_left);
    emojiDrawer = (EmojiDrawer) findViewById(R.id.emoji_drawer);
    emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      emojiToggle.setVisibility(View.GONE);
    }

    attachmentAdapter = new AttachmentTypeSelectorAdapter(this);
    attachmentManager = new AttachmentManager(this, this);

    SendButtonListener sendButtonListener = new SendButtonListener();
    ComposeKeyPressedListener composeKeyPressedListener = new ComposeKeyPressedListener();

    sendButton.setOnClickListener(sendButtonListener);
    sendButton.setEnabled(true);
    composeText.setOnKeyListener(composeKeyPressedListener);
    composeText.addTextChangedListener(composeKeyPressedListener);
    composeText.setOnEditorActionListener(sendButtonListener);
    composeText.setOnClickListener(composeKeyPressedListener);
    emojiDrawer.setComposeEditText(composeText);
    emojiToggle.setOnClickListener(new EmojiToggleListener());

    recipients.addListener(
        new RecipientModifiedListener() {
          @Override
          public void onModified(Recipient recipient) {
            initializeTitleBar();
          }
        });

    registerForContextMenu(sendButton);
  }
  private static Recipients getOurRecipients(Context context, String theirRecipients) {
    StringTokenizer tokenizer = new StringTokenizer(theirRecipients.trim(), " ");
    StringBuilder sb = new StringBuilder();

    while (tokenizer.hasMoreTokens()) {
      String theirRecipientId = tokenizer.nextToken();
      String address = getTheirCanonicalAddress(context, theirRecipientId);

      if (address == null) continue;

      if (sb.length() != 0) sb.append(',');

      sb.append(address);
    }

    try {
      if (sb.length() == 0) return null;
      else return RecipientFactory.getRecipientsFromString(context, sb.toString());
    } catch (RecipientFormattingException rfe) {
      Log.w("SmsMigrator", rfe);
      return null;
    }
  }
  private void createConversationIfNecessary(Intent intent) {
    long thread = intent.getLongExtra("thread_id", -1L);
    Recipients recipients = null;

    if (intent.getAction() != null && intent.getAction().equals("android.intent.action.SENDTO")) {
      try {
        recipients =
            RecipientFactory.getRecipientsFromString(
                this, intent.getData().getSchemeSpecificPart());
        thread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipients);
      } catch (RecipientFormattingException rfe) {
        recipients = null;
      }
    } else {
      recipients = intent.getParcelableExtra("recipients");
    }

    if (recipients != null) {
      createConversation(thread, recipients);
      intent.putExtra("thread_id", -1L);
      intent.putExtra("recipients", (Parcelable) null);
      intent.setAction(null);
    }
  }
Пример #19
0
  protected Pair<Long, Long> insertMessageInbox(IncomingTextMessage message, long type) {
    if (message.isJoined()) {
      type = (type & (Types.TOTAL_MASK - Types.BASE_TYPE_MASK)) | Types.JOINED_TYPE;
    } else if (message.isPreKeyBundle()) {
      type |= Types.KEY_EXCHANGE_BIT | Types.KEY_EXCHANGE_BUNDLE_BIT;
    } else if (message.isSecureMessage()) {
      type |= Types.SECURE_MESSAGE_BIT;
    } else if (message.isGroup()) {
      type |= Types.SECURE_MESSAGE_BIT;
      if (((IncomingGroupMessage) message).isUpdate()) type |= Types.GROUP_UPDATE_BIT;
      else if (((IncomingGroupMessage) message).isQuit()) type |= Types.GROUP_QUIT_BIT;
    } else if (message.isEndSession()) {
      type |= Types.SECURE_MESSAGE_BIT;
      type |= Types.END_SESSION_BIT;
    }

    if (message.isPush()) type |= Types.PUSH_MESSAGE_BIT;

    Recipients recipients;

    if (message.getSender() != null) {
      recipients = RecipientFactory.getRecipientsFromString(context, message.getSender(), true);
    } else {
      Log.w(TAG, "Sender is null, returning unknown recipient");
      recipients =
          RecipientFactory.getRecipientsFor(context, Recipient.getUnknownRecipient(), false);
    }

    Recipients groupRecipients;

    if (message.getGroupId() == null) {
      groupRecipients = null;
    } else {
      groupRecipients =
          RecipientFactory.getRecipientsFromString(context, message.getGroupId(), true);
    }

    boolean unread =
        org.thoughtcrime.securesms.util.Util.isDefaultSmsProvider(context)
            || message.isSecureMessage()
            || message.isPreKeyBundle();

    long threadId;

    if (groupRecipients == null)
      threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);
    else threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipients);

    ContentValues values = new ContentValues(6);
    values.put(ADDRESS, message.getSender());
    values.put(ADDRESS_DEVICE_ID, message.getSenderDeviceId());
    values.put(DATE_RECEIVED, System.currentTimeMillis());
    values.put(DATE_SENT, message.getSentTimestampMillis());
    values.put(PROTOCOL, message.getProtocol());
    values.put(READ, unread ? 0 : 1);

    if (!TextUtils.isEmpty(message.getPseudoSubject()))
      values.put(SUBJECT, message.getPseudoSubject());

    values.put(REPLY_PATH_PRESENT, message.isReplyPathPresent());
    values.put(SERVICE_CENTER, message.getServiceCenterAddress());
    values.put(BODY, message.getMessageBody());
    values.put(TYPE, type);
    values.put(THREAD_ID, threadId);

    SQLiteDatabase db = databaseHelper.getWritableDatabase();
    long messageId = db.insert(TABLE_NAME, null, values);

    if (unread) {
      DatabaseFactory.getThreadDatabase(context).setUnread(threadId);
    }

    DatabaseFactory.getThreadDatabase(context).update(threadId, true);
    notifyConversationListeners(threadId);
    jobManager.add(new TrimThreadJob(context, threadId));

    return new Pair<>(messageId, threadId);
  }