Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc8b2afb authored by Adam Powell's avatar Adam Powell Committed by Android (Google) Code Review
Browse files

Merge "Implement ChooserTargetService querying for ChooserActivity"

parents 7d8f2c25 24428418
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -8158,6 +8158,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_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_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_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
    field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -28384,8 +28385,10 @@ package android.service.chooser {
  public final class ChooserTarget implements android.os.Parcelable {
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.Intent);
    method public int describeContents();
    method public android.graphics.Bitmap getIcon();
    method public android.content.Intent getIntent();
    method public android.content.IntentSender getIntentSender();
    method public float getScore();
    method public java.lang.CharSequence getTitle();
@@ -28398,6 +28401,8 @@ package android.service.chooser {
    ctor public ChooserTargetService();
    method public android.os.IBinder onBind(android.content.Intent);
    method public abstract java.util.List<android.service.chooser.ChooserTarget> onGetChooserTargets(android.content.ComponentName, android.content.IntentFilter);
    field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
    field public static final java.lang.String META_DATA_NAME = "android.service.chooser.chooser_target_service";
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";
  }
+5 −0
Original line number Diff line number Diff line
@@ -8384,6 +8384,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_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_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_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
    field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
@@ -30383,8 +30384,10 @@ package android.service.chooser {
  public final class ChooserTarget implements android.os.Parcelable {
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
    ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.Intent);
    method public int describeContents();
    method public android.graphics.Bitmap getIcon();
    method public android.content.Intent getIntent();
    method public android.content.IntentSender getIntentSender();
    method public float getScore();
    method public java.lang.CharSequence getTitle();
@@ -30397,6 +30400,8 @@ package android.service.chooser {
    ctor public ChooserTargetService();
    method public android.os.IBinder onBind(android.content.Intent);
    method public abstract java.util.List<android.service.chooser.ChooserTarget> onGetChooserTargets(android.content.ComponentName, android.content.IntentFilter);
    field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
    field public static final java.lang.String META_DATA_NAME = "android.service.chooser.chooser_target_service";
    field public static final java.lang.String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";
  }
+8 −0
Original line number Diff line number Diff line
@@ -3310,6 +3310,14 @@ public class Intent implements Parcelable, Cloneable {
     */
    public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";

    /**
     * A Parcelable[] of {@link android.service.chooser.ChooserTarget ChooserTarget} objects
     * as set with {@link #putExtra(String, Parcelable[])} representing additional app-specific
     * targets to place at the front of the list of choices. Shown to the user with
     * {@link #ACTION_CHOOSER}.
     */
    public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";

    /**
     * A Bundle forming a mapping of potential target package names to different extras Bundles
     * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
+133 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

package android.service.chooser;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -24,8 +25,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.util.Log;

/**
@@ -54,6 +57,12 @@ public final class ChooserTarget implements Parcelable {
     */
    private IntentSender mIntentSender;

    /**
     * A raw intent provided in lieu of an IntentSender. Will be filled in and sent
     * by {@link #sendIntent(Context, Intent)}.
     */
    private Intent mIntent;

    /**
     * The score given to this item. It can be normalized.
     */
@@ -135,6 +144,17 @@ public final class ChooserTarget implements Parcelable {
        mIntentSender = intentSender;
    }

    public ChooserTarget(CharSequence title, Bitmap icon, float score, Intent intent) {
        mTitle = title;
        mIcon = icon;
        if (score > 1.f || score < 0.f) {
            throw new IllegalArgumentException("Score " + score + " out of range; "
                    + "must be between 0.0f and 1.0f");
        }
        mScore = score;
        mIntent = intent;
    }

    ChooserTarget(Parcel in) {
        mTitle = in.readCharSequence();
        if (in.readInt() != 0) {
@@ -144,6 +164,9 @@ public final class ChooserTarget implements Parcelable {
        }
        mScore = in.readFloat();
        mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in);
        if (in.readInt() != 0) {
            mIntent = Intent.CREATOR.createFromParcel(in);
        }
    }

    /**
@@ -179,6 +202,7 @@ public final class ChooserTarget implements Parcelable {

    /**
     * Returns the raw IntentSender supplied by the ChooserTarget's creator.
     * This may be null if the creator specified a regular Intent instead.
     *
     * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
     *
@@ -188,6 +212,18 @@ public final class ChooserTarget implements Parcelable {
        return mIntentSender;
    }

    /**
     * Returns the Intent supplied by the ChooserTarget's creator.
     * This may be null if the creator specified an IntentSender or PendingIntent instead.
     *
     * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
     *
     * @return the Intent supplied by the ChooserTarget's creator
     */
    public Intent getIntent() {
        return mIntent;
    }

    /**
     * Fill in the IntentSender supplied by the ChooserTarget's creator and send it.
     *
@@ -200,6 +236,7 @@ public final class ChooserTarget implements Parcelable {
            fillInIntent.migrateExtraStreamToClipData();
            fillInIntent.prepareToLeaveProcess();
        }
        if (mIntentSender != null) {
            try {
                mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
                return true;
@@ -207,11 +244,101 @@ public final class ChooserTarget implements Parcelable {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else if (mIntent != null) {
            try {
                final Intent toSend = new Intent(mIntent);
                toSend.fillIn(fillInIntent, 0);
                context.startActivity(toSend);
                return true;
            } catch (Exception e) {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else {
            Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
            return false;
        }
    }

    /**
     * Same as {@link #sendIntent(Context, Intent)}, but offers a userId field to use
     * for launching the {@link #getIntent() intent} using
     * {@link Activity#startActivityAsCaller(Intent, Bundle, int)} if the
     * {@link #getIntentSender() IntentSender} is not present. If the IntentSender is present,
     * it will be invoked as usual with its own calling identity.
     *
     * @hide internal use only.
     */
    public boolean sendIntentAsCaller(Activity context, Intent fillInIntent, int userId) {
        if (fillInIntent != null) {
            fillInIntent.migrateExtraStreamToClipData();
            fillInIntent.prepareToLeaveProcess();
        }
        if (mIntentSender != null) {
            try {
                mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
                return true;
            } catch (IntentSender.SendIntentException e) {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else if (mIntent != null) {
            try {
                final Intent toSend = new Intent(mIntent);
                toSend.fillIn(fillInIntent, 0);
                context.startActivityAsCaller(toSend, null, userId);
                return true;
            } catch (Exception e) {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else {
            Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
            return false;
        }
    }

    /**
     * The UserHandle is only used if we're launching a raw intent. The IntentSender will be
     * launched with its associated identity.
     *
     * @hide Internal use only
     */
    public boolean sendIntentAsUser(Activity context, Intent fillInIntent, UserHandle user) {
        if (fillInIntent != null) {
            fillInIntent.migrateExtraStreamToClipData();
            fillInIntent.prepareToLeaveProcess();
        }
        if (mIntentSender != null) {
            try {
                mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
                return true;
            } catch (IntentSender.SendIntentException e) {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else if (mIntent != null) {
            try {
                final Intent toSend = new Intent(mIntent);
                toSend.fillIn(fillInIntent, 0);
                context.startActivityAsUser(toSend, user);
                return true;
            } catch (Exception e) {
                Log.e(TAG, "sendIntent " + this + " failed", e);
                return false;
            }
        } else {
            Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
            return false;
        }
    }

    @Override
    public String toString() {
        return "ChooserTarget{" + mIntentSender.getCreatorPackage() + "'" + mTitle
        return "ChooserTarget{"
                + (mIntentSender != null ? mIntentSender.getCreatorPackage() : mIntent)
                + ", "
                + "'" + mTitle
                + "', " + mScore + "}";
    }

+25 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.List;

@@ -77,9 +78,26 @@ public abstract class ChooserTargetService extends Service {
    private final String TAG = ChooserTargetService.class.getSimpleName()
            + '[' + getClass().getSimpleName() + ']';

    private static final boolean DEBUG = false;

    /**
     * The Intent action that a ChooserTargetService must respond to
     */
    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
    public static final String SERVICE_INTERFACE = "android.service.chooser.ChooserTargetService";

    /**
     * The name of the <code>meta-data</code> element that must be present on an
     * <code>activity</code> element in a manifest to link it to a ChooserTargetService
     */
    public static final String META_DATA_NAME = "android.service.chooser.chooser_target_service";

    /**
     * The permission that a ChooserTargetService must require in order to bind to it.
     * If this permission is not enforced the system will skip that ChooserTargetService.
     */
    public static final String BIND_PERMISSION = "android.permission.BIND_CHOOSER_TARGET_SERVICE";

    private IChooserTargetServiceWrapper mWrapper = null;

    /**
@@ -105,7 +123,9 @@ public abstract class ChooserTargetService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        if (DEBUG) Log.d(TAG, "onBind " + intent);
        if (!SERVICE_INTERFACE.equals(intent.getAction())) {
            if (DEBUG) Log.d(TAG, "bad intent action " + intent.getAction() + "; returning null");
            return null;
        }

@@ -121,9 +141,14 @@ public abstract class ChooserTargetService extends Service {
                IntentFilter matchedFilter, IChooserTargetResult result) throws RemoteException {
            List<ChooserTarget> targets = null;
            try {
                if (DEBUG) {
                    Log.d(TAG, "getChooserTargets calling onGetChooserTargets; "
                            + targetComponentName + " filter: " + matchedFilter);
                }
                targets = onGetChooserTargets(targetComponentName, matchedFilter);
            } finally {
                result.sendResult(targets);
                if (DEBUG) Log.d(TAG, "Sent results");
            }
        }
    }
Loading