public void saveCategory(Category newCategory) {
   CategoryTree tree = loadCategories();
   if (newCategory.id > 0) {
     LongSparseArray<Category> map = tree.asIdMap();
     Category oldCategory = map.get(newCategory.id);
     if (oldCategory != null) {
       oldCategory.title = newCategory.title;
       Category oldParent = map.get(oldCategory.parentId);
       Category newParent = map.get(newCategory.parentId);
       if (newParent != oldParent) {
         if (oldParent != null) {
           oldParent.removeChild(oldCategory);
         } else {
           tree.removeRoot(oldCategory);
         }
         if (newParent != null) {
           newParent.addChild(oldCategory);
         } else {
           tree.addRoot(oldCategory);
         }
       }
     }
   } else {
     if (newCategory.parentId > 0) {
       LongSparseArray<Category> map = tree.asIdMap();
       Category parent = map.get(newCategory.parentId);
       if (parent != null) {
         parent.addChild(newCategory);
       }
     } else {
       tree.addRoot(newCategory);
     }
   }
   saveCategories(tree);
 }
  public DownloadInfoRunnable getDownload(long id) {

    if (downloads.get(id) != null) {
      return downloads.get(id);
    } else {
      return new DownloadInfoRunnable(manager, id);
    }
  }
 public int getUserColor(final long userId, final boolean ignoreCache) {
   if (userId == -1) return Color.TRANSPARENT;
   if (!ignoreCache && mUserColors.indexOfKey(userId) >= 0) return mUserColors.get(userId);
   final int color = mColorPreferences.getInt(Long.toString(userId), Color.TRANSPARENT);
   mUserColors.put(userId, color);
   return color;
 }
示例#4
0
  private void TL_BadMsgNotification(TL.Object obj) {
    int error_code = obj.getInt("error_code");

    Message msg = TLMessage.get(obj.getLong("bad_msg_id"));
    Common.logError("bad_msg: " + error_code + " " + msg.obj.name + ":" + msg.obj.type);

    if (error_code == 16 || error_code == 17) {
      time_delta = (int) ((cur_message_id >> 32) - Common.getUnixTime());
      last_message_id = 0;
    }

    if (error_code == 32 || error_code == 33) {
      Common.logError("cur seq: " + cur_msg_seq);
      Common.logError("old seq: " + seqno);
      if (!bad_seq) {
        session = GEN_session_id();
        seqno = 0;
        send_ping();
        bad_seq = true;
      }

      // seqno = cur_msg_seq + (cur_msg_seq % 2) + 100;
      //	session = GEN_session_id();
      //	seqno = 0;
    }

    if (obj.id == 0xedab447b) { // bad_server_salt
      server_salt = obj.getLong("new_server_salt");
      dcState.set("server_salt", server_salt);
    }

    retry(obj.getLong("bad_msg_id"));
  }
示例#5
0
  private void TL_RpcError(TL.Object obj) {
    int code = obj.getInt("error_code");
    String msg = obj.getString("error_message");

    Common.logError(String.format("rpc_error: %s (%d)\n", msg, code));

    Message req_msg = TLMessage.get(req_msg_id);
    if (req_msg == null) return;
    Common.logError("message object: " + req_msg.obj.name + ":" + req_msg.obj.type);

    int idx = msg.indexOf("_MIGRATE_");
    if (idx > 0) {
      String type = msg.substring(0, idx);

      String num = msg.substring(idx + 9);
      if ((idx = num.indexOf(":")) > 0) num = num.substring(0, idx);
      int dc_id = Integer.parseInt(num);
      Common.logError("redirect to dc: " + dc_id);

      MTProto m = MTProto.getConnection(dc_id, cb, reuseFlag);
      cb.onRedirect(m);
      if (type.equals("PHONE") || type.equals("NETWORK") || type.equals("USER")) dc_this = dc_id;

      m.sendMessage(req_msg);
    }
  }
示例#6
0
 public void retry(long message_id) {
   Common.logError("retry");
   Message msg = TLMessage.get(message_id);
   if (msg == null) return;
   TLMessage.delete(message_id);
   sendMessage(msg);
 }
示例#7
0
 private void TL_MsgsAck(TL.Object obj) {
   TL.Vector msg_ids = obj.getVector("msg_ids");
   for (int i = 0; i < msg_ids.count; i++) {
     Message msg = TLMessage.get(msg_ids.getLong(i));
     if (msg != null) msg.accepted = true;
     // TLMessage.delete(msg_ids.getLong(i));
   }
 }
