am 14bafef5
: am 24922798
: am b20a8ed9
: am d9b0f843
: Merge "Fix issue #22860466: viapi security bug - rubber stamping in nested VIs" into mnc-dev
* commit '14bafef5b050f14c0fed3bfed8b137862139e627': Fix issue #22860466: viapi security bug - rubber stamping in nested VIs
This commit is contained in:
@ -3341,6 +3341,7 @@ package android.app {
|
|||||||
method public boolean isImmersive();
|
method public boolean isImmersive();
|
||||||
method public boolean isTaskRoot();
|
method public boolean isTaskRoot();
|
||||||
method public boolean isVoiceInteraction();
|
method public boolean isVoiceInteraction();
|
||||||
|
method public boolean isVoiceInteractionRoot();
|
||||||
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
|
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
|
||||||
method public boolean moveTaskToBack(boolean);
|
method public boolean moveTaskToBack(boolean);
|
||||||
method public boolean navigateUpTo(android.content.Intent);
|
method public boolean navigateUpTo(android.content.Intent);
|
||||||
|
@ -3444,6 +3444,7 @@ package android.app {
|
|||||||
method public boolean isImmersive();
|
method public boolean isImmersive();
|
||||||
method public boolean isTaskRoot();
|
method public boolean isTaskRoot();
|
||||||
method public boolean isVoiceInteraction();
|
method public boolean isVoiceInteraction();
|
||||||
|
method public boolean isVoiceInteractionRoot();
|
||||||
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
|
method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
|
||||||
method public boolean moveTaskToBack(boolean);
|
method public boolean moveTaskToBack(boolean);
|
||||||
method public boolean navigateUpTo(android.content.Intent);
|
method public boolean navigateUpTo(android.content.Intent);
|
||||||
|
@ -1228,6 +1228,22 @@ public class Activity extends ContextThemeWrapper
|
|||||||
return mVoiceInteractor != null;
|
return mVoiceInteractor != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like {@link #isVoiceInteraction}, but only returns true if this is also the root
|
||||||
|
* of a voice interaction. That is, returns true if this activity was directly
|
||||||
|
* started by the voice interaction service as the initiation of a voice interaction.
|
||||||
|
* Otherwise, for example if it was started by another activity while under voice
|
||||||
|
* interaction, returns false.
|
||||||
|
*/
|
||||||
|
public boolean isVoiceInteractionRoot() {
|
||||||
|
try {
|
||||||
|
return mVoiceInteractor != null
|
||||||
|
&& ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the active {@link VoiceInteractor} that the user is going through to
|
* Retrieve the active {@link VoiceInteractor} that the user is going through to
|
||||||
* interact with this activity.
|
* interact with this activity.
|
||||||
|
@ -2582,6 +2582,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
|||||||
reply.writeInt(res ? 1 : 0);
|
reply.writeInt(res ? 1 : 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case IS_ROOT_VOICE_INTERACTION_TRANSACTION: {
|
||||||
|
data.enforceInterface(IActivityManager.descriptor);
|
||||||
|
IBinder token = data.readStrongBinder();
|
||||||
|
boolean res = isRootVoiceInteraction(token);
|
||||||
|
reply.writeNoException();
|
||||||
|
reply.writeInt(res ? 1 : 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onTransact(code, data, reply, flags);
|
return super.onTransact(code, data, reply, flags);
|
||||||
@ -5962,5 +5971,19 @@ class ActivityManagerProxy implements IActivityManager
|
|||||||
return res != 0;
|
return res != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRootVoiceInteraction(IBinder token) throws RemoteException {
|
||||||
|
Parcel data = Parcel.obtain();
|
||||||
|
Parcel reply = Parcel.obtain();
|
||||||
|
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||||
|
data.writeStrongBinder(token);
|
||||||
|
mRemote.transact(IS_ROOT_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
|
||||||
|
reply.readException();
|
||||||
|
int res = reply.readInt();
|
||||||
|
data.recycle();
|
||||||
|
reply.recycle();
|
||||||
|
return res != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private IBinder mRemote;
|
private IBinder mRemote;
|
||||||
}
|
}
|
||||||
|
@ -515,6 +515,8 @@ public interface IActivityManager extends IInterface {
|
|||||||
public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
|
public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
|
||||||
throws RemoteException;
|
throws RemoteException;
|
||||||
|
|
||||||
|
public boolean isRootVoiceInteraction(IBinder token) throws RemoteException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private non-Binder interfaces
|
* Private non-Binder interfaces
|
||||||
*/
|
*/
|
||||||
@ -861,4 +863,5 @@ public interface IActivityManager extends IInterface {
|
|||||||
int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
|
int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
|
||||||
= IBinder.FIRST_CALL_TRANSACTION+299;
|
= IBinder.FIRST_CALL_TRANSACTION+299;
|
||||||
int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
|
int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
|
||||||
|
int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301;
|
||||||
}
|
}
|
||||||
|
@ -6540,6 +6540,17 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRootVoiceInteraction(IBinder token) {
|
||||||
|
synchronized(this) {
|
||||||
|
ActivityRecord r = ActivityRecord.isInStackLocked(token);
|
||||||
|
if (r == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return r.rootVoiceInteraction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIntentSender getIntentSender(int type,
|
public IIntentSender getIntentSender(int type,
|
||||||
String packageName, IBinder token, String resultWho,
|
String packageName, IBinder token, String resultWho,
|
||||||
|
@ -107,6 +107,7 @@ final class ActivityRecord {
|
|||||||
boolean fullscreen; // covers the full screen?
|
boolean fullscreen; // covers the full screen?
|
||||||
final boolean noDisplay; // activity is not displayed?
|
final boolean noDisplay; // activity is not displayed?
|
||||||
final boolean componentSpecified; // did caller specifiy an explicit component?
|
final boolean componentSpecified; // did caller specifiy an explicit component?
|
||||||
|
final boolean rootVoiceInteraction; // was this the root activity of a voice interaction?
|
||||||
|
|
||||||
static final int APPLICATION_ACTIVITY_TYPE = 0;
|
static final int APPLICATION_ACTIVITY_TYPE = 0;
|
||||||
static final int HOME_ACTIVITY_TYPE = 1;
|
static final int HOME_ACTIVITY_TYPE = 1;
|
||||||
@ -207,6 +208,9 @@ final class ActivityRecord {
|
|||||||
pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
|
pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
|
||||||
pw.print(" componentSpecified="); pw.print(componentSpecified);
|
pw.print(" componentSpecified="); pw.print(componentSpecified);
|
||||||
pw.print(" mActivityType="); pw.println(mActivityType);
|
pw.print(" mActivityType="); pw.println(mActivityType);
|
||||||
|
if (rootVoiceInteraction) {
|
||||||
|
pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
|
||||||
|
}
|
||||||
pw.print(prefix); pw.print("compat="); pw.print(compat);
|
pw.print(prefix); pw.print("compat="); pw.print(compat);
|
||||||
pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
|
pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
|
||||||
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
|
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
|
||||||
@ -432,7 +436,8 @@ final class ActivityRecord {
|
|||||||
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
|
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
|
||||||
ActivityInfo aInfo, Configuration _configuration,
|
ActivityInfo aInfo, Configuration _configuration,
|
||||||
ActivityRecord _resultTo, String _resultWho, int _reqCode,
|
ActivityRecord _resultTo, String _resultWho, int _reqCode,
|
||||||
boolean _componentSpecified, ActivityStackSupervisor supervisor,
|
boolean _componentSpecified, boolean _rootVoiceInteraction,
|
||||||
|
ActivityStackSupervisor supervisor,
|
||||||
ActivityContainer container, Bundle options) {
|
ActivityContainer container, Bundle options) {
|
||||||
service = _service;
|
service = _service;
|
||||||
appToken = new Token(this, service);
|
appToken = new Token(this, service);
|
||||||
@ -444,6 +449,7 @@ final class ActivityRecord {
|
|||||||
shortComponentName = _intent.getComponent().flattenToShortString();
|
shortComponentName = _intent.getComponent().flattenToShortString();
|
||||||
resolvedType = _resolvedType;
|
resolvedType = _resolvedType;
|
||||||
componentSpecified = _componentSpecified;
|
componentSpecified = _componentSpecified;
|
||||||
|
rootVoiceInteraction = _rootVoiceInteraction;
|
||||||
configuration = _configuration;
|
configuration = _configuration;
|
||||||
stackConfigOverride = (container != null)
|
stackConfigOverride = (container != null)
|
||||||
? container.mStack.mOverrideConfig : Configuration.EMPTY;
|
? container.mStack.mOverrideConfig : Configuration.EMPTY;
|
||||||
@ -1257,7 +1263,7 @@ final class ActivityRecord {
|
|||||||
}
|
}
|
||||||
final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
|
final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
|
||||||
launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(),
|
launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(),
|
||||||
null, null, 0, componentSpecified, stackSupervisor, null, null);
|
null, null, 0, componentSpecified, false, stackSupervisor, null, null);
|
||||||
|
|
||||||
r.persistentState = persistentState;
|
r.persistentState = persistentState;
|
||||||
r.taskDescription = taskDescription;
|
r.taskDescription = taskDescription;
|
||||||
|
@ -1506,6 +1506,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
|||||||
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
|
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
|
||||||
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
|
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
|
||||||
try {
|
try {
|
||||||
|
intent.addCategory(Intent.CATEGORY_VOICE);
|
||||||
if (!AppGlobals.getPackageManager().activitySupportsIntent(
|
if (!AppGlobals.getPackageManager().activitySupportsIntent(
|
||||||
intent.getComponent(), intent, resolvedType)) {
|
intent.getComponent(), intent, resolvedType)) {
|
||||||
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
|
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
|
||||||
@ -1626,7 +1627,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
|||||||
|
|
||||||
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
|
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
|
||||||
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
|
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
|
||||||
requestCode, componentSpecified, this, container, options);
|
requestCode, componentSpecified, voiceSession != null, this, container, options);
|
||||||
if (outActivity != null) {
|
if (outActivity != null) {
|
||||||
outActivity[0] = r;
|
outActivity[0] = r;
|
||||||
}
|
}
|
||||||
@ -3721,19 +3722,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisplayAdded(int displayId) {
|
public void onDisplayAdded(int displayId) {
|
||||||
Slog.v(TAG, "Display added displayId=" + displayId);
|
if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
|
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisplayRemoved(int displayId) {
|
public void onDisplayRemoved(int displayId) {
|
||||||
Slog.v(TAG, "Display removed displayId=" + displayId);
|
if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
|
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisplayChanged(int displayId) {
|
public void onDisplayChanged(int displayId) {
|
||||||
Slog.v(TAG, "Display changed displayId=" + displayId);
|
if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
|
mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,19 @@
|
|||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LinearLayout android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button android:id="@+id/airplane"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/launchAirplane"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<string name="tree">Tree</string>
|
<string name="tree">Tree</string>
|
||||||
<string name="text">Text</string>
|
<string name="text">Text</string>
|
||||||
<string name="asyncStructure">(Async structure goes here)</string>
|
<string name="asyncStructure">(Async structure goes here)</string>
|
||||||
|
<string name="launchAirplane">Launch airplane mode</string>
|
||||||
<string name="confirm">Confirm</string>
|
<string name="confirm">Confirm</string>
|
||||||
<string name="abort">Abort</string>
|
<string name="abort">Abort</string>
|
||||||
<string name="complete">Complete</string>
|
<string name="complete">Complete</string>
|
||||||
|
@ -21,6 +21,7 @@ import android.app.VoiceInteractor;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.service.voice.VoiceInteractionService;
|
import android.service.voice.VoiceInteractionService;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -39,6 +40,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
|||||||
VoiceInteractor mInteractor;
|
VoiceInteractor mInteractor;
|
||||||
VoiceInteractor.Request mCurrentRequest = null;
|
VoiceInteractor.Request mCurrentRequest = null;
|
||||||
TextView mLog;
|
TextView mLog;
|
||||||
|
Button mAirplaneButton;
|
||||||
Button mAbortButton;
|
Button mAbortButton;
|
||||||
Button mCompleteButton;
|
Button mCompleteButton;
|
||||||
Button mCommandButton;
|
Button mCommandButton;
|
||||||
@ -65,6 +67,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
|||||||
|
|
||||||
setContentView(R.layout.test_interaction);
|
setContentView(R.layout.test_interaction);
|
||||||
mLog = (TextView)findViewById(R.id.log);
|
mLog = (TextView)findViewById(R.id.log);
|
||||||
|
mAirplaneButton = (Button)findViewById(R.id.airplane);
|
||||||
|
mAirplaneButton.setOnClickListener(this);
|
||||||
mAbortButton = (Button)findViewById(R.id.abort);
|
mAbortButton = (Button)findViewById(R.id.abort);
|
||||||
mAbortButton.setOnClickListener(this);
|
mAbortButton.setOnClickListener(this);
|
||||||
mCompleteButton = (Button)findViewById(R.id.complete);
|
mCompleteButton = (Button)findViewById(R.id.complete);
|
||||||
@ -122,7 +126,12 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (v == mAbortButton) {
|
if (v == mAirplaneButton) {
|
||||||
|
Intent intent = new Intent(Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE);
|
||||||
|
intent.addCategory(Intent.CATEGORY_VOICE);
|
||||||
|
intent.putExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED, true);
|
||||||
|
startActivity(intent);
|
||||||
|
} else if (v == mAbortButton) {
|
||||||
VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice();
|
VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice();
|
||||||
mInteractor.submitRequest(req, REQUEST_ABORT);
|
mInteractor.submitRequest(req, REQUEST_ABORT);
|
||||||
} else if (v == mCompleteButton) {
|
} else if (v == mCompleteButton) {
|
||||||
|
Reference in New Issue
Block a user