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

Commit f9c5e0fe authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add new API to propagate contextual data to the assist action

When launching an assist, we have a new API allowing the
current foreground activity/application to provide additional
arbitrary contextual information that is stuffed in the
assist intent before it is launched.

Change-Id: I0b2a6f5a266dc42cc0175327fa76774f814af3b4
parent cc743347
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ package android {
    field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
    field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
    field public static final java.lang.String GET_TASKS = "android.permission.GET_TASKS";
    field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
    field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
    field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
    field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
@@ -2738,6 +2739,7 @@ package android.app {
    method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder);
    method public boolean onPrepareOptionsMenu(android.view.Menu);
    method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
    method public void onProvideAssistData(android.os.Bundle);
    method protected void onRestart();
    method protected void onRestoreInstanceState(android.os.Bundle);
    method protected void onResume();
@@ -3077,7 +3079,9 @@ package android.app {
    method public void onTerminate();
    method public void onTrimMemory(int);
    method public void registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
    method public void registerOnProvideAssistData(android.app.Application.OnProvideAssistData);
    method public void unregisterActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
    method public void unregisterOnProvideAssistData(android.app.Application.OnProvideAssistData);
  }
  public static abstract interface Application.ActivityLifecycleCallbacks {
@@ -3090,6 +3094,10 @@ package android.app {
    method public abstract void onActivityStopped(android.app.Activity);
  }
  public static abstract interface Application.OnProvideAssistData {
    method public abstract void onProvideAssistData(android.app.Activity, android.os.Bundle);
  }
  public class ApplicationErrorReport implements android.os.Parcelable {
    ctor public ApplicationErrorReport();
    method public int describeContents();
@@ -5901,6 +5909,8 @@ package android.content {
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
    field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
    field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
    field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
    field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
    field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
    field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
+14 −0
Original line number Diff line number Diff line
@@ -1345,6 +1345,20 @@ public class Activity extends ContextThemeWrapper
        return null;
    }

    /**
     * This is called when the user is requesting an assist, to build a full
     * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
     * application.  You can override this method to place into the bundle anything
     * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
     * of the assist Intent.  The default implementation does nothing.
     *
     * <p>This function will be called after any global assist callbacks that had
     * been registered with {@link Application#registerOnProvideAssistData
     * Application.registerOnProvideAssistData}.
     */
    public void onProvideAssistData(Bundle data) {
    }

    /**
     * Called when you are no longer visible to the user.  You will next
     * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
+43 −0
Original line number Diff line number Diff line
@@ -1818,6 +1818,24 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case GET_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int requestType = data.readInt();
            Bundle res = getTopActivityExtras(requestType);
            reply.writeNoException();
            reply.writeBundle(res);
            return true;
        }

        case REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            Bundle extras = data.readBundle();
            reportTopActivityExtras(token, extras);
            reply.writeNoException();
            return true;
        }

        }

        return super.onTransact(code, data, reply, flags);
@@ -4149,5 +4167,30 @@ class ActivityManagerProxy implements IActivityManager
        return res;
    }

    public Bundle getTopActivityExtras(int requestType) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(requestType);
        mRemote.transact(GET_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
        reply.readException();
        Bundle res = reply.readBundle();
        data.recycle();
        reply.recycle();
        return res;
    }

    public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        data.writeBundle(extras);
        mRemote.transact(REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    private IBinder mRemote;
}
+38 −0
Original line number Diff line number Diff line
@@ -534,6 +534,12 @@ public final class ActivityThread {
        CompatibilityInfo info;
    }

    static final class RequestActivityExtras {
        IBinder activityToken;
        IBinder requestToken;
        int requestType;
    }
    
    private native void dumpGraphicsInfo(FileDescriptor fd);

    private class ApplicationThread extends ApplicationThreadNative {
@@ -1108,6 +1114,16 @@ public final class ActivityThread {
            queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
        }

        @Override
        public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
                int requestType) {
            RequestActivityExtras cmd = new RequestActivityExtras();
            cmd.activityToken = activityToken;
            cmd.requestToken = requestToken;
            cmd.requestType = requestType;
            queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
        }

        private void printRow(PrintWriter pw, String format, Object...objs) {
            pw.println(String.format(format, objs));
        }
@@ -1173,6 +1189,7 @@ public final class ActivityThread {
        public static final int TRIM_MEMORY             = 140;
        public static final int DUMP_PROVIDER           = 141;
        public static final int UNSTABLE_PROVIDER_DIED  = 142;
        public static final int REQUEST_ACTIVITY_EXTRAS = 143;
        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
                switch (code) {
@@ -1219,6 +1236,7 @@ public final class ActivityThread {
                    case TRIM_MEMORY: return "TRIM_MEMORY";
                    case DUMP_PROVIDER: return "DUMP_PROVIDER";
                    case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
                    case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
                }
            }
            return Integer.toString(code);
@@ -1430,6 +1448,9 @@ public final class ActivityThread {
                case UNSTABLE_PROVIDER_DIED:
                    handleUnstableProviderDied((IBinder)msg.obj, false);
                    break;
                case REQUEST_ACTIVITY_EXTRAS:
                    handleRequestActivityExtras((RequestActivityExtras)msg.obj);
                    break;
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
@@ -2322,6 +2343,23 @@ public final class ActivityThread {
        performNewIntents(data.token, data.intents);
    }

    public void handleRequestActivityExtras(RequestActivityExtras cmd) {
        Bundle data = new Bundle();
        ActivityClientRecord r = mActivities.get(cmd.activityToken);
        if (r != null) {
            r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
            r.activity.onProvideAssistData(data);
        }
        if (data.isEmpty()) {
            data = null;
        }
        IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.reportTopActivityExtras(cmd.requestToken, data);
        } catch (RemoteException e) {
        }
    }
    
    private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();

    /**
+50 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;

@@ -45,6 +46,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
            new ArrayList<ComponentCallbacks>();
    private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
            new ArrayList<ActivityLifecycleCallbacks>();
    private ArrayList<OnProvideAssistData> mAssistCallbacks = null;

    /** @hide */
    public LoadedApk mLoadedApk;
@@ -59,6 +61,21 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
        void onActivityDestroyed(Activity activity);
    }

    /**
     * Callback interface for use with {@link Application#registerOnProvideAssistData}
     * and {@link Application#unregisterOnProvideAssistData}.
     */
    public interface OnProvideAssistData {
        /**
         * This is called when the user is requesting an assist, to build a full
         * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
         * application.  You can override this method to place into the bundle anything
         * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
         * of the assist Intent.
         */
        public void onProvideAssistData(Activity activity, Bundle data);
    }

    public Application() {
        super(null);
    }
@@ -138,6 +155,23 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
        }
    }

    public void registerOnProvideAssistData(OnProvideAssistData callback) {
        synchronized (this) {
            if (mAssistCallbacks == null) {
                mAssistCallbacks = new ArrayList<OnProvideAssistData>();
            }
            mAssistCallbacks.add(callback);
        }
    }

    public void unregisterOnProvideAssistData(OnProvideAssistData callback) {
        synchronized (this) {
            if (mAssistCallbacks != null) {
                mAssistCallbacks.remove(callback);
            }
        }
    }

    // ------------------ Internal API ------------------
    
    /**
@@ -232,4 +266,19 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
        }
        return callbacks;
    }

    /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) {
        Object[] callbacks;
        synchronized (this) {
            if (mAssistCallbacks == null) {
                return;
            }
            callbacks = mAssistCallbacks.toArray();
        }
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((OnProvideAssistData)callbacks[i]).onProvideAssistData(activity, data);
            }
        }
    }
}
Loading