示例#8
0
 private void TL_RpcResult(TL.Object obj) {
   req_msg_id = obj.getLong("req_msg_id");
   TL.Object result = obj.getObject("result");
   Message msg = TLMessage.get(req_msg_id);
   if (msg != null && msg.result != null)
     msg.result.onResultRPC(
         result, msg.param, result.name != null && result.name.equals("rpc_error"));
   process(result);
   TLMessage.delete(req_msg_id);
 }
  public void setReferrer(long id, String referrer) {
    try {

      DownloadInfoRunnable downloadInfoRunnable = downloads.get(id);
      if (downloadInfoRunnable != null) {
        downloadInfoRunnable.getDownloadExecutor().getApk().setReferrer(referrer);
      } else {
        Log.d("AptoideDownloadService", "Downloadinfo for referrer was null");
      }

    } catch (Exception e) {
      e.printStackTrace();
      Log.d("AptoideDownloadService", "error setting referrer");
    }
  }
 public void deleteCategoryById(long id) {
   if (id > 0) {
     CategoryTree tree = loadCategories();
     LongSparseArray<Category> map = tree.asIdMap();
     Category category = map.get(id);
     if (category != null) {
       Category parent = category.parent;
       if (parent == null) {
         tree.removeRoot(category);
       } else {
         parent.removeChild(category);
       }
       saveCategories(tree);
     }
   }
 }
  @Override
  public View getHeader(RecyclerView parent, int position) {
    long headerId = mAdapter.getHeaderId(position);

    View header = mHeaderViews.get(headerId);
    if (header == null) {
      // TODO - recycle views
      RecyclerView.ViewHolder viewHolder = mAdapter.onCreateHeaderViewHolder(parent);
      mAdapter.onBindHeaderViewHolder(viewHolder, position);
      header = viewHolder.itemView;
      if (header.getLayoutParams() == null) {
        header.setLayoutParams(
            new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
      }

      int widthSpec;
      int heightSpec;

      if (mOrientationProvider.getOrientation(parent) == LinearLayoutManager.VERTICAL) {
        widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
        heightSpec =
            View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
      } else {
        widthSpec =
            View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.UNSPECIFIED);
        heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.EXACTLY);
      }

      int childWidth =
          ViewGroup.getChildMeasureSpec(
              widthSpec,
              parent.getPaddingLeft() + parent.getPaddingRight(),
              header.getLayoutParams().width);
      int childHeight =
          ViewGroup.getChildMeasureSpec(
              heightSpec,
              parent.getPaddingTop() + parent.getPaddingBottom(),
              header.getLayoutParams().height);
      header.measure(childWidth, childHeight);
      header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight());
      mHeaderViews.put(headerId, header);
    }
    return header;
  }
  /** Called when one specific passphrase for keyId timed out. */
  private void removeTimeoutedPassphrase(long keyId) {

    CachedPassphrase cPass = mPassphraseCache.get(keyId);
    if (cPass != null) {
      if (cPass.mPassphrase != null) {
        // clean internal char[] from memory!
        cPass.mPassphrase.removeFromMemory();
      }
      // remove passphrase object
      mPassphraseCache.remove(keyId);
    }

    Log.d(
        Constants.TAG,
        "PassphraseCacheService Timeout of keyId " + keyId + ", removed from memory!");

    updateService();
  }
示例#13
0
  /**
   * Get the final moves that we want to upsync to the server, setting the status in the DB for all
   * rows to {@link #STATUS_PROCESSING} that are being updated and to {@link #STATUS_FAILED} for any
   * old updates. Messages whose sequence of pending moves results in a no-op (i.e. the message has
   * been moved back to its original folder) have their moves cleared from the DB without any
   * upsync.
   *
   * @param context A {@link Context}.
   * @param accountId The account we want to update.
   * @return The final moves to send to the server, or null if there are none.
   */
  public static List<MessageMove> getMoves(final Context context, final long accountId) {
    final ContentResolver cr = context.getContentResolver();
    final Cursor c = getCursor(cr, CONTENT_URI, ProjectionMoveQuery.PROJECTION, accountId);
    if (c == null) {
      return null;
    }

    // Collapse any rows in the cursor that are acting on the same message. We know the cursor
    // returned by getRowsToProcess is ordered from oldest to newest, and we use this fact to
    // get the original and final folder for the message.
    LongSparseArray<MessageMove> movesMap = new LongSparseArray();
    try {
      while (c.moveToNext()) {
        final long id = c.getLong(ProjectionMoveQuery.COLUMN_ID);
        final long messageKey = c.getLong(ProjectionMoveQuery.COLUMN_MESSAGE_KEY);
        final String serverId = c.getString(ProjectionMoveQuery.COLUMN_SERVER_ID);
        final long srcFolderKey = c.getLong(ProjectionMoveQuery.COLUMN_SRC_FOLDER_KEY);
        final long dstFolderKey = c.getLong(ProjectionMoveQuery.COLUMN_DST_FOLDER_KEY);
        final String srcFolderServerId =
            c.getString(ProjectionMoveQuery.COLUMN_SRC_FOLDER_SERVER_ID);
        final String dstFolderServerId =
            c.getString(ProjectionMoveQuery.COLUMN_DST_FOLDER_SERVER_ID);
        final MessageMove existingMove = movesMap.get(messageKey);
        if (existingMove != null) {
          if (existingMove.mLastId >= id) {
            LogUtils.w(LOG_TAG, "Moves were not in ascending id order");
          }
          if (!existingMove.mDstFolderServerId.equals(srcFolderServerId)
              || existingMove.mDstFolderKey != srcFolderKey) {
            LogUtils.w(LOG_TAG, "existing move's dst not same as this move's src");
          }
          existingMove.mDstFolderKey = dstFolderKey;
          existingMove.mDstFolderServerId = dstFolderServerId;
          existingMove.mLastId = id;
        } else {
          movesMap.put(
              messageKey,
              new MessageMove(
                  messageKey,
                  serverId,
                  id,
                  srcFolderKey,
                  dstFolderKey,
                  srcFolderServerId,
                  dstFolderServerId));
        }
      }
    } finally {
      c.close();
    }

    // Prune any no-op moves (i.e. messages that have been moved back to the initial folder).
    final int moveCount = movesMap.size();
    final long[] unmovedMessages = new long[moveCount];
    int unmovedMessagesCount = 0;
    final ArrayList<MessageMove> moves = new ArrayList(moveCount);
    for (int i = 0; i < movesMap.size(); ++i) {
      final MessageMove move = movesMap.valueAt(i);
      // We also treat changes without a server id as a no-op.
      if ((move.mServerId == null || move.mServerId.length() == 0)
          || move.mSrcFolderKey == move.mDstFolderKey) {
        unmovedMessages[unmovedMessagesCount] = move.mMessageKey;
        ++unmovedMessagesCount;
      } else {
        moves.add(move);
      }
    }
    if (unmovedMessagesCount != 0) {
      deleteRowsForMessages(cr, CONTENT_URI, unmovedMessages, unmovedMessagesCount);
    }
    if (moves.isEmpty()) {
      return null;
    }
    return moves;
  }
  /** Internal implementation to get cached passphrase. */
  private Passphrase getCachedPassphraseImpl(long masterKeyId, long subKeyId)
      throws ProviderHelper.NotFoundException {
    // on "none" key, just do nothing
    if (masterKeyId == Constants.key.none) {
      return null;
    }

    // passphrase for symmetric encryption?
    if (masterKeyId == Constants.key.symmetric) {
      Log.d(
          Constants.TAG,
          "PassphraseCacheService.getCachedPassphraseImpl() for symmetric encryption");
      CachedPassphrase cachedPassphrase = mPassphraseCache.get(Constants.key.symmetric);
      if (cachedPassphrase == null) {
        return null;
      }
      return cachedPassphrase.mPassphrase;
    }

    // try to get master key id which is used as an identifier for cached passphrases
    Log.d(
        Constants.TAG,
        "PassphraseCacheService.getCachedPassphraseImpl() for masterKeyId "
            + masterKeyId
            + ", subKeyId "
            + subKeyId);

    // get the type of key (from the database)
    CachedPublicKeyRing keyRing = new ProviderHelper(this).getCachedPublicKeyRing(masterKeyId);
    SecretKeyType keyType = keyRing.getSecretKeyType(subKeyId);

    switch (keyType) {
      case PASSPHRASE_EMPTY:
        return new Passphrase("");
      case UNAVAILABLE:
        throw new ProviderHelper.NotFoundException("secret key for this subkey is not available");
      case GNU_DUMMY:
        throw new ProviderHelper.NotFoundException(
            "secret key for stripped subkey is not available");
    }

    // get cached passphrase
    CachedPassphrase cachedPassphrase = mPassphraseCache.get(subKeyId);
    if (cachedPassphrase == null) {

      // If we cache strictly by subkey, exit early
      if (Preferences.getPreferences(mContext).getPassphraseCacheSubs()) {
        Log.d(
            Constants.TAG,
            "PassphraseCacheService: specific subkey passphrase not (yet) cached, returning null");
        // not really an error, just means the passphrase is not cached but not empty either
        return null;
      }

      if (subKeyId == masterKeyId) {
        Log.d(
            Constants.TAG,
            "PassphraseCacheService: masterkey passphrase not (yet) cached, returning null");
        // not really an error, just means the passphrase is not cached but not empty either
        return null;
      }

      cachedPassphrase = mPassphraseCache.get(masterKeyId);
      // If we cache strictly by subkey, exit early
      if (cachedPassphrase == null) {
        Log.d(
            Constants.TAG,
            "PassphraseCacheService: keyring passphrase not (yet) cached, returning null");
        // not really an error, just means the passphrase is not cached but not empty either
        return null;
      }
    }

    return cachedPassphrase.mPassphrase;
  }