am d8ba6cc9
: Merge "Add new API to propagate contextual data to the assist action"
# Via Android (Google) Code Review (1) and Dianne Hackborn (1) * commit 'd8ba6cc9217e2e042106870e9d2e70cfd80426d6': Add new API to propagate contextual data to the assist action
This commit is contained in:
@ -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";
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -533,6 +533,12 @@ public final class ActivityThread {
|
||||
String pkg;
|
||||
CompatibilityInfo info;
|
||||
}
|
||||
|
||||
static final class RequestActivityExtras {
|
||||
IBinder activityToken;
|
||||
IBinder requestToken;
|
||||
int requestType;
|
||||
}
|
||||
|
||||
private native void dumpGraphicsInfo(FileDescriptor fd);
|
||||
|
||||
@ -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>();
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
@ -137,7 +154,24 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
|
||||
mActivityLifecycleCallbacks.remove(callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -587,6 +587,17 @@ public abstract class ApplicationThreadNative extends Binder
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
|
||||
case REQUEST_ACTIVITY_EXTRAS_TRANSACTION:
|
||||
{
|
||||
data.enforceInterface(IApplicationThread.descriptor);
|
||||
IBinder activityToken = data.readStrongBinder();
|
||||
IBinder requestToken = data.readStrongBinder();
|
||||
int requestType = data.readInt();
|
||||
requestActivityExtras(activityToken, requestToken, requestType);
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
@ -1185,4 +1196,15 @@ class ApplicationThreadProxy implements IApplicationThread {
|
||||
mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
|
||||
data.recycle();
|
||||
}
|
||||
|
||||
public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
|
||||
throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
data.writeInterfaceToken(IApplicationThread.descriptor);
|
||||
data.writeStrongBinder(activityToken);
|
||||
data.writeStrongBinder(requestToken);
|
||||
data.writeInt(requestType);
|
||||
mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
|
||||
data.recycle();
|
||||
}
|
||||
}
|
||||
|
@ -368,6 +368,10 @@ public interface IActivityManager extends IInterface {
|
||||
|
||||
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
|
||||
|
||||
public Bundle getTopActivityExtras(int requestType) throws RemoteException;
|
||||
|
||||
public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
|
||||
|
||||
/*
|
||||
* Private non-Binder interfaces
|
||||
*/
|
||||
@ -624,4 +628,6 @@ public interface IActivityManager extends IInterface {
|
||||
int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
|
||||
int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
|
||||
int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
|
||||
int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
|
||||
int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
|
||||
}
|
||||
|
@ -130,6 +130,8 @@ public interface IApplicationThread extends IInterface {
|
||||
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
|
||||
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
|
||||
void unstableProviderDied(IBinder provider) throws RemoteException;
|
||||
void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
|
||||
throws RemoteException;
|
||||
|
||||
String descriptor = "android.app.IApplicationThread";
|
||||
|
||||
@ -179,4 +181,5 @@ public interface IApplicationThread extends IInterface {
|
||||
int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
|
||||
int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
|
||||
int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
|
||||
int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
|
||||
}
|
||||
|
@ -846,8 +846,8 @@ public class SearchManager
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Intent getAssistIntent(Context context) {
|
||||
return getAssistIntent(context, UserHandle.myUserId());
|
||||
public Intent getAssistIntent(Context context, boolean inclContext) {
|
||||
return getAssistIntent(context, inclContext, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -856,7 +856,7 @@ public class SearchManager
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public Intent getAssistIntent(Context context, int userHandle) {
|
||||
public Intent getAssistIntent(Context context, boolean inclContext, int userHandle) {
|
||||
try {
|
||||
if (mService == null) {
|
||||
return null;
|
||||
@ -867,6 +867,13 @@ public class SearchManager
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_ASSIST);
|
||||
intent.setComponent(comp);
|
||||
if (inclContext) {
|
||||
IActivityManager am = ActivityManagerNative.getDefault();
|
||||
Bundle extras = am.getTopActivityExtras(0);
|
||||
if (extras != null) {
|
||||
intent.replaceExtras(extras);
|
||||
}
|
||||
}
|
||||
return intent;
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "getAssistIntent() failed: " + re);
|
||||
|
@ -1140,14 +1140,33 @@ public class Intent implements Parcelable, Cloneable {
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
|
||||
|
||||
/**
|
||||
* Activity Action: Perform assist action.
|
||||
* <p>
|
||||
* Input: nothing
|
||||
* Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
|
||||
* additional optional contextual information about where the user was when they requested
|
||||
* the assist.
|
||||
* Output: nothing.
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_ASSIST = "android.intent.action.ASSIST";
|
||||
|
||||
/**
|
||||
* An optional field on {@link #ACTION_ASSIST} containing the name of the current
|
||||
* foreground application package at the time the assist was invoked.
|
||||
*/
|
||||
public static final String EXTRA_ASSIST_PACKAGE
|
||||
= "android.intent.extra.ASSIST_PACKAGE";
|
||||
|
||||
/**
|
||||
* An optional field on {@link #ACTION_ASSIST} containing additional contextual
|
||||
* information supplied by the current foreground app at the time of the assist
|
||||
* request. This is a {@link Bundle} of additional data.
|
||||
*/
|
||||
public static final String EXTRA_ASSIST_CONTEXT
|
||||
= "android.intent.extra.ASSIST_CONTEXT";
|
||||
|
||||
/**
|
||||
* Activity Action: List all available applications
|
||||
* <p>Input: Nothing.
|
||||
|
@ -182,7 +182,7 @@ class SimulatedDpad {
|
||||
|
||||
Intent intent =
|
||||
((SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT_OR_SELF);
|
||||
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT_OR_SELF);
|
||||
if (intent != null) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
|
@ -1702,6 +1702,13 @@
|
||||
android:description="@string/permdesc_stopAppSwitches"
|
||||
android:protectionLevel="signature|system" />
|
||||
|
||||
<!-- Allows an application to retrieve private information about
|
||||
the current top activity, such as any assist context it can provide. -->
|
||||
<permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
|
||||
android:label="@string/permlab_getTopActivityInfo"
|
||||
android:description="@string/permdesc_getTopActivityInfo"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<!-- Allows an application to retrieve the current state of keys and
|
||||
switches. This is only for use by the system.
|
||||
@deprecated The API that used this permission has been removed. -->
|
||||
|
@ -783,6 +783,12 @@
|
||||
<string name="permdesc_stopAppSwitches">Prevents the user from switching to
|
||||
another app.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_getTopActivityInfo">get current app info</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permdesc_getTopActivityInfo">Allows the holder to retrieve private information
|
||||
about the current application in the foreground of the screen.</string>
|
||||
|
||||
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
<string name="permlab_runSetActivityWatcher">monitor and control all app launching</string>
|
||||
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
|
||||
|
@ -49,7 +49,8 @@
|
||||
<uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" />
|
||||
<uses-permission android:name="android.permission.START_ANY_ACTIVITY" />
|
||||
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
|
||||
|
||||
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
|
||||
|
||||
<!-- WindowManager -->
|
||||
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
|
@ -103,7 +103,7 @@ public class SearchPanelView extends FrameLayout implements
|
||||
} else {
|
||||
// Otherwise, keyguard isn't showing so launch it from here.
|
||||
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
|
||||
if (intent == null) return;
|
||||
|
||||
try {
|
||||
@ -180,7 +180,7 @@ public class SearchPanelView extends FrameLayout implements
|
||||
|
||||
private void maybeSwapSearchIcon() {
|
||||
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
|
||||
if (intent != null) {
|
||||
ComponentName component = intent.getComponent();
|
||||
if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
|
||||
@ -329,6 +329,6 @@ public class SearchPanelView extends FrameLayout implements
|
||||
|
||||
public boolean isAssistantAvailable() {
|
||||
return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
|
||||
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
|
||||
}
|
||||
}
|
||||
|
@ -2206,7 +2206,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
private void launchAssistAction() {
|
||||
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
|
||||
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
|
||||
if (intent != null) {
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
|
@ -1567,7 +1567,7 @@ public class KeyguardHostView extends KeyguardViewBase {
|
||||
|
||||
public void showAssistant() {
|
||||
final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
|
||||
|
||||
if (intent == null) return;
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
|
||||
case com.android.internal.R.drawable.ic_action_assist_generic:
|
||||
Intent assistIntent =
|
||||
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
|
||||
if (assistIntent != null) {
|
||||
mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
|
||||
} else {
|
||||
@ -195,7 +195,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
|
||||
currentUserHandle);
|
||||
boolean searchActionAvailable =
|
||||
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
|
||||
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
|
||||
mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
|
||||
|| !currentUserSetup;
|
||||
mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
|
||||
@ -207,7 +207,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
|
||||
// Update the search icon with drawable from the search .apk
|
||||
if (!mSearchDisabled) {
|
||||
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
|
||||
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
|
||||
.getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
|
||||
if (intent != null) {
|
||||
// XXX Hack. We need to substitute the icon here but haven't formalized
|
||||
// the public API. The "_google" metadata will be going away, so
|
||||
|
@ -1428,6 +1428,6 @@ public class KeyguardViewMediator {
|
||||
|
||||
private boolean isAssistantAvailable() {
|
||||
return mSearchManager != null
|
||||
&& mSearchManager.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
|
||||
&& mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
|
||||
}
|
||||
}
|
||||
|
@ -262,6 +262,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
// Maximum number of users we allow to be running at a time.
|
||||
static final int MAX_RUNNING_USERS = 3;
|
||||
|
||||
// How long to wait in getTopActivityExtras for the activity to respond with the result.
|
||||
static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
|
||||
|
||||
static final int MY_PID = Process.myPid();
|
||||
|
||||
static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
@ -319,11 +322,32 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
* Activity we have told the window manager to have key focus.
|
||||
*/
|
||||
ActivityRecord mFocusedActivity = null;
|
||||
|
||||
/**
|
||||
* List of intents that were used to start the most recent tasks.
|
||||
*/
|
||||
final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
|
||||
|
||||
public class PendingActivityExtras extends Binder implements Runnable {
|
||||
public final ActivityRecord activity;
|
||||
public boolean haveResult = false;
|
||||
public Bundle result = null;
|
||||
public PendingActivityExtras(ActivityRecord _activity) {
|
||||
activity = _activity;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
|
||||
synchronized (this) {
|
||||
haveResult = true;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<PendingActivityExtras> mPendingActivityExtras
|
||||
= new ArrayList<PendingActivityExtras>();
|
||||
|
||||
/**
|
||||
* Process management.
|
||||
*/
|
||||
@ -7451,6 +7475,63 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return KEY_DISPATCHING_TIMEOUT;
|
||||
}
|
||||
|
||||
public Bundle getTopActivityExtras(int requestType) {
|
||||
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
|
||||
"getTopActivityExtras()");
|
||||
PendingActivityExtras pae;
|
||||
Bundle extras = new Bundle();
|
||||
synchronized (this) {
|
||||
ActivityRecord activity = mMainStack.mResumedActivity;
|
||||
if (activity == null) {
|
||||
Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
|
||||
return null;
|
||||
}
|
||||
extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
|
||||
if (activity.app == null || activity.app.thread == null) {
|
||||
Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
|
||||
return extras;
|
||||
}
|
||||
if (activity.app.pid == Binder.getCallingPid()) {
|
||||
Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
|
||||
return extras;
|
||||
}
|
||||
pae = new PendingActivityExtras(activity);
|
||||
try {
|
||||
activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
|
||||
mPendingActivityExtras.add(pae);
|
||||
mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
|
||||
return extras;
|
||||
}
|
||||
}
|
||||
synchronized (pae) {
|
||||
while (!pae.haveResult) {
|
||||
try {
|
||||
pae.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
if (pae.result != null) {
|
||||
extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
mPendingActivityExtras.remove(pae);
|
||||
mHandler.removeCallbacks(pae);
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
|
||||
public void reportTopActivityExtras(IBinder token, Bundle extras) {
|
||||
PendingActivityExtras pae = (PendingActivityExtras)token;
|
||||
synchronized (pae) {
|
||||
pae.result = extras;
|
||||
pae.haveResult = true;
|
||||
pae.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerProcessObserver(IProcessObserver observer) {
|
||||
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
|
||||
"registerProcessObserver()");
|
||||
|
Reference in New Issue
Block a user