summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-07-17 18:04:14 -0700
committerDianne Hackborn <hackbod@google.com>2015-07-20 12:49:10 -0700
commit17f693520da8977c4a60f5b4be3be035cba7146c (patch)
tree6e3fcf5d6adb3d72ab5b7c2300f3bb8ebe8bc550
parent5aff3b5489262ccff4b6f9e18e0d990ebfe4d7bc (diff)
downloadframeworks_base-17f693520da8977c4a60f5b4be3be035cba7146c.zip
frameworks_base-17f693520da8977c4a60f5b4be3be035cba7146c.tar.gz
frameworks_base-17f693520da8977c4a60f5b4be3be035cba7146c.tar.bz2
Fix issue #22531747: Assist info should declare if user has disabled...
...context and/or screenshot Added new API to find out what contextual data has been globally disabled. Also updated various documentation to make it clear what kind of contextual data you will get (and when it will be null). Also added a new Activity.showAssist() API because... well, I was already in there, it was easy to do, it is safe, and maybe people will build cool things with it. Change-Id: Ia553d6bcdd098dc0fce4b9237fbfaca9652fc74b
-rw-r--r--api/current.txt3
-rw-r--r--api/system-current.txt3
-rw-r--r--core/java/android/app/Activity.java18
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/ActivityManagerNative.java39
-rw-r--r--core/java/android/app/IActivityManager.java9
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java43
-rw-r--r--core/java/com/android/internal/app/AssistUtils.java9
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl9
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java54
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java56
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java25
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java40
-rw-r--r--tests/VoiceInteraction/res/layout/voice_interaction_session.xml6
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java15
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java24
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java1
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java2
19 files changed, 262 insertions, 100 deletions
diff --git a/api/current.txt b/api/current.txt
index ea33eaf..f15f699 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3466,6 +3466,7 @@ package android.app {
method public final void setVolumeControlStream(int);
method public boolean shouldShowRequestPermissionRationale(java.lang.String);
method public boolean shouldUpRecreateTask(android.content.Intent);
+ method public boolean showAssist(android.os.Bundle);
method public final deprecated void showDialog(int);
method public final deprecated boolean showDialog(int, android.os.Bundle);
method public void showLockTaskEscapeMessage();
@@ -28805,6 +28806,7 @@ package android.service.voice {
method public android.content.Context getContext();
method public int getDisabledShowContext();
method public android.view.LayoutInflater getLayoutInflater();
+ method public int getUserDisabledShowContext();
method public android.app.Dialog getWindow();
method public void hide();
method public void onAssistStructureFailure(java.lang.Throwable);
@@ -28840,6 +28842,7 @@ package android.service.voice {
method public void setTheme(int);
method public void show(android.os.Bundle, int);
method public void startVoiceActivity(android.content.Intent);
+ field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
field public static final int SHOW_WITH_ASSIST = 1; // 0x1
field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index d1e19fb..f9017dc 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3569,6 +3569,7 @@ package android.app {
method public final void setVolumeControlStream(int);
method public boolean shouldShowRequestPermissionRationale(java.lang.String);
method public boolean shouldUpRecreateTask(android.content.Intent);
+ method public boolean showAssist(android.os.Bundle);
method public final deprecated void showDialog(int);
method public final deprecated boolean showDialog(int, android.os.Bundle);
method public void showLockTaskEscapeMessage();
@@ -30957,6 +30958,7 @@ package android.service.voice {
method public android.content.Context getContext();
method public int getDisabledShowContext();
method public android.view.LayoutInflater getLayoutInflater();
+ method public int getUserDisabledShowContext();
method public android.app.Dialog getWindow();
method public void hide();
method public void onAssistStructureFailure(java.lang.Throwable);
@@ -30992,6 +30994,7 @@ package android.service.voice {
method public void setTheme(int);
method public void show(android.os.Bundle, int);
method public void startVoiceActivity(android.content.Intent);
+ field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8
field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4
field public static final int SHOW_WITH_ASSIST = 1; // 0x1
field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 96c7f84..8d4ce62 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1545,6 +1545,24 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Ask to have the current assistant shown to the user. This only works if the calling
+ * activity is the current foreground activity. It is the same as calling
+ * {@link android.service.voice.VoiceInteractionService#showSession
+ * VoiceInteractionService.showSession} and requesting all of the possible context.
+ * The receiver will always see
+ * {@link android.service.voice.VoiceInteractionSession#SHOW_SOURCE_APPLICATION} set.
+ * @return Returns true if the assistant was successfully invoked, else false. For example
+ * false will be returned if the caller is not the current top activity.
+ */
+ public boolean showAssist(Bundle args) {
+ try {
+ return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9ca206a..55b2fd9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2807,7 +2807,7 @@ public class ActivityManager {
/**
* Request that the system start watching for the calling process to exceed a pss
- * size as given here. Once called, the system will look for any occassions where it
+ * size as given here. Once called, the system will look for any occasions where it
* sees the associated process with a larger pss size and, when this happens, automatically
* pull a heap dump from it and allow the user to share the data. Note that this request
* continues running even if the process is killed and restarted. To remove the watch,
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index bfb92c4..b758a7a 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2193,8 +2193,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
int requestType = data.readInt();
IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder());
- requestAssistContextExtras(requestType, receiver);
+ IBinder activityToken = data.readStrongBinder();
+ boolean res = requestAssistContextExtras(requestType, receiver, activityToken);
reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
return true;
}
@@ -2225,7 +2227,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
- boolean res = isScreenCaptureAllowedOnCurrentActivity();
+ boolean res = isAssistDataAllowedOnCurrentActivity();
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
+ case SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ Bundle args = data.readBundle();
+ boolean res = showAssistFromActivity(token, args);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -5377,17 +5389,20 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
- throws RemoteException {
+ public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
+ IBinder activityToken) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(requestType);
data.writeStrongBinder(receiver.asBinder());
+ data.writeStrongBinder(activityToken);
mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
+ boolean res = reply.readInt() != 0;
data.recycle();
reply.recycle();
+ return res;
}
public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
@@ -5429,7 +5444,7 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException {
+ public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -5441,6 +5456,20 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ data.writeBundle(args);
+ mRemote.transact(SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void killUid(int uid, String reason) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5eb3961..9ebbb9b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -434,8 +434,8 @@ public interface IActivityManager extends IInterface {
public Bundle getAssistContextExtras(int requestType) throws RemoteException;
- public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
- throws RemoteException;
+ public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
+ IBinder activityToken) throws RemoteException;
public void reportAssistContextExtras(IBinder token, Bundle extras,
AssistStructure structure, AssistContent content, Uri referrer) throws RemoteException;
@@ -443,7 +443,9 @@ public interface IActivityManager extends IInterface {
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) throws RemoteException;
- public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException;
+ public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException;
+
+ public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException;
public void killUid(int uid, String reason) throws RemoteException;
@@ -858,4 +860,5 @@ public interface IActivityManager extends IInterface {
int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
= IBinder.FIRST_CALL_TRANSACTION+299;
+ int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 95f96e8..a3ccbd3 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -91,6 +91,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
*/
public static final int SHOW_SOURCE_ASSIST_GESTURE = 1<<2;
+ /**
+ * Flag for use with {@link #onShow}: indicates that the application itself has invoked
+ * the assistant.
+ */
+ public static final int SHOW_SOURCE_APPLICATION = 1<<3;
+
final Context mContext;
final HandlerCaller mHandlerCaller;
@@ -936,6 +942,23 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
/**
+ * Return which show context flags have been disabled by the user through the system
+ * settings UI, so the session will never get this data. Returned flags are any combination of
+ * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
+ * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}. Note that this only tells you about
+ * global user settings, not about restrictions that may be applied contextual based on
+ * the current application the user is in or other transient states.
+ */
+ public int getUserDisabledShowContext() {
+ try {
+ return mSystemService.getUserDisabledShowContext();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ /**
* Show the UI for this session. This asks the system to go through the process of showing
* your UI, which will eventually culminate in {@link #onShow}. This is similar to calling
* {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
@@ -1179,23 +1202,33 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* Called to receive data from the application that the user was currently viewing when
- * an assist session is started.
+ * an assist session is started. If the original show request did not specify
+ * {@link #SHOW_WITH_ASSIST}, this method will not be called.
*
* @param data Arbitrary data supplied by the app through
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
+ * May be null if assist data has been disabled by the user or device policy.
* @param structure If available, the structure definition of all windows currently
- * displayed by the app; if structure has been turned off by the user, will be null.
+ * displayed by the app. May be null if assist data has been disabled by the user
+ * or device policy; will be an empty stub if the application has disabled assist
+ * by marking its window as secure.
* @param content Additional content data supplied by the app through
* {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
+ * May be null if assist data has been disabled by the user or device policy; will
+ * not be automatically filled in with data from the app if the app has marked its
+ * window as secure.
*/
- public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+ public void onHandleAssist(@Nullable Bundle data, @Nullable AssistStructure structure,
+ @Nullable AssistContent content) {
}
/**
* Called to receive a screenshot of what the user was currently viewing when an assist
- * session is started. Will be null if screenshots are disabled by the user.
+ * session is started. May be null if screenshots are disabled by the user, policy,
+ * or application. If the original show request did not specify
+ * {@link #SHOW_WITH_SCREENSHOT}, this method will not be called.
*/
- public void onHandleScreenshot(Bitmap screenshot) {
+ public void onHandleScreenshot(@Nullable Bitmap screenshot) {
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 6ba09c9..ff989bd 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -45,13 +46,15 @@ public class AssistUtils {
ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
}
- public void showSessionForActiveService(Bundle args,
- IVoiceInteractionSessionShowCallback showCallback) {
+ public boolean showSessionForActiveService(Bundle args, int sourceFlags,
+ IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
try {
- mVoiceInteractionManagerService.showSessionForActiveService(args, showCallback);
+ return mVoiceInteractionManagerService.showSessionForActiveService(args, sourceFlags,
+ showCallback, activityToken);
} catch (RemoteException e) {
Log.w(TAG, "Failed to call showSessionForActiveService", e);
}
+ return false;
}
public void launchVoiceAssistFromKeyguard() {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 73ad981..dc946ab 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -39,6 +39,7 @@ interface IVoiceInteractionManagerService {
void finish(IBinder token);
void setDisabledShowContext(int flags);
int getDisabledShowContext();
+ int getUserDisabledShowContext();
/**
* Gets the registered Sound model for keyphrase detection for the current user.
@@ -96,10 +97,12 @@ interface IVoiceInteractionManagerService {
* affordances.
*
* @param args the bundle to pass as arguments to the voice interaction session
- * @param showCallback callback to be notified when the session was shown
+ * @param sourceFlags flags indicating the source of this show
+ * @param showCallback optional callback to be notified when the session was shown
+ * @param activityToken optional token of activity that needs to be on top
*/
- void showSessionForActiveService(in Bundle args,
- IVoiceInteractionSessionShowCallback showCallback);
+ boolean showSessionForActiveService(in Bundle args, int sourceFlags,
+ IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken);
/**
* Hides the session from the active service, if it is showing.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 0daa5c9..f66a7dd 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -18,6 +18,7 @@ import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.voice.VoiceInteractionSession;
import android.util.Log;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -218,7 +219,8 @@ public class AssistManager {
}
private void startVoiceInteractor(Bundle args) {
- mAssistUtils.showSessionForActiveService(args, mShowCallback);
+ mAssistUtils.showSessionForActiveService(args,
+ VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, null);
}
public void launchVoiceAssistFromKeyguard() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3bf6fde..eb6579c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -65,6 +65,7 @@ import android.os.storage.IMountService;
import android.os.storage.MountServiceInternal;
import android.os.storage.StorageManager;
import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.VoiceInteractionSession;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
@@ -73,6 +74,7 @@ import android.view.Display;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.AssistUtils;
import com.android.internal.app.DumpHeapActivity;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IVoiceInteractor;
@@ -10686,7 +10688,7 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public Bundle getAssistContextExtras(int requestType) {
PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
- UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
+ null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
if (pae == null) {
return null;
}
@@ -10707,7 +10709,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
- public boolean isScreenCaptureAllowedOnCurrentActivity() {
+ public boolean isAssistDataAllowedOnCurrentActivity() {
int userId = mCurrentUserId;
synchronized (this) {
ActivityRecord activity = getFocusedStack().topActivity();
@@ -10722,13 +10724,41 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
- public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
- enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
- null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
+ public boolean showAssistFromActivity(IBinder token, Bundle args) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ ActivityRecord caller = ActivityRecord.forTokenLocked(token);
+ ActivityRecord top = getFocusedStack().topActivity();
+ if (top != caller) {
+ Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+ + " is not current top " + top);
+ return false;
+ }
+ if (!top.nowVisible) {
+ Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+ + " is not visible");
+ return false;
+ }
+ }
+ AssistUtils utils = new AssistUtils(mContext);
+ return utils.showSessionForActiveService(args,
+ VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
+ IBinder activityToken) {
+ return enqueueAssistContext(requestType, null, null, receiver, activityToken,
+ UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
}
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
- IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
+ IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
+ long timeout) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"enqueueAssistContext()");
synchronized (this) {
@@ -10741,9 +10771,13 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
return null;
}
- if (activity.app.pid == Binder.getCallingPid()) {
- Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
- return null;
+ if (activityToken != null) {
+ ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
+ if (activity != caller) {
+ Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
+ + " is not current top " + activity);
+ return null;
+ }
}
PendingAssistExtras pae;
Bundle extras = new Bundle();
@@ -10854,7 +10888,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) {
- return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
+ return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 42f879c..b57c413 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -448,7 +448,7 @@ public class VoiceInteractionManagerService extends SystemService {
}
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.showSessionLocked(args, flags, null /* showCallback */);
+ mImpl.showSessionLocked(args, flags, null, null);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -463,12 +463,9 @@ public class VoiceInteractionManagerService extends SystemService {
throw new SecurityException(
"deliverNewSession without running voice interaction service");
}
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- return mImpl.deliverNewSessionLocked(callingPid, callingUid, token, session,
- interactor);
+ return mImpl.deliverNewSessionLocked(token, session, interactor);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -484,7 +481,7 @@ public class VoiceInteractionManagerService extends SystemService {
}
final long caller = Binder.clearCallingIdentity();
try {
- return mImpl.showSessionLocked(sessionArgs, flags, null /* showCallback */);
+ return mImpl.showSessionLocked(sessionArgs, flags, null, null);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -533,11 +530,9 @@ public class VoiceInteractionManagerService extends SystemService {
Slog.w(TAG, "setKeepAwake without running voice interaction service");
return;
}
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.setKeepAwakeLocked(callingPid, callingUid, token, keepAwake);
+ mImpl.setKeepAwakeLocked(token, keepAwake);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -551,11 +546,9 @@ public class VoiceInteractionManagerService extends SystemService {
Slog.w(TAG, "closeSystemDialogs without running voice interaction service");
return;
}
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.closeSystemDialogsLocked(callingPid, callingUid, token);
+ mImpl.closeSystemDialogsLocked(token);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -585,16 +578,14 @@ public class VoiceInteractionManagerService extends SystemService {
Slog.w(TAG, "setDisabledShowContext without running voice interaction service");
return;
}
- final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.setDisabledShowContextLocked(callingPid, callingUid, flags);
+ mImpl.setDisabledShowContextLocked(callingUid, flags);
} finally {
Binder.restoreCallingIdentity(caller);
}
}
-
}
@Override
@@ -604,16 +595,32 @@ public class VoiceInteractionManagerService extends SystemService {
Slog.w(TAG, "getDisabledShowContext without running voice interaction service");
return 0;
}
- final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- return mImpl.getDisabledShowContextLocked(callingPid, callingUid);
+ return mImpl.getDisabledShowContextLocked(callingUid);
} finally {
Binder.restoreCallingIdentity(caller);
}
}
+ }
+ @Override
+ public int getUserDisabledShowContext() {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG,
+ "getUserDisabledShowContext without running voice interaction service");
+ return 0;
+ }
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ return mImpl.getUserDisabledShowContextLocked(callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
}
//----------------- Model management APIs --------------------------------//
@@ -799,22 +806,22 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
- public void showSessionForActiveService(Bundle args,
- IVoiceInteractionSessionShowCallback showCallback) {
+ public boolean showSessionForActiveService(Bundle args, int sourceFlags,
+ IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "showSessionForActiveService without running voice interaction"
+ "service");
- return;
+ return false;
}
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.showSessionLocked(args,
- VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE
+ return mImpl.showSessionLocked(args,
+ sourceFlags
| VoiceInteractionSession.SHOW_WITH_ASSIST
| VoiceInteractionSession.SHOW_WITH_SCREENSHOT,
- showCallback);
+ showCallback, activityToken);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -908,7 +915,8 @@ public class VoiceInteractionManagerService extends SystemService {
}
private void enforceCallingPermission(String permission) {
- if (mContext.checkCallingPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+ if (mContext.checkCallingOrSelfPermission(permission)
+ != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Caller does not hold the permission " + permission);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 7409f99..a4facc1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -142,12 +142,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
public boolean showSessionLocked(Bundle args, int flags,
- IVoiceInteractionSessionShowCallback showCallback) {
+ IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
if (mActiveSession == null) {
mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler);
}
- return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback);
+ return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback,
+ activityToken);
}
public boolean hideSessionLocked() {
@@ -157,7 +158,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
return false;
}
- public boolean deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
+ public boolean deliverNewSessionLocked(IBinder token,
IVoiceInteractionSession session, IVoiceInteractor interactor) {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "deliverNewSession does not match active session");
@@ -189,8 +190,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
}
- public void setKeepAwakeLocked(int callingPid, int callingUid, IBinder token,
- boolean keepAwake) {
+ public void setKeepAwakeLocked(IBinder token, boolean keepAwake) {
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "setKeepAwake does not match active session");
@@ -202,7 +202,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
}
- public void closeSystemDialogsLocked(int callingPid, int callingUid, IBinder token) {
+ public void closeSystemDialogsLocked(IBinder token) {
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "closeSystemDialogs does not match active session");
@@ -223,7 +223,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mActiveSession = null;
}
- public void setDisabledShowContextLocked(int callingPid, int callingUid, int flags) {
+ public void setDisabledShowContextLocked(int callingUid, int flags) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
throw new SecurityException("Calling uid " + callingUid
@@ -232,7 +232,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mDisabledShowContext = flags;
}
- public int getDisabledShowContextLocked(int callingPid, int callingUid) {
+ public int getDisabledShowContextLocked(int callingUid) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
throw new SecurityException("Calling uid " + callingUid
@@ -241,6 +241,15 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
return mDisabledShowContext;
}
+ public int getUserDisabledShowContextLocked(int callingUid) {
+ int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
+ if (callingUid != activeUid) {
+ throw new SecurityException("Calling uid " + callingUid
+ + " does not match active uid " + activeUid);
+ }
+ return mActiveSession != null ? mActiveSession.getUserDisabledShowContextLocked() : 0;
+ }
+
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!mValid) {
pw.print(" NOT VALID: ");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index dfdd639..47a9fcd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -183,8 +183,21 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
}
}
+ public int getUserDisabledShowContextLocked() {
+ int flags = 0;
+ if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) == 0) {
+ flags |= VoiceInteractionSession.SHOW_WITH_ASSIST;
+ }
+ if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) == 0) {
+ flags |= VoiceInteractionSession.SHOW_WITH_SCREENSHOT;
+ }
+ return flags;
+ }
+
public boolean showLocked(Bundle args, int flags, int disabledContext,
- IVoiceInteractionSessionShowCallback showCallback) {
+ IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
if (mBound) {
if (!mFullyBound) {
mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
@@ -193,18 +206,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
new UserHandle(mUser));
}
mShown = true;
- boolean isScreenCaptureAllowed = true;
+ boolean isAssistDataAllowed = true;
try {
- isScreenCaptureAllowed = mAm.isScreenCaptureAllowedOnCurrentActivity();
+ isAssistDataAllowed = mAm.isAssistDataAllowedOnCurrentActivity();
} catch (RemoteException e) {
}
- boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0
- && isScreenCaptureAllowed
+ disabledContext |= getUserDisabledShowContextLocked();
+ boolean structureEnabled = isAssistDataAllowed
&& (disabledContext&VoiceInteractionSession.SHOW_WITH_ASSIST) == 0;
- boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0
- && isScreenCaptureAllowed
+ boolean screenshotEnabled = isAssistDataAllowed
&& (disabledContext&VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0;
mShowArgs = args;
mShowFlags = flags;
@@ -215,9 +225,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& structureEnabled) {
try {
- needDisclosure = true;
- mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
- mAssistReceiver);
+ if (mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
+ mAssistReceiver, activityToken)) {
+ needDisclosure = true;
+ } else {
+ // Wasn't allowed... given that, let's not do the screenshot either.
+ mHaveAssistData = true;
+ mAssistData = null;
+ screenshotEnabled = false;
+ }
} catch (RemoteException e) {
}
} else {
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index dc4e31b..b106437 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -80,6 +80,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Disallow screenshot" />
+ <TextView android:id="@+id/options_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 8381aa1..f1dd1de 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -74,21 +74,6 @@ public class MainInteractionService extends VoiceInteractionService {
"Hello There", Locale.forLanguageTag("en-US"), mHotwordCallback);
}
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (isActiveService(this, new ComponentName(this, getClass()))) {
- Bundle args = new Bundle();
- args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
- args.putBundle("assist", intent.getExtras());
- showSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST
- | VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
- } else {
- Log.w(TAG, "Not starting -- not current voice interaction service");
- }
- stopSelf(startId);
- return START_NOT_STICKY;
- }
-
private void hotwordAvailabilityChangeHelper(int availability) {
Log.i(TAG, "Hotword availability = " + availability);
switch (availability) {
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index 8796c9f..c0a67c1 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -50,6 +50,7 @@ public class MainInteractionSession extends VoiceInteractionSession
View mOptionsContainer;
CheckBox mDisallowAssist;
CheckBox mDisallowScreenshot;
+ TextView mOptionsText;
ImageView mScreenshot;
ImageView mFullScreenshot;
Button mConfirmButton;
@@ -86,8 +87,9 @@ public class MainInteractionSession extends VoiceInteractionSession
@Override
public void onShow(Bundle args, int showFlags) {
super.onShow(args, showFlags);
+ Log.i(TAG, "onShow: flags=0x" + Integer.toHexString(showFlags) + " args=" + args);
mState = STATE_IDLE;
- mStartIntent = args.getParcelable("intent");
+ mStartIntent = args != null ? (Intent)args.getParcelable("intent") : null;
if (mStartIntent == null) {
mStartIntent = new Intent(getContext(), TestInteractionActivity.class);
}
@@ -96,6 +98,7 @@ public class MainInteractionSession extends VoiceInteractionSession
}
onHandleScreenshot(null);
updateState();
+ refreshOptions();
}
@Override
@@ -134,6 +137,7 @@ public class MainInteractionSession extends VoiceInteractionSession
mDisallowAssist.setOnClickListener(this);
mDisallowScreenshot = (CheckBox)mContentView.findViewById(R.id.disallow_screenshot);
mDisallowScreenshot.setOnClickListener(this);
+ mOptionsText = (TextView)mContentView.findViewById(R.id.options_text);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -145,13 +149,17 @@ public class MainInteractionSession extends VoiceInteractionSession
}
void refreshOptions() {
- if (mOptionsCheck.isChecked()) {
- mOptionsContainer.setVisibility(View.VISIBLE);
- int flags = getDisabledShowContext();
- mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0);
- mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0);
- } else {
- mOptionsContainer.setVisibility(View.GONE);
+ if (mOptionsContainer != null) {
+ if (mOptionsCheck.isChecked()) {
+ mOptionsContainer.setVisibility(View.VISIBLE);
+ int flags = getDisabledShowContext();
+ mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0);
+ mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0);
+ int disabled = getUserDisabledShowContext();
+ mOptionsText.setText("Disabled: 0x" + Integer.toHexString(disabled));
+ } else {
+ mOptionsContainer.setVisibility(View.GONE);
+ }
}
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index b0d6b39..e10d89f 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -16,7 +16,6 @@
package com.android.test.voiceinteraction;
-import android.annotation.Nullable;
import android.app.Activity;
import android.app.VoiceInteractor;
import android.content.ComponentName;
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
index a7636c3..ee75f28 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java
@@ -49,7 +49,7 @@ public class VoiceInteractionMain extends Activity {
View.OnClickListener mStartListener = new View.OnClickListener() {
public void onClick(View v) {
- startService(new Intent(VoiceInteractionMain.this, MainInteractionService.class));
+ showAssist(null);
}
};
}