summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}
};
}