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 isTaskRoot();
|
||||
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 boolean moveTaskToBack(boolean);
|
||||
method public boolean navigateUpTo(android.content.Intent);
|
||||
|
@ -3444,6 +3444,7 @@ package android.app {
|
||||
method public boolean isImmersive();
|
||||
method public boolean isTaskRoot();
|
||||
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 boolean moveTaskToBack(boolean);
|
||||
method public boolean navigateUpTo(android.content.Intent);
|
||||
|
@ -1228,6 +1228,22 @@ public class Activity extends ContextThemeWrapper
|
||||
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
|
||||
* interact with this activity.
|
||||
|
@ -2582,6 +2582,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
reply.writeInt(res ? 1 : 0);
|
||||
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);
|
||||
@ -5962,5 +5971,19 @@ class ActivityManagerProxy implements IActivityManager
|
||||
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;
|
||||
}
|
||||
|
@ -515,6 +515,8 @@ public interface IActivityManager extends IInterface {
|
||||
public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
|
||||
throws RemoteException;
|
||||
|
||||
public boolean isRootVoiceInteraction(IBinder token) throws RemoteException;
|
||||
|
||||
/*
|
||||
* Private non-Binder interfaces
|
||||
*/
|
||||
@ -861,4 +863,5 @@ public interface IActivityManager extends IInterface {
|
||||
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;
|
||||
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
|
||||
public IIntentSender getIntentSender(int type,
|
||||
String packageName, IBinder token, String resultWho,
|
||||
|
@ -107,6 +107,7 @@ final class ActivityRecord {
|
||||
boolean fullscreen; // covers the full screen?
|
||||
final boolean noDisplay; // activity is not displayed?
|
||||
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 HOME_ACTIVITY_TYPE = 1;
|
||||
@ -207,6 +208,9 @@ final class ActivityRecord {
|
||||
pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
|
||||
pw.print(" componentSpecified="); pw.print(componentSpecified);
|
||||
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(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
|
||||
pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
|
||||
@ -432,7 +436,8 @@ final class ActivityRecord {
|
||||
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
|
||||
ActivityInfo aInfo, Configuration _configuration,
|
||||
ActivityRecord _resultTo, String _resultWho, int _reqCode,
|
||||
boolean _componentSpecified, ActivityStackSupervisor supervisor,
|
||||
boolean _componentSpecified, boolean _rootVoiceInteraction,
|
||||
ActivityStackSupervisor supervisor,
|
||||
ActivityContainer container, Bundle options) {
|
||||
service = _service;
|
||||
appToken = new Token(this, service);
|
||||
@ -444,6 +449,7 @@ final class ActivityRecord {
|
||||
shortComponentName = _intent.getComponent().flattenToShortString();
|
||||
resolvedType = _resolvedType;
|
||||
componentSpecified = _componentSpecified;
|
||||
rootVoiceInteraction = _rootVoiceInteraction;
|
||||
configuration = _configuration;
|
||||
stackConfigOverride = (container != null)
|
||||
? container.mStack.mOverrideConfig : Configuration.EMPTY;
|
||||
@ -1257,7 +1263,7 @@ final class ActivityRecord {
|
||||
}
|
||||
final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid,
|
||||
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.taskDescription = taskDescription;
|
||||
|
@ -1506,6 +1506,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
|
||||
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
|
||||
try {
|
||||
intent.addCategory(Intent.CATEGORY_VOICE);
|
||||
if (!AppGlobals.getPackageManager().activitySupportsIntent(
|
||||
intent.getComponent(), intent, resolvedType)) {
|
||||
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
|
||||
@ -1626,7 +1627,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
|
||||
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
|
||||
requestCode, componentSpecified, this, container, options);
|
||||
requestCode, componentSpecified, voiceSession != null, this, container, options);
|
||||
if (outActivity != null) {
|
||||
outActivity[0] = r;
|
||||
}
|
||||
@ -3721,19 +3722,19 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,19 @@
|
||||
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"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
|
@ -21,6 +21,7 @@
|
||||
<string name="tree">Tree</string>
|
||||
<string name="text">Text</string>
|
||||
<string name="asyncStructure">(Async structure goes here)</string>
|
||||
<string name="launchAirplane">Launch airplane mode</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="abort">Abort</string>
|
||||
<string name="complete">Complete</string>
|
||||
|
@ -21,6 +21,7 @@ import android.app.VoiceInteractor;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@ -39,6 +40,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
||||
VoiceInteractor mInteractor;
|
||||
VoiceInteractor.Request mCurrentRequest = null;
|
||||
TextView mLog;
|
||||
Button mAirplaneButton;
|
||||
Button mAbortButton;
|
||||
Button mCompleteButton;
|
||||
Button mCommandButton;
|
||||
@ -65,6 +67,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
||||
|
||||
setContentView(R.layout.test_interaction);
|
||||
mLog = (TextView)findViewById(R.id.log);
|
||||
mAirplaneButton = (Button)findViewById(R.id.airplane);
|
||||
mAirplaneButton.setOnClickListener(this);
|
||||
mAbortButton = (Button)findViewById(R.id.abort);
|
||||
mAbortButton.setOnClickListener(this);
|
||||
mCompleteButton = (Button)findViewById(R.id.complete);
|
||||
@ -122,7 +126,12 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis
|
||||
|
||||
@Override
|
||||
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();
|
||||
mInteractor.submitRequest(req, REQUEST_ABORT);
|
||||
} else if (v == mCompleteButton) {
|
||||
|
Reference in New Issue
Block a user