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:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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: ");
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user