Merge "Add alternate intents and refinement callbacks to ChooserActivity" into mnc-dev
This commit is contained in:
@@ -8282,6 +8282,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
|
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
|
||||||
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
|
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
|
||||||
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
|
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
|
||||||
|
field public static final java.lang.String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
|
field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
|
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
|
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
|
||||||
@@ -8293,6 +8294,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
|
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
|
||||||
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
|
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
|
||||||
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
|
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
|
||||||
|
field public static final java.lang.String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
|
||||||
field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
|
field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
|
||||||
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
|
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
|
||||||
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
|
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
|
||||||
@@ -8325,6 +8327,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
|
||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
|
||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list";
|
||||||
|
field public static final java.lang.String EXTRA_RESULT_RECEIVER = "android.intent.extra.RESULT_RECEIVER";
|
||||||
field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT";
|
field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT";
|
||||||
field public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
|
field public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
|
||||||
field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE";
|
field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE";
|
||||||
|
|||||||
@@ -8508,6 +8508,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
|
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
|
||||||
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
|
field public static final java.lang.String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
|
||||||
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
|
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
|
||||||
|
field public static final java.lang.String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
|
field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
|
field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
|
||||||
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
|
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
|
||||||
@@ -8519,6 +8520,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
|
field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
|
||||||
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
|
field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
|
||||||
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
|
field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
|
||||||
|
field public static final java.lang.String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
|
||||||
field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
|
field public static final java.lang.String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
|
||||||
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
|
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
|
||||||
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
|
field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
|
||||||
@@ -8554,6 +8556,7 @@ package android.content {
|
|||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
|
||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
|
||||||
field public static final java.lang.String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list";
|
field public static final java.lang.String EXTRA_RESTRICTIONS_LIST = "android.intent.extra.restrictions_list";
|
||||||
|
field public static final java.lang.String EXTRA_RESULT_RECEIVER = "android.intent.extra.RESULT_RECEIVER";
|
||||||
field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT";
|
field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT";
|
||||||
field public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
|
field public static final java.lang.String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
|
||||||
field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE";
|
field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE";
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package android.content;
|
package android.content;
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.os.ResultReceiver;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
@@ -3291,10 +3292,78 @@ public class Intent implements Parcelable, Cloneable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An Intent describing the choices you would like shown with
|
* An Intent describing the choices you would like shown with
|
||||||
* {@link #ACTION_PICK_ACTIVITY}.
|
* {@link #ACTION_PICK_ACTIVITY} or {@link #ACTION_CHOOSER}.
|
||||||
*/
|
*/
|
||||||
public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
|
public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Intent[] describing additional, alternate choices you would like shown with
|
||||||
|
* {@link #ACTION_CHOOSER}.
|
||||||
|
*
|
||||||
|
* <p>An app may be capable of providing several different payload types to complete a
|
||||||
|
* user's intended action. For example, an app invoking {@link #ACTION_SEND} to share photos
|
||||||
|
* with another app may use EXTRA_ALTERNATE_INTENTS to have the chooser transparently offer
|
||||||
|
* several different supported sending mechanisms for sharing, such as the actual "image/*"
|
||||||
|
* photo data or a hosted link where the photos can be viewed.</p>
|
||||||
|
*
|
||||||
|
* <p>The intent present in {@link #EXTRA_INTENT} will be treated as the
|
||||||
|
* first/primary/preferred intent in the set. Additional intents specified in
|
||||||
|
* this extra are ordered; by default intents that appear earlier in the array will be
|
||||||
|
* preferred over intents that appear later in the array as matches for the same
|
||||||
|
* target component. To alter this preference, a calling app may also supply
|
||||||
|
* {@link #EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER}.</p>
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link IntentSender} for an Activity that will be invoked when the user makes a selection
|
||||||
|
* from the chooser activity presented by {@link #ACTION_CHOOSER}.
|
||||||
|
*
|
||||||
|
* <p>An app preparing an action for another app to complete may wish to allow the user to
|
||||||
|
* disambiguate between several options for completing the action based on the chosen target
|
||||||
|
* or otherwise refine the action before it is invoked.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>When sent, this IntentSender may be filled in with the following extras:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #EXTRA_INTENT} The first intent that matched the user's chosen target</li>
|
||||||
|
* <li>{@link #EXTRA_ALTERNATE_INTENTS} Any additional intents that also matched the user's
|
||||||
|
* chosen target beyond the first</li>
|
||||||
|
* <li>{@link #EXTRA_RESULT_RECEIVER} A {@link ResultReceiver} that the refinement activity
|
||||||
|
* should fill in and send once the disambiguation is complete</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER
|
||||||
|
= "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link ResultReceiver} used to return data back to the sender.
|
||||||
|
*
|
||||||
|
* <p>Used to complete an app-specific
|
||||||
|
* {@link #EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER refinement} for {@link #ACTION_CHOOSER}.</p>
|
||||||
|
*
|
||||||
|
* <p>If {@link #EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER} is present in the intent
|
||||||
|
* used to start a {@link #ACTION_CHOOSER} activity this extra will be
|
||||||
|
* {@link #fillIn(Intent, int) filled in} to that {@link IntentSender} and sent
|
||||||
|
* when the user selects a target component from the chooser. It is up to the recipient
|
||||||
|
* to send a result to this ResultReceiver to signal that disambiguation is complete
|
||||||
|
* and that the chooser should invoke the user's choice.</p>
|
||||||
|
*
|
||||||
|
* <p>The disambiguator should provide a Bundle to the ResultReceiver with an intent
|
||||||
|
* assigned to the key {@link #EXTRA_INTENT}. This supplied intent will be used by the chooser
|
||||||
|
* to match and fill in the final Intent or ChooserTarget before starting it.
|
||||||
|
* The supplied intent must {@link #filterEquals(Intent) match} one of the intents from
|
||||||
|
* {@link #EXTRA_INTENT} or {@link #EXTRA_ALTERNATE_INTENTS} passed to
|
||||||
|
* {@link #EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER} to be accepted.</p>
|
||||||
|
*
|
||||||
|
* <p>The result code passed to the ResultReceiver should be
|
||||||
|
* {@link android.app.Activity#RESULT_OK} if the refinement succeeded and the supplied intent's
|
||||||
|
* target in the chooser should be started, or {@link android.app.Activity#RESULT_CANCELED} if
|
||||||
|
* the chooser should finish without starting a target.</p>
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_RESULT_RECEIVER
|
||||||
|
= "android.intent.extra.RESULT_RECEIVER";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CharSequence dialog title to provide to the user when used with a
|
* A CharSequence dialog title to provide to the user when used with a
|
||||||
* {@link #ACTION_CHOOSER}.
|
* {@link #ACTION_CHOOSER}.
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
|
import android.content.IntentSender.SendIntentException;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
@@ -34,6 +35,7 @@ import android.os.IBinder;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.ResultReceiver;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.service.chooser.ChooserTarget;
|
import android.service.chooser.ChooserTarget;
|
||||||
import android.service.chooser.ChooserTargetService;
|
import android.service.chooser.ChooserTargetService;
|
||||||
@@ -53,11 +55,13 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
private static final int QUERY_TARGET_LIMIT = 5;
|
private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
|
||||||
private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
|
private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
|
||||||
|
|
||||||
private Bundle mReplacementExtras;
|
private Bundle mReplacementExtras;
|
||||||
private IntentSender mChosenComponentSender;
|
private IntentSender mChosenComponentSender;
|
||||||
|
private IntentSender mRefinementIntentSender;
|
||||||
|
private RefinementResultReceiver mRefinementResultReceiver;
|
||||||
|
|
||||||
private ChooserTarget[] mCallerChooserTargets;
|
private ChooserTarget[] mCallerChooserTargets;
|
||||||
|
|
||||||
@@ -113,6 +117,32 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
if (target != null) {
|
if (target != null) {
|
||||||
modifyTargetIntent(target);
|
modifyTargetIntent(target);
|
||||||
}
|
}
|
||||||
|
Parcelable[] targetsParcelable
|
||||||
|
= intent.getParcelableArrayExtra(Intent.EXTRA_ALTERNATE_INTENTS);
|
||||||
|
if (targetsParcelable != null) {
|
||||||
|
final boolean offset = target == null;
|
||||||
|
Intent[] additionalTargets =
|
||||||
|
new Intent[offset ? targetsParcelable.length - 1 : targetsParcelable.length];
|
||||||
|
for (int i = 0; i < targetsParcelable.length; i++) {
|
||||||
|
if (!(targetsParcelable[i] instanceof Intent)) {
|
||||||
|
Log.w(TAG, "EXTRA_ALTERNATE_INTENTS array entry #" + i + " is not an Intent: "
|
||||||
|
+ targetsParcelable[i]);
|
||||||
|
finish();
|
||||||
|
super.onCreate(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Intent additionalTarget = (Intent) targetsParcelable[i];
|
||||||
|
if (i == 0 && target == null) {
|
||||||
|
target = additionalTarget;
|
||||||
|
modifyTargetIntent(target);
|
||||||
|
} else {
|
||||||
|
additionalTargets[offset ? i - 1 : i] = additionalTarget;
|
||||||
|
modifyTargetIntent(additionalTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setAdditionalTargets(additionalTargets);
|
||||||
|
}
|
||||||
|
|
||||||
mReplacementExtras = intent.getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
|
mReplacementExtras = intent.getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
|
||||||
CharSequence title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
|
CharSequence title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
|
||||||
int defaultTitleRes = 0;
|
int defaultTitleRes = 0;
|
||||||
@@ -125,7 +155,7 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
initialIntents = new Intent[pa.length];
|
initialIntents = new Intent[pa.length];
|
||||||
for (int i=0; i<pa.length; i++) {
|
for (int i=0; i<pa.length; i++) {
|
||||||
if (!(pa[i] instanceof Intent)) {
|
if (!(pa[i] instanceof Intent)) {
|
||||||
Log.w("ChooserActivity", "Initial intent #" + i + " not an Intent: " + pa[i]);
|
Log.w(TAG, "Initial intent #" + i + " not an Intent: " + pa[i]);
|
||||||
finish();
|
finish();
|
||||||
super.onCreate(null);
|
super.onCreate(null);
|
||||||
return;
|
return;
|
||||||
@@ -141,8 +171,7 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
final ChooserTarget[] targets = new ChooserTarget[pa.length];
|
final ChooserTarget[] targets = new ChooserTarget[pa.length];
|
||||||
for (int i = 0; i < pa.length; i++) {
|
for (int i = 0; i < pa.length; i++) {
|
||||||
if (!(pa[i] instanceof ChooserTarget)) {
|
if (!(pa[i] instanceof ChooserTarget)) {
|
||||||
Log.w("ChooserActivity", "Chooser target #" + i + " is not a ChooserTarget: " +
|
Log.w(TAG, "Chooser target #" + i + " is not a ChooserTarget: " + pa[i]);
|
||||||
pa[i]);
|
|
||||||
finish();
|
finish();
|
||||||
super.onCreate(null);
|
super.onCreate(null);
|
||||||
return;
|
return;
|
||||||
@@ -153,11 +182,22 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
}
|
}
|
||||||
mChosenComponentSender = intent.getParcelableExtra(
|
mChosenComponentSender = intent.getParcelableExtra(
|
||||||
Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
|
Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
|
||||||
|
mRefinementIntentSender = intent.getParcelableExtra(
|
||||||
|
Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER);
|
||||||
setSafeForwardingMode(true);
|
setSafeForwardingMode(true);
|
||||||
super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
|
super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
|
||||||
null, false);
|
null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (mRefinementResultReceiver != null) {
|
||||||
|
mRefinementResultReceiver.destroy();
|
||||||
|
mRefinementResultReceiver = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
|
public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
|
||||||
Intent result = defIntent;
|
Intent result = defIntent;
|
||||||
@@ -211,6 +251,37 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
||||||
|
if (mRefinementIntentSender != null) {
|
||||||
|
final Intent fillIn = new Intent();
|
||||||
|
final List<Intent> sourceIntents = target.getAllSourceIntents();
|
||||||
|
if (!sourceIntents.isEmpty()) {
|
||||||
|
fillIn.putExtra(Intent.EXTRA_INTENT, sourceIntents.get(0));
|
||||||
|
if (sourceIntents.size() > 1) {
|
||||||
|
final Intent[] alts = new Intent[sourceIntents.size() - 1];
|
||||||
|
for (int i = 1, N = sourceIntents.size(); i < N; i++) {
|
||||||
|
alts[i - 1] = sourceIntents.get(i);
|
||||||
|
}
|
||||||
|
fillIn.putExtra(Intent.EXTRA_ALTERNATE_INTENTS, alts);
|
||||||
|
}
|
||||||
|
if (mRefinementResultReceiver != null) {
|
||||||
|
mRefinementResultReceiver.destroy();
|
||||||
|
}
|
||||||
|
mRefinementResultReceiver = new RefinementResultReceiver(this, target, null);
|
||||||
|
fillIn.putExtra(Intent.EXTRA_RESULT_RECEIVER,
|
||||||
|
mRefinementResultReceiver);
|
||||||
|
try {
|
||||||
|
mRefinementIntentSender.sendIntent(this, 0, fillIn, null, null);
|
||||||
|
return false;
|
||||||
|
} catch (SendIntentException e) {
|
||||||
|
Log.e(TAG, "Refinement IntentSender failed to send", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onTargetSelected(target, alwaysCheck);
|
||||||
|
}
|
||||||
|
|
||||||
void queryTargetServices(ChooserListAdapter adapter) {
|
void queryTargetServices(ChooserListAdapter adapter) {
|
||||||
final PackageManager pm = getPackageManager();
|
final PackageManager pm = getPackageManager();
|
||||||
int targetsToQuery = 0;
|
int targetsToQuery = 0;
|
||||||
@@ -258,8 +329,9 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
targetsToQuery++;
|
targetsToQuery++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetsToQuery >= QUERY_TARGET_LIMIT) {
|
if (targetsToQuery >= QUERY_TARGET_SERVICE_LIMIT) {
|
||||||
if (DEBUG) Log.d(TAG, "queryTargets hit query target limit " + QUERY_TARGET_LIMIT);
|
if (DEBUG) Log.d(TAG, "queryTargets hit query target limit "
|
||||||
|
+ QUERY_TARGET_SERVICE_LIMIT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,6 +375,43 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
mTargetResultHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
|
mTargetResultHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) {
|
||||||
|
if (mRefinementResultReceiver != null) {
|
||||||
|
mRefinementResultReceiver.destroy();
|
||||||
|
mRefinementResultReceiver = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedTarget == null) {
|
||||||
|
Log.e(TAG, "Refinement result intent did not match any known targets; canceling");
|
||||||
|
} else if (!checkTargetSourceIntent(selectedTarget, matchingIntent)) {
|
||||||
|
Log.e(TAG, "onRefinementResult: Selected target " + selectedTarget
|
||||||
|
+ " cannot match refined source intent " + matchingIntent);
|
||||||
|
} else if (super.onTargetSelected(selectedTarget.cloneFilledIn(matchingIntent, 0), false)) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onRefinementCanceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRefinementCanceled() {
|
||||||
|
if (mRefinementResultReceiver != null) {
|
||||||
|
mRefinementResultReceiver.destroy();
|
||||||
|
mRefinementResultReceiver = null;
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean checkTargetSourceIntent(TargetInfo target, Intent matchingIntent) {
|
||||||
|
final List<Intent> targetIntents = target.getAllSourceIntents();
|
||||||
|
for (int i = 0, N = targetIntents.size(); i < N; i++) {
|
||||||
|
final Intent targetIntent = targetIntents.get(i);
|
||||||
|
if (targetIntent.filterEquals(matchingIntent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
|
ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
|
||||||
List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
|
List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
|
||||||
@@ -313,17 +422,19 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChooserTargetInfo implements TargetInfo {
|
final class ChooserTargetInfo implements TargetInfo {
|
||||||
private final TargetInfo mSourceInfo;
|
private final DisplayResolveInfo mSourceInfo;
|
||||||
private final ResolveInfo mBackupResolveInfo;
|
private final ResolveInfo mBackupResolveInfo;
|
||||||
private final ChooserTarget mChooserTarget;
|
private final ChooserTarget mChooserTarget;
|
||||||
private final Drawable mDisplayIcon;
|
private final Drawable mDisplayIcon;
|
||||||
|
private final Intent mFillInIntent;
|
||||||
|
private final int mFillInFlags;
|
||||||
|
|
||||||
public ChooserTargetInfo(ChooserTarget target) {
|
public ChooserTargetInfo(ChooserTarget target) {
|
||||||
this(null, target);
|
this(null, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChooserTargetInfo(TargetInfo sourceInfo, ChooserTarget chooserTarget) {
|
public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget) {
|
||||||
mSourceInfo = sourceInfo;
|
mSourceInfo = sourceInfo;
|
||||||
mChooserTarget = chooserTarget;
|
mChooserTarget = chooserTarget;
|
||||||
mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
|
mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
|
||||||
@@ -333,6 +444,18 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
} else {
|
} else {
|
||||||
mBackupResolveInfo = getPackageManager().resolveActivity(getResolvedIntent(), 0);
|
mBackupResolveInfo = getPackageManager().resolveActivity(getResolvedIntent(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFillInIntent = null;
|
||||||
|
mFillInFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChooserTargetInfo(ChooserTargetInfo other, Intent fillInIntent, int flags) {
|
||||||
|
mSourceInfo = other.mSourceInfo;
|
||||||
|
mBackupResolveInfo = other.mBackupResolveInfo;
|
||||||
|
mChooserTarget = other.mChooserTarget;
|
||||||
|
mDisplayIcon = other.mDisplayIcon;
|
||||||
|
mFillInIntent = fillInIntent;
|
||||||
|
mFillInFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -358,22 +481,42 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Intent getFillInIntent() {
|
private Intent getFillInIntent() {
|
||||||
return mSourceInfo != null ? mSourceInfo.getResolvedIntent() : getTargetIntent();
|
Intent result = mSourceInfo != null
|
||||||
|
? mSourceInfo.getResolvedIntent() : getTargetIntent();
|
||||||
|
if (result == null) {
|
||||||
|
Log.e(TAG, "ChooserTargetInfo#getFillInIntent: no fillIn intent available");
|
||||||
|
} else if (mFillInIntent != null) {
|
||||||
|
result = new Intent(result);
|
||||||
|
result.fillIn(mFillInIntent, mFillInFlags);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean start(Activity activity, Bundle options) {
|
public boolean start(Activity activity, Bundle options) {
|
||||||
return mChooserTarget.sendIntent(activity, getFillInIntent());
|
final Intent intent = getFillInIntent();
|
||||||
|
if (intent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mChooserTarget.sendIntent(activity, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startAsCaller(Activity activity, Bundle options, int userId) {
|
public boolean startAsCaller(Activity activity, Bundle options, int userId) {
|
||||||
return mChooserTarget.sendIntentAsCaller(activity, getFillInIntent(), userId);
|
final Intent intent = getFillInIntent();
|
||||||
|
if (intent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mChooserTarget.sendIntentAsCaller(activity, intent, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
|
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
|
||||||
return mChooserTarget.sendIntentAsUser(activity, getFillInIntent(), user);
|
final Intent intent = getFillInIntent();
|
||||||
|
if (intent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mChooserTarget.sendIntentAsUser(activity, intent, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -395,6 +538,21 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
public Drawable getDisplayIcon() {
|
public Drawable getDisplayIcon() {
|
||||||
return mDisplayIcon;
|
return mDisplayIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
|
||||||
|
return new ChooserTargetInfo(this, fillInIntent, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Intent> getAllSourceIntents() {
|
||||||
|
final List<Intent> results = new ArrayList<>();
|
||||||
|
if (mSourceInfo != null) {
|
||||||
|
// We only queried the service for the first one in our sourceinfo.
|
||||||
|
results.add(mSourceInfo.getAllSourceIntents().get(0));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChooserListAdapter extends ResolveListAdapter {
|
public class ChooserListAdapter extends ResolveListAdapter {
|
||||||
@@ -542,4 +700,53 @@ public class ChooserActivity extends ResolverActivity {
|
|||||||
connection = c;
|
connection = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class RefinementResultReceiver extends ResultReceiver {
|
||||||
|
private ChooserActivity mChooserActivity;
|
||||||
|
private TargetInfo mSelectedTarget;
|
||||||
|
|
||||||
|
public RefinementResultReceiver(ChooserActivity host, TargetInfo target,
|
||||||
|
Handler handler) {
|
||||||
|
super(handler);
|
||||||
|
mChooserActivity = host;
|
||||||
|
mSelectedTarget = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||||
|
if (mChooserActivity == null) {
|
||||||
|
Log.e(TAG, "Destroyed RefinementResultReceiver received a result");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resultData == null) {
|
||||||
|
Log.e(TAG, "RefinementResultReceiver received null resultData");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resultCode) {
|
||||||
|
case RESULT_CANCELED:
|
||||||
|
mChooserActivity.onRefinementCanceled();
|
||||||
|
break;
|
||||||
|
case RESULT_OK:
|
||||||
|
Parcelable intentParcelable = resultData.getParcelable(Intent.EXTRA_INTENT);
|
||||||
|
if (intentParcelable instanceof Intent) {
|
||||||
|
mChooserActivity.onRefinementResult(mSelectedTarget,
|
||||||
|
(Intent) intentParcelable);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "RefinementResultReceiver received RESULT_OK but no Intent"
|
||||||
|
+ " in resultData with key Intent.EXTRA_INTENT");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(TAG, "Unknown result code " + resultCode
|
||||||
|
+ " sent to RefinementResultReceiver");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
mChooserActivity = null;
|
||||||
|
mSelectedTarget = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
private int mLastSelected = AbsListView.INVALID_POSITION;
|
private int mLastSelected = AbsListView.INVALID_POSITION;
|
||||||
private boolean mResolvingHome = false;
|
private boolean mResolvingHome = false;
|
||||||
private int mProfileSwitchMessageId = -1;
|
private int mProfileSwitchMessageId = -1;
|
||||||
private Intent mIntent;
|
private final ArrayList<Intent> mIntents = new ArrayList<>();
|
||||||
|
|
||||||
private UsageStatsManager mUsm;
|
private UsageStatsManager mUsm;
|
||||||
private Map<String, UsageStats> mStats;
|
private Map<String, UsageStats> mStats;
|
||||||
@@ -229,7 +229,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||||||
mIconDpi = am.getLauncherLargeIconDensity();
|
mIconDpi = am.getLauncherLargeIconDensity();
|
||||||
|
|
||||||
mIntent = new Intent(intent);
|
mIntents.add(0, new Intent(intent));
|
||||||
mAdapter = createAdapter(this, initialIntents, rList, mLaunchedFromUid, alwaysUseOption);
|
mAdapter = createAdapter(this, initialIntents, rList, mLaunchedFromUid, alwaysUseOption);
|
||||||
|
|
||||||
final int layoutId;
|
final int layoutId;
|
||||||
@@ -250,7 +250,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = mAdapter.mList.size();
|
int count = mAdapter.mDisplayList.size();
|
||||||
if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
|
if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
|
||||||
setContentView(layoutId);
|
setContentView(layoutId);
|
||||||
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
|
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
|
||||||
@@ -376,8 +376,16 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final void setAdditionalTargets(Intent[] intents) {
|
||||||
|
if (intents != null) {
|
||||||
|
for (Intent intent : intents) {
|
||||||
|
mIntents.add(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Intent getTargetIntent() {
|
public Intent getTargetIntent() {
|
||||||
return mIntent;
|
return mIntents.isEmpty() ? null : mIntents.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getReferrerPackageName() {
|
private String getReferrerPackageName() {
|
||||||
@@ -630,8 +638,9 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
TargetInfo target = mAdapter.targetInfoForPosition(which, filtered);
|
TargetInfo target = mAdapter.targetInfoForPosition(which, filtered);
|
||||||
onTargetSelected(target, always);
|
if (onTargetSelected(target, always)) {
|
||||||
finish();
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -641,7 +650,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
return defIntent;
|
return defIntent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
||||||
final ResolveInfo ri = target.getResolveInfo();
|
final ResolveInfo ri = target.getResolveInfo();
|
||||||
final Intent intent = target != null ? target.getResolvedIntent() : null;
|
final Intent intent = target != null ? target.getResolvedIntent() : null;
|
||||||
|
|
||||||
@@ -728,7 +737,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
ComponentName[] set = new ComponentName[N];
|
ComponentName[] set = new ComponentName[N];
|
||||||
int bestMatch = 0;
|
int bestMatch = 0;
|
||||||
for (int i=0; i<N; i++) {
|
for (int i=0; i<N; i++) {
|
||||||
ResolveInfo r = mAdapter.mOrigResolveList.get(i);
|
ResolveInfo r = mAdapter.mOrigResolveList.get(i).getResolveInfoAt(0);
|
||||||
set[i] = new ComponentName(r.activityInfo.packageName,
|
set[i] = new ComponentName(r.activityInfo.packageName,
|
||||||
r.activityInfo.name);
|
r.activityInfo.name);
|
||||||
if (r.match > bestMatch) bestMatch = r.match;
|
if (r.match > bestMatch) bestMatch = r.match;
|
||||||
@@ -774,6 +783,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if (target != null) {
|
if (target != null) {
|
||||||
safelyStartActivity(target);
|
safelyStartActivity(target);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void safelyStartActivity(TargetInfo cti) {
|
void safelyStartActivity(TargetInfo cti) {
|
||||||
@@ -837,15 +847,17 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
private Drawable mDisplayIcon;
|
private Drawable mDisplayIcon;
|
||||||
private final CharSequence mExtendedInfo;
|
private final CharSequence mExtendedInfo;
|
||||||
private final Intent mResolvedIntent;
|
private final Intent mResolvedIntent;
|
||||||
|
private final List<Intent> mSourceIntents = new ArrayList<>();
|
||||||
|
|
||||||
DisplayResolveInfo(ResolveInfo pri, CharSequence pLabel,
|
DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel,
|
||||||
CharSequence pInfo, Intent pOrigIntent) {
|
CharSequence pInfo, Intent pOrigIntent) {
|
||||||
|
mSourceIntents.add(originalIntent);
|
||||||
mResolveInfo = pri;
|
mResolveInfo = pri;
|
||||||
mDisplayLabel = pLabel;
|
mDisplayLabel = pLabel;
|
||||||
mExtendedInfo = pInfo;
|
mExtendedInfo = pInfo;
|
||||||
|
|
||||||
final Intent intent = new Intent(pOrigIntent != null ? pOrigIntent :
|
final Intent intent = new Intent(pOrigIntent != null ? pOrigIntent :
|
||||||
getReplacementIntent(pri.activityInfo, mIntent));
|
getReplacementIntent(pri.activityInfo, getTargetIntent()));
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
|
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
|
||||||
| Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
|
| Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
|
||||||
final ActivityInfo ai = mResolveInfo.activityInfo;
|
final ActivityInfo ai = mResolveInfo.activityInfo;
|
||||||
@@ -854,6 +866,16 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
mResolvedIntent = intent;
|
mResolvedIntent = intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags) {
|
||||||
|
mSourceIntents.addAll(other.getAllSourceIntents());
|
||||||
|
mResolveInfo = other.mResolveInfo;
|
||||||
|
mDisplayLabel = other.mDisplayLabel;
|
||||||
|
mDisplayIcon = other.mDisplayIcon;
|
||||||
|
mExtendedInfo = other.mExtendedInfo;
|
||||||
|
mResolvedIntent = new Intent(other.mResolvedIntent);
|
||||||
|
mResolvedIntent.fillIn(fillInIntent, flags);
|
||||||
|
}
|
||||||
|
|
||||||
public ResolveInfo getResolveInfo() {
|
public ResolveInfo getResolveInfo() {
|
||||||
return mResolveInfo;
|
return mResolveInfo;
|
||||||
}
|
}
|
||||||
@@ -866,6 +888,20 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
return mDisplayIcon;
|
return mDisplayIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
|
||||||
|
return new DisplayResolveInfo(this, fillInIntent, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Intent> getAllSourceIntents() {
|
||||||
|
return mSourceIntents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAlternateSourceIntent(Intent alt) {
|
||||||
|
mSourceIntents.add(alt);
|
||||||
|
}
|
||||||
|
|
||||||
public void setDisplayIcon(Drawable icon) {
|
public void setDisplayIcon(Drawable icon) {
|
||||||
mDisplayIcon = icon;
|
mDisplayIcon = icon;
|
||||||
}
|
}
|
||||||
@@ -986,6 +1022,16 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
* @return The drawable that should be used to represent this target
|
* @return The drawable that should be used to represent this target
|
||||||
*/
|
*/
|
||||||
public Drawable getDisplayIcon();
|
public Drawable getDisplayIcon();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone this target with the given fill-in information.
|
||||||
|
*/
|
||||||
|
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the list of supported source intents deduped against this single target
|
||||||
|
*/
|
||||||
|
public List<Intent> getAllSourceIntents();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResolveListAdapter extends BaseAdapter {
|
class ResolveListAdapter extends BaseAdapter {
|
||||||
@@ -998,8 +1044,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
|
|
||||||
protected final LayoutInflater mInflater;
|
protected final LayoutInflater mInflater;
|
||||||
|
|
||||||
List<DisplayResolveInfo> mList;
|
List<DisplayResolveInfo> mDisplayList;
|
||||||
List<ResolveInfo> mOrigResolveList;
|
List<ResolvedComponentInfo> mOrigResolveList;
|
||||||
|
|
||||||
private int mLastChosenPosition = -1;
|
private int mLastChosenPosition = -1;
|
||||||
private boolean mFilterLastUsed;
|
private boolean mFilterLastUsed;
|
||||||
@@ -1010,7 +1056,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
mBaseResolveList = rList;
|
mBaseResolveList = rList;
|
||||||
mLaunchedFromUid = launchedFromUid;
|
mLaunchedFromUid = launchedFromUid;
|
||||||
mInflater = LayoutInflater.from(context);
|
mInflater = LayoutInflater.from(context);
|
||||||
mList = new ArrayList<>();
|
mDisplayList = new ArrayList<>();
|
||||||
mFilterLastUsed = filterLastUsed;
|
mFilterLastUsed = filterLastUsed;
|
||||||
rebuildList();
|
rebuildList();
|
||||||
}
|
}
|
||||||
@@ -1027,7 +1073,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
public DisplayResolveInfo getFilteredItem() {
|
public DisplayResolveInfo getFilteredItem() {
|
||||||
if (mFilterLastUsed && mLastChosenPosition >= 0) {
|
if (mFilterLastUsed && mLastChosenPosition >= 0) {
|
||||||
// Not using getItem since it offsets to dodge this position for the list
|
// Not using getItem since it offsets to dodge this position for the list
|
||||||
return mList.get(mLastChosenPosition);
|
return mDisplayList.get(mLastChosenPosition);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1048,11 +1094,12 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildList() {
|
private void rebuildList() {
|
||||||
List<ResolveInfo> currentResolveList;
|
List<ResolvedComponentInfo> currentResolveList = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final Intent primaryIntent = getTargetIntent();
|
||||||
mLastChosen = AppGlobals.getPackageManager().getLastChosenActivity(
|
mLastChosen = AppGlobals.getPackageManager().getLastChosenActivity(
|
||||||
mIntent, mIntent.resolveTypeIfNeeded(getContentResolver()),
|
primaryIntent, primaryIntent.resolveTypeIfNeeded(getContentResolver()),
|
||||||
PackageManager.MATCH_DEFAULT_ONLY);
|
PackageManager.MATCH_DEFAULT_ONLY);
|
||||||
} catch (RemoteException re) {
|
} catch (RemoteException re) {
|
||||||
Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
|
Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
|
||||||
@@ -1060,15 +1107,27 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
|
|
||||||
// Clear the value of mOtherProfile from previous call.
|
// Clear the value of mOtherProfile from previous call.
|
||||||
mOtherProfile = null;
|
mOtherProfile = null;
|
||||||
mList.clear();
|
mDisplayList.clear();
|
||||||
if (mBaseResolveList != null) {
|
if (mBaseResolveList != null) {
|
||||||
currentResolveList = mOrigResolveList = mBaseResolveList;
|
currentResolveList = mOrigResolveList = new ArrayList<>();
|
||||||
|
addResolveListDedupe(currentResolveList, getTargetIntent(), mBaseResolveList);
|
||||||
} else {
|
} else {
|
||||||
currentResolveList = mOrigResolveList = mPm.queryIntentActivities(mIntent,
|
final boolean shouldGetResolvedFilter = shouldGetResolvedFilter();
|
||||||
PackageManager.MATCH_DEFAULT_ONLY
|
final boolean shouldGetActivityMetadata = shouldGetActivityMetadata();
|
||||||
| (shouldGetResolvedFilter() ? PackageManager.GET_RESOLVED_FILTER : 0)
|
for (int i = 0, N = mIntents.size(); i < N; i++) {
|
||||||
| (shouldGetActivityMetadata() ? PackageManager.GET_META_DATA : 0)
|
final Intent intent = mIntents.get(i);
|
||||||
);
|
final List<ResolveInfo> infos = mPm.queryIntentActivities(intent,
|
||||||
|
PackageManager.MATCH_DEFAULT_ONLY
|
||||||
|
| (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
|
||||||
|
| (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0));
|
||||||
|
if (infos != null) {
|
||||||
|
if (currentResolveList == null) {
|
||||||
|
currentResolveList = mOrigResolveList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
addResolveListDedupe(currentResolveList, intent, infos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filter out any activities that the launched uid does not
|
// Filter out any activities that the launched uid does not
|
||||||
// have permission for. We don't do this when we have an explicit
|
// have permission for. We don't do this when we have an explicit
|
||||||
// list of resolved activities, because that only happens when
|
// list of resolved activities, because that only happens when
|
||||||
@@ -1076,14 +1135,15 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
// they gave us.
|
// they gave us.
|
||||||
if (currentResolveList != null) {
|
if (currentResolveList != null) {
|
||||||
for (int i=currentResolveList.size()-1; i >= 0; i--) {
|
for (int i=currentResolveList.size()-1; i >= 0; i--) {
|
||||||
ActivityInfo ai = currentResolveList.get(i).activityInfo;
|
ActivityInfo ai = currentResolveList.get(i)
|
||||||
|
.getResolveInfoAt(0).activityInfo;
|
||||||
int granted = ActivityManager.checkComponentPermission(
|
int granted = ActivityManager.checkComponentPermission(
|
||||||
ai.permission, mLaunchedFromUid,
|
ai.permission, mLaunchedFromUid,
|
||||||
ai.applicationInfo.uid, ai.exported);
|
ai.applicationInfo.uid, ai.exported);
|
||||||
if (granted != PackageManager.PERMISSION_GRANTED) {
|
if (granted != PackageManager.PERMISSION_GRANTED) {
|
||||||
// Access not allowed!
|
// Access not allowed!
|
||||||
if (mOrigResolveList == currentResolveList) {
|
if (mOrigResolveList == currentResolveList) {
|
||||||
mOrigResolveList = new ArrayList<ResolveInfo>(mOrigResolveList);
|
mOrigResolveList = new ArrayList<>(mOrigResolveList);
|
||||||
}
|
}
|
||||||
currentResolveList.remove(i);
|
currentResolveList.remove(i);
|
||||||
}
|
}
|
||||||
@@ -1094,9 +1154,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if ((currentResolveList != null) && ((N = currentResolveList.size()) > 0)) {
|
if ((currentResolveList != null) && ((N = currentResolveList.size()) > 0)) {
|
||||||
// Only display the first matches that are either of equal
|
// Only display the first matches that are either of equal
|
||||||
// priority or have asked to be default options.
|
// priority or have asked to be default options.
|
||||||
ResolveInfo r0 = currentResolveList.get(0);
|
ResolvedComponentInfo rci0 = currentResolveList.get(0);
|
||||||
|
ResolveInfo r0 = rci0.getResolveInfoAt(0);
|
||||||
for (int i=1; i<N; i++) {
|
for (int i=1; i<N; i++) {
|
||||||
ResolveInfo ri = currentResolveList.get(i);
|
ResolveInfo ri = currentResolveList.get(i).getResolveInfoAt(0);
|
||||||
if (DEBUG) Log.v(
|
if (DEBUG) Log.v(
|
||||||
TAG,
|
TAG,
|
||||||
r0.activityInfo.name + "=" +
|
r0.activityInfo.name + "=" +
|
||||||
@@ -1107,7 +1168,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
r0.isDefault != ri.isDefault) {
|
r0.isDefault != ri.isDefault) {
|
||||||
while (i < N) {
|
while (i < N) {
|
||||||
if (mOrigResolveList == currentResolveList) {
|
if (mOrigResolveList == currentResolveList) {
|
||||||
mOrigResolveList = new ArrayList<ResolveInfo>(mOrigResolveList);
|
mOrigResolveList = new ArrayList<>(mOrigResolveList);
|
||||||
}
|
}
|
||||||
currentResolveList.remove(i);
|
currentResolveList.remove(i);
|
||||||
N--;
|
N--;
|
||||||
@@ -1115,9 +1176,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (N > 1) {
|
if (N > 1) {
|
||||||
Comparator<ResolveInfo> rComparator =
|
Collections.sort(currentResolveList,
|
||||||
new ResolverComparator(ResolverActivity.this, mIntent);
|
new ResolverComparator(ResolverActivity.this, getTargetIntent()));
|
||||||
Collections.sort(currentResolveList, rComparator);
|
|
||||||
}
|
}
|
||||||
// First put the initial items at the top.
|
// First put the initial items at the top.
|
||||||
if (mInitialIntents != null) {
|
if (mInitialIntents != null) {
|
||||||
@@ -1146,14 +1206,15 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
|
ri.nonLocalizedLabel = li.getNonLocalizedLabel();
|
||||||
ri.icon = li.getIconResource();
|
ri.icon = li.getIconResource();
|
||||||
}
|
}
|
||||||
addResolveInfo(new DisplayResolveInfo(ri,
|
addResolveInfo(new DisplayResolveInfo(ii, ri,
|
||||||
ri.loadLabel(getPackageManager()), null, ii));
|
ri.loadLabel(getPackageManager()), null, ii));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for applications with same name and use application name or
|
// Check for applications with same name and use application name or
|
||||||
// package name if necessary
|
// package name if necessary
|
||||||
r0 = currentResolveList.get(0);
|
rci0 = currentResolveList.get(0);
|
||||||
|
r0 = rci0.getResolveInfoAt(0);
|
||||||
int start = 0;
|
int start = 0;
|
||||||
CharSequence r0Label = r0.loadLabel(mPm);
|
CharSequence r0Label = r0.loadLabel(mPm);
|
||||||
mHasExtendedInfo = false;
|
mHasExtendedInfo = false;
|
||||||
@@ -1161,7 +1222,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if (r0Label == null) {
|
if (r0Label == null) {
|
||||||
r0Label = r0.activityInfo.packageName;
|
r0Label = r0.activityInfo.packageName;
|
||||||
}
|
}
|
||||||
ResolveInfo ri = currentResolveList.get(i);
|
ResolvedComponentInfo rci = currentResolveList.get(i);
|
||||||
|
ResolveInfo ri = rci.getResolveInfoAt(0);
|
||||||
CharSequence riLabel = ri.loadLabel(mPm);
|
CharSequence riLabel = ri.loadLabel(mPm);
|
||||||
if (riLabel == null) {
|
if (riLabel == null) {
|
||||||
riLabel = ri.activityInfo.packageName;
|
riLabel = ri.activityInfo.packageName;
|
||||||
@@ -1169,13 +1231,14 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if (riLabel.equals(r0Label)) {
|
if (riLabel.equals(r0Label)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
processGroup(currentResolveList, start, (i-1), r0, r0Label);
|
processGroup(currentResolveList, start, (i-1), rci0, r0Label);
|
||||||
|
rci0 = rci;
|
||||||
r0 = ri;
|
r0 = ri;
|
||||||
r0Label = riLabel;
|
r0Label = riLabel;
|
||||||
start = i;
|
start = i;
|
||||||
}
|
}
|
||||||
// Process last group
|
// Process last group
|
||||||
processGroup(currentResolveList, start, (N-1), r0, r0Label);
|
processGroup(currentResolveList, start, (N-1), rci0, r0Label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout doesn't handle both profile button and last chosen
|
// Layout doesn't handle both profile button and last chosen
|
||||||
@@ -1188,6 +1251,36 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
onListRebuilt();
|
onListRebuilt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addResolveListDedupe(List<ResolvedComponentInfo> into, Intent intent,
|
||||||
|
List<ResolveInfo> from) {
|
||||||
|
final int fromCount = from.size();
|
||||||
|
final int intoCount = into.size();
|
||||||
|
for (int i = 0; i < fromCount; i++) {
|
||||||
|
final ResolveInfo newInfo = from.get(i);
|
||||||
|
boolean found = false;
|
||||||
|
// Only loop to the end of into as it was before we started; no dupes in from.
|
||||||
|
for (int j = 0; j < intoCount; j++) {
|
||||||
|
final ResolvedComponentInfo rci = into.get(i);
|
||||||
|
if (isSameResolvedComponent(newInfo, rci)) {
|
||||||
|
found = true;
|
||||||
|
rci.add(intent, newInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
into.add(new ResolvedComponentInfo(new ComponentName(
|
||||||
|
newInfo.activityInfo.packageName, newInfo.activityInfo.name),
|
||||||
|
intent, newInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSameResolvedComponent(ResolveInfo a, ResolvedComponentInfo b) {
|
||||||
|
final ActivityInfo ai = a.activityInfo;
|
||||||
|
return ai.packageName.equals(b.name.getPackageName())
|
||||||
|
&& ai.name.equals(b.name.getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
public void onListRebuilt() {
|
public void onListRebuilt() {
|
||||||
// This space for rent
|
// This space for rent
|
||||||
}
|
}
|
||||||
@@ -1196,18 +1289,18 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
return mFilterLastUsed;
|
return mFilterLastUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processGroup(List<ResolveInfo> rList, int start, int end, ResolveInfo ro,
|
private void processGroup(List<ResolvedComponentInfo> rList, int start, int end,
|
||||||
CharSequence roLabel) {
|
ResolvedComponentInfo ro, CharSequence roLabel) {
|
||||||
// Process labels from start to i
|
// Process labels from start to i
|
||||||
int num = end - start+1;
|
int num = end - start+1;
|
||||||
if (num == 1) {
|
if (num == 1) {
|
||||||
// No duplicate labels. Use label for entry at start
|
// No duplicate labels. Use label for entry at start
|
||||||
addResolveInfo(new DisplayResolveInfo(ro, roLabel, null, null));
|
addResolveInfoWithAlternates(ro, null, roLabel);
|
||||||
updateLastChosenPosition(ro);
|
|
||||||
} else {
|
} else {
|
||||||
mHasExtendedInfo = true;
|
mHasExtendedInfo = true;
|
||||||
boolean usePkg = false;
|
boolean usePkg = false;
|
||||||
CharSequence startApp = ro.activityInfo.applicationInfo.loadLabel(mPm);
|
CharSequence startApp = ro.getResolveInfoAt(0).activityInfo.applicationInfo
|
||||||
|
.loadLabel(mPm);
|
||||||
if (startApp == null) {
|
if (startApp == null) {
|
||||||
usePkg = true;
|
usePkg = true;
|
||||||
}
|
}
|
||||||
@@ -1217,7 +1310,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
new HashSet<CharSequence>();
|
new HashSet<CharSequence>();
|
||||||
duplicates.add(startApp);
|
duplicates.add(startApp);
|
||||||
for (int j = start+1; j <= end ; j++) {
|
for (int j = start+1; j <= end ; j++) {
|
||||||
ResolveInfo jRi = rList.get(j);
|
ResolveInfo jRi = rList.get(j).getResolveInfoAt(0);
|
||||||
CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm);
|
CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm);
|
||||||
if ( (jApp == null) || (duplicates.contains(jApp))) {
|
if ( (jApp == null) || (duplicates.contains(jApp))) {
|
||||||
usePkg = true;
|
usePkg = true;
|
||||||
@@ -1230,26 +1323,46 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
duplicates.clear();
|
duplicates.clear();
|
||||||
}
|
}
|
||||||
for (int k = start; k <= end; k++) {
|
for (int k = start; k <= end; k++) {
|
||||||
ResolveInfo add = rList.get(k);
|
final ResolvedComponentInfo rci = rList.get(k);
|
||||||
|
final ResolveInfo add = rci.getResolveInfoAt(0);
|
||||||
|
final CharSequence extraInfo;
|
||||||
if (usePkg) {
|
if (usePkg) {
|
||||||
// Use application name for all entries from start to end-1
|
|
||||||
addResolveInfo(new DisplayResolveInfo(add, roLabel,
|
|
||||||
add.activityInfo.packageName, null));
|
|
||||||
} else {
|
|
||||||
// Use package name for all entries from start to end-1
|
// Use package name for all entries from start to end-1
|
||||||
addResolveInfo(new DisplayResolveInfo(add, roLabel,
|
extraInfo = add.activityInfo.packageName;
|
||||||
add.activityInfo.applicationInfo.loadLabel(mPm), null));
|
} else {
|
||||||
|
// Use application name for all entries from start to end-1
|
||||||
|
extraInfo = add.activityInfo.applicationInfo.loadLabel(mPm);
|
||||||
}
|
}
|
||||||
updateLastChosenPosition(add);
|
addResolveInfoWithAlternates(rci, extraInfo, roLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addResolveInfoWithAlternates(ResolvedComponentInfo rci,
|
||||||
|
CharSequence extraInfo, CharSequence roLabel) {
|
||||||
|
final int count = rci.getCount();
|
||||||
|
final Intent intent = rci.getIntentAt(0);
|
||||||
|
final ResolveInfo add = rci.getResolveInfoAt(0);
|
||||||
|
final Intent replaceIntent = getReplacementIntent(add.activityInfo, intent);
|
||||||
|
final DisplayResolveInfo dri = new DisplayResolveInfo(intent, add, roLabel,
|
||||||
|
extraInfo, replaceIntent);
|
||||||
|
addResolveInfo(dri);
|
||||||
|
if (replaceIntent == intent) {
|
||||||
|
// Only add alternates if we didn't get a specific replacement from
|
||||||
|
// the caller. If we have one it trumps potential alternates.
|
||||||
|
for (int i = 1, N = count; i < N; i++) {
|
||||||
|
final Intent altIntent = rci.getIntentAt(i);
|
||||||
|
dri.addAlternateSourceIntent(altIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateLastChosenPosition(add);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateLastChosenPosition(ResolveInfo info) {
|
private void updateLastChosenPosition(ResolveInfo info) {
|
||||||
if (mLastChosen != null
|
if (mLastChosen != null
|
||||||
&& mLastChosen.activityInfo.packageName.equals(info.activityInfo.packageName)
|
&& mLastChosen.activityInfo.packageName.equals(info.activityInfo.packageName)
|
||||||
&& mLastChosen.activityInfo.name.equals(info.activityInfo.name)) {
|
&& mLastChosen.activityInfo.name.equals(info.activityInfo.name)) {
|
||||||
mLastChosenPosition = mList.size() - 1;
|
mLastChosenPosition = mDisplayList.size() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1259,20 +1372,21 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
// The first one we see gets special treatment.
|
// The first one we see gets special treatment.
|
||||||
mOtherProfile = dri;
|
mOtherProfile = dri;
|
||||||
} else {
|
} else {
|
||||||
mList.add(dri);
|
mDisplayList.add(dri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResolveInfo resolveInfoForPosition(int position, boolean filtered) {
|
public ResolveInfo resolveInfoForPosition(int position, boolean filtered) {
|
||||||
return (filtered ? getItem(position) : mList.get(position)).getResolveInfo();
|
return (filtered ? getItem(position) : mDisplayList.get(position))
|
||||||
|
.getResolveInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetInfo targetInfoForPosition(int position, boolean filtered) {
|
public TargetInfo targetInfoForPosition(int position, boolean filtered) {
|
||||||
return filtered ? getItem(position) : mList.get(position);
|
return filtered ? getItem(position) : mDisplayList.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
int result = mList.size();
|
int result = mDisplayList.size();
|
||||||
if (mFilterLastUsed && mLastChosenPosition >= 0) {
|
if (mFilterLastUsed && mLastChosenPosition >= 0) {
|
||||||
result--;
|
result--;
|
||||||
}
|
}
|
||||||
@@ -1283,7 +1397,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
|
if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
return mList.get(position);
|
return mDisplayList.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
@@ -1295,8 +1409,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasResolvedTarget(ResolveInfo info) {
|
public boolean hasResolvedTarget(ResolveInfo info) {
|
||||||
for (int i = 0, N = mList.size(); i < N; i++) {
|
for (int i = 0, N = mDisplayList.size(); i < N; i++) {
|
||||||
if (info.equals(mList.get(i).getResolveInfo())) {
|
if (info.equals(mDisplayList.get(i).getResolveInfo())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1304,11 +1418,12 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected int getDisplayResolveInfoCount() {
|
protected int getDisplayResolveInfoCount() {
|
||||||
return mList.size();
|
return mDisplayList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DisplayResolveInfo getDisplayResolveInfo(int index) {
|
protected DisplayResolveInfo getDisplayResolveInfo(int index) {
|
||||||
return mList.get(index);
|
// Used to query services. We only query services for primary targets, not alternates.
|
||||||
|
return mDisplayList.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final View getView(int position, View convertView, ViewGroup parent) {
|
public final View getView(int position, View convertView, ViewGroup parent) {
|
||||||
@@ -1349,6 +1464,52 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class ResolvedComponentInfo {
|
||||||
|
public final ComponentName name;
|
||||||
|
private final List<Intent> mIntents = new ArrayList<>();
|
||||||
|
private final List<ResolveInfo> mResolveInfos = new ArrayList<>();
|
||||||
|
|
||||||
|
public ResolvedComponentInfo(ComponentName name, Intent intent, ResolveInfo info) {
|
||||||
|
this.name = name;
|
||||||
|
add(intent, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Intent intent, ResolveInfo info) {
|
||||||
|
mIntents.add(intent);
|
||||||
|
mResolveInfos.add(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return mIntents.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Intent getIntentAt(int index) {
|
||||||
|
return index >= 0 ? mIntents.get(index) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResolveInfo getResolveInfoAt(int index) {
|
||||||
|
return index >= 0 ? mResolveInfos.get(index) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findIntent(Intent intent) {
|
||||||
|
for (int i = 0, N = mIntents.size(); i < N; i++) {
|
||||||
|
if (intent.equals(mIntents.get(i))) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int findResolveInfo(ResolveInfo info) {
|
||||||
|
for (int i = 0, N = mResolveInfos.size(); i < N; i++) {
|
||||||
|
if (info.equals(mResolveInfos.get(i))) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class ViewHolder {
|
static class ViewHolder {
|
||||||
public TextView text;
|
public TextView text;
|
||||||
public TextView text2;
|
public TextView text2;
|
||||||
@@ -1435,7 +1596,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
&& match <= IntentFilter.MATCH_CATEGORY_PATH;
|
&& match <= IntentFilter.MATCH_CATEGORY_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResolverComparator implements Comparator<ResolveInfo> {
|
class ResolverComparator implements Comparator<ResolvedComponentInfo> {
|
||||||
private final Collator mCollator;
|
private final Collator mCollator;
|
||||||
private final boolean mHttp;
|
private final boolean mHttp;
|
||||||
|
|
||||||
@@ -1446,7 +1607,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(ResolveInfo lhs, ResolveInfo rhs) {
|
public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
|
||||||
|
final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
|
||||||
|
final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
|
||||||
|
|
||||||
// We want to put the one targeted to another user at the end of the dialog.
|
// We want to put the one targeted to another user at the end of the dialog.
|
||||||
if (lhs.targetUserId != UserHandle.USER_CURRENT) {
|
if (lhs.targetUserId != UserHandle.USER_CURRENT) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1487,7 +1651,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
|
|||||||
if (stats != null) {
|
if (stats != null) {
|
||||||
return stats.getTotalTimeInForeground();
|
return stats.getTotalTimeInForeground();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class UsbResolverActivity extends ResolverActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
|
||||||
final ResolveInfo ri = target.getResolveInfo();
|
final ResolveInfo ri = target.getResolveInfo();
|
||||||
try {
|
try {
|
||||||
IBinder b = ServiceManager.getService(USB_SERVICE);
|
IBinder b = ServiceManager.getService(USB_SERVICE);
|
||||||
@@ -129,5 +129,6 @@ public class UsbResolverActivity extends ResolverActivity {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "onIntentSelected failed", e);
|
Log.e(TAG, "onIntentSelected failed", e);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user