diff options
| -rw-r--r-- | core/java/android/app/ActivityView.java | 21 | ||||
| -rw-r--r-- | core/java/android/app/IActivityContainer.aidl | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityStackSupervisor.java | 34 |
3 files changed, 57 insertions, 0 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index edf21dde82e2..a810134f28f2 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -147,6 +147,7 @@ public class ActivityView extends ViewGroup { if (mSurface != null) { mActivityContainer.startActivity(intent); } else { + mActivityContainer.checkEmbeddedAllowed(intent); mQueuedIntent = intent; mQueuedPendingIntent = null; } @@ -162,6 +163,7 @@ public class ActivityView extends ViewGroup { if (mSurface != null) { mActivityContainer.startActivityIntentSender(iIntentSender); } else { + mActivityContainer.checkEmbeddedAllowedIntentSender(iIntentSender); mQueuedPendingIntent = iIntentSender; mQueuedIntent = null; } @@ -177,6 +179,7 @@ public class ActivityView extends ViewGroup { if (mSurface != null) { mActivityContainer.startActivityIntentSender(iIntentSender); } else { + mActivityContainer.checkEmbeddedAllowedIntentSender(iIntentSender); mQueuedPendingIntent = iIntentSender; mQueuedIntent = null; } @@ -326,6 +329,24 @@ public class ActivityView extends ViewGroup { } } + void checkEmbeddedAllowed(Intent intent) { + try { + mIActivityContainer.checkEmbeddedAllowed(intent); + } catch (RemoteException e) { + throw new RuntimeException( + "ActivityView: Unable to startActivity from Intent. " + e); + } + } + + void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { + try { + mIActivityContainer.checkEmbeddedAllowedIntentSender(intentSender); + } catch (RemoteException e) { + throw new RuntimeException( + "ActivityView: Unable to startActivity from IntentSender. " + e); + } + } + int getDisplayId() { try { return mIActivityContainer.getDisplayId(); diff --git a/core/java/android/app/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl index cc3b10cfa88f..52884f744b73 100644 --- a/core/java/android/app/IActivityContainer.aidl +++ b/core/java/android/app/IActivityContainer.aidl @@ -29,6 +29,8 @@ interface IActivityContainer { void setSurface(in Surface surface, int width, int height, int density); int startActivity(in Intent intent); int startActivityIntentSender(in IIntentSender intentSender); + void checkEmbeddedAllowed(in Intent intent); + void checkEmbeddedAllowedIntentSender(in IIntentSender intentSender); int getDisplayId(); boolean injectEvent(in InputEvent event); void release(); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 0b6f7d155d17..28b1df52db6b 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3057,6 +3057,40 @@ public final class ActivityStackSupervisor implements DisplayListener { null, 0, FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this); } + private void checkEmbeddedAllowedInner(Intent intent, String resolvedType) { + int userId = mService.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); + if (resolvedType == null) { + resolvedType = intent.getType(); + if (resolvedType == null && intent.getData() != null + && "content".equals(intent.getData().getScheme())) { + resolvedType = mService.getProviderMimeType(intent.getData(), userId); + } + } + ActivityInfo aInfo = resolveActivity(intent, resolvedType, 0, null, null, userId); + if ((aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) { + throw new SecurityException( + "Attempt to embed activity that has not set allowEmbedded=\"true\""); + } + } + + /** Throw a SecurityException if allowEmbedded is not true */ + @Override + public final void checkEmbeddedAllowed(Intent intent) { + checkEmbeddedAllowedInner(intent, null); + } + + /** Throw a SecurityException if allowEmbedded is not true */ + @Override + public final void checkEmbeddedAllowedIntentSender(IIntentSender intentSender) { + if (!(intentSender instanceof PendingIntentRecord)) { + throw new IllegalArgumentException("Bad PendingIntent object"); + } + PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender; + checkEmbeddedAllowedInner(pendingIntent.key.requestIntent, + pendingIntent.key.requestResolvedType); + } + @Override public IBinder asBinder() { return this; |