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:
Dianne Hackborn
2015-08-04 01:37:57 +00:00
committed by Android Git Automerger
11 changed files with 92 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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