/**
   * Chooses a activity to handle the current intent. This will result in adding a historical record
   * for that action and construct intent with its component name set such that it can be
   * immediately started by the client.
   *
   * <p><strong>Note:</strong> By calling this method the client guarantees that the returned intent
   * will be started. This intent is returned to the client solely to let additional customization
   * before the start.
   *
   * @return An {@link Intent} for launching the activity or null if the policy has consumed the
   *     intent or there is not current intent set via {@link #setIntent(Intent)}.
   * @see HistoricalRecord
   * @see OnChooseActivityListener
   */
  public Intent chooseActivity(int index) {
    synchronized (mInstanceLock) {
      if (mIntent == null) {
        return null;
      }

      ensureConsistentState();

      ActivityResolveInfo chosenActivity = mActivities.get(index);

      ComponentName chosenName =
          new ComponentName(
              chosenActivity.resolveInfo.activityInfo.packageName,
              chosenActivity.resolveInfo.activityInfo.name);

      Intent choiceIntent = new Intent(mIntent);
      choiceIntent.setComponent(chosenName);

      if (mActivityChoserModelPolicy != null) {
        // Do not allow the policy to change the intent.
        Intent choiceIntentCopy = new Intent(choiceIntent);
        final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this, choiceIntentCopy);
        if (handled) {
          return null;
        }
      }

      HistoricalRecord historicalRecord =
          new HistoricalRecord(
              chosenName, System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
      addHisoricalRecord(historicalRecord);

      return choiceIntent;
    }
  }
 /**
  * Gets the default activity, The default activity is defined as the one with highest rank i.e.
  * the first one in the list of activities that can handle the intent.
  *
  * @return The default activity, <code>null</code> id not activities.
  * @see #getActivity(int)
  */
 public ResolveInfo getDefaultActivity() {
   synchronized (mInstanceLock) {
     ensureConsistentState();
     if (!mActivities.isEmpty()) {
       return mActivities.get(0).resolveInfo;
     }
   }
   return null;
 }
 /**
  * Sets an intent for which to choose a activity.
  *
  * <p><strong>Note:</strong> Clients must set only semantically similar intents for each data
  * model.
  *
  * <p>
  *
  * @param intent The intent.
  */
 public void setIntent(Intent intent) {
   synchronized (mInstanceLock) {
     if (mIntent == intent) {
       return;
     }
     mIntent = intent;
     mReloadActivities = true;
     ensureConsistentState();
   }
 }
 /**
  * Gets the index of a the given activity.
  *
  * @param activity The activity index.
  * @return The index if found, -1 otherwise.
  */
 public int getActivityIndex(ResolveInfo activity) {
   synchronized (mInstanceLock) {
     ensureConsistentState();
     List<ActivityResolveInfo> activities = mActivities;
     final int activityCount = activities.size();
     for (int i = 0; i < activityCount; i++) {
       ActivityResolveInfo currentActivity = activities.get(i);
       if (currentActivity.resolveInfo == activity) {
         return i;
       }
     }
     return INVALID_INDEX;
   }
 }
  /**
   * Sets the default activity. The default activity is set by adding a historical record with
   * weight high enough that this activity will become the highest ranked. Such a strategy
   * guarantees that the default will eventually change if not used. Also the weight of the record
   * for setting a default is inflated with a constant amount to guarantee that it will stay as
   * default for awhile.
   *
   * @param index The index of the activity to set as default.
   */
  public void setDefaultActivity(int index) {
    synchronized (mInstanceLock) {
      ensureConsistentState();

      ActivityResolveInfo newDefaultActivity = mActivities.get(index);
      ActivityResolveInfo oldDefaultActivity = mActivities.get(0);

      final float weight;
      if (oldDefaultActivity != null) {
        // Add a record with weight enough to boost the chosen at the top.
        weight = oldDefaultActivity.weight - newDefaultActivity.weight + DEFAULT_ACTIVITY_INFLATION;
      } else {
        weight = DEFAULT_HISTORICAL_RECORD_WEIGHT;
      }

      ComponentName defaultName =
          new ComponentName(
              newDefaultActivity.resolveInfo.activityInfo.packageName,
              newDefaultActivity.resolveInfo.activityInfo.name);
      HistoricalRecord historicalRecord =
          new HistoricalRecord(defaultName, System.currentTimeMillis(), weight);
      addHisoricalRecord(historicalRecord);
    }
  }
 /**
  * Gets the history size.
  *
  * @return The history size.
  */
 public int getHistorySize() {
   synchronized (mInstanceLock) {
     ensureConsistentState();
     return mHistoricalRecords.size();
   }
 }
 /**
  * Gets an activity at a given index.
  *
  * @return The activity.
  * @see ActivityResolveInfo
  * @see #setIntent(Intent)
  */
 public ResolveInfo getActivity(int index) {
   synchronized (mInstanceLock) {
     ensureConsistentState();
     return mActivities.get(index).resolveInfo;
   }
 }
 /**
  * Gets the number of activities that can handle the intent.
  *
  * @return The activity count.
  * @see #setIntent(Intent)
  */
 public int getActivityCount() {
   synchronized (mInstanceLock) {
     ensureConsistentState();
     return mActivities.size();
   }
 }