am 3aefa438: am 78ead58d: Merge "Fix issue #22531747: Assist info should declare if user has disabled..." into mnc-dev

* commit '3aefa438300b116d2c080de434e0a890bf1dded5':
  Fix issue #22531747: Assist info should declare if user has disabled...
This commit is contained in:
Dianne Hackborn
2015-07-20 20:12:48 +00:00
committed by Android Git Automerger
19 changed files with 262 additions and 100 deletions

View File

@ -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();
@ -28808,6 +28809,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);
@ -28843,6 +28845,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

View File

@ -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();
@ -30960,6 +30961,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);
@ -30995,6 +30997,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

View File

@ -1544,6 +1544,24 @@ public class Activity extends ContextThemeWrapper
public void onProvideAssistContent(AssistContent outContent) {
}
/**
* 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,

View File

@ -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,

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
@ -935,6 +941,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
@ -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) {

View File

@ -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() {

View File

@ -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.

View File

@ -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() {

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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: ");

View File

@ -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 {

View File

@ -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>

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);
}
};
}