diff options
6 files changed, 41 insertions, 12 deletions
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index af55788e617f..6b30ec4d536f 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -19,24 +19,25 @@ package android.app; import static android.content.Context.DISPLAY_SERVICE; import static android.content.Context.WINDOW_SERVICE; import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; +import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager.DisplayListener; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.os.Handler; -import android.os.Message; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; /** * Base class for presentations. @@ -115,7 +116,9 @@ import android.util.TypedValue; * The display manager keeps track of all displays in the system. However, not all * displays are appropriate for showing presentations. For example, if an activity * attempted to show a presentation on the main display it might obscure its own content - * (it's like opening a dialog on top of your activity). + * (it's like opening a dialog on top of your activity). Creating a presentation on the main + * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown + * when invoking {@link #show()}. * </p><p> * Here's how to identify suitable displays for showing presentations using * {@link DisplayManager#getDisplays(String)} and the @@ -188,12 +191,16 @@ public class Presentation extends Dialog { mDisplay = display; mDisplayManager = (DisplayManager)getContext().getSystemService(DISPLAY_SERVICE); + final int windowType = + (display.getFlags() & Display.FLAG_PRIVATE) != 0 ? TYPE_PRIVATE_PRESENTATION + : TYPE_PRESENTATION; + final Window w = getWindow(); final WindowManager.LayoutParams attr = w.getAttributes(); attr.token = mToken; w.setAttributes(attr); w.setGravity(Gravity.FILL); - w.setType(TYPE_PRESENTATION); + w.setType(windowType); setCanceledOnTouchOutside(false); } @@ -242,7 +249,7 @@ public class Presentation extends Dialog { /** * Inherited from {@link Dialog#show}. Will throw * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary - * {@link Display} can't be found. + * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set. */ @Override public void show() { diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 0e782d752815..b362c7a311d2 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -1144,6 +1144,7 @@ public abstract class DocumentsProvider extends ContentProvider { out.putParcelable(DocumentsContract.EXTRA_RESULT, path); } else if (METHOD_GET_DOCUMENT_METADATA.equals(method)) { + enforceReadPermissionInner(documentUri, getCallingPackage(), null); return getDocumentMetadata(documentId); } else { throw new UnsupportedOperationException("Method not supported " + method); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index e9c0f5d8afb1..74af6185aefc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -596,7 +596,8 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, String message = mContext.getString(R.string.instant_apps_message); PendingIntent appInfoAction = PendingIntent.getActivity(mContext, 0, new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - .setData(Uri.fromParts("package", pkg, null)), 0); + .setData(Uri.fromParts("package", pkg, null)), + PendingIntent.FLAG_IMMUTABLE); Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info), appInfoAction).build(); @@ -610,7 +611,7 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, - 0 /* requestCode */, browserIntent, 0 /* flags */); + 0 /* requestCode */, browserIntent, PendingIntent.FLAG_IMMUTABLE); ComponentName aiaComponent = null; try { aiaComponent = AppGlobals.getPackageManager().getInstantAppInstallerComponent(); @@ -628,7 +629,8 @@ public class PhoneStatusBarPolicy implements Callback, Callbacks, .putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, pendingIntent) .putExtra(Intent.EXTRA_INSTANT_APP_FAILURE, pendingIntent); - PendingIntent webPendingIntent = PendingIntent.getActivity(mContext, 0, goToWebIntent, 0); + PendingIntent webPendingIntent = PendingIntent.getActivity( + mContext, 0, goToWebIntent, PendingIntent.FLAG_IMMUTABLE); Action webAction = new Notification.Action.Builder(null, mContext.getString(R.string.go_to_web), webPendingIntent).build(); builder.addAction(webAction); diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index d73606f3003f..51b7279c97e8 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -161,6 +161,7 @@ public class AppTransition implements Dump { private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420; private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336; private static final long APP_TRANSITION_TIMEOUT_MS = 5000; + static final int MAX_APP_TRANSITION_DURATION = 3 * 1000; // 3 secs. private final Context mContext; private final WindowManagerService mService; diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index bd5d35eae77d..6cf1e98881f4 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -38,6 +38,7 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_A import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static android.view.WindowManager.TRANSIT_UNSET; +import static com.android.server.wm.AppTransition.MAX_APP_TRANSITION_DURATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; @@ -1843,7 +1844,16 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets, surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId); if (a != null) { - if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this); + if (a != null) { + // Setup the maximum app transition duration to prevent malicious app may set a long + // animation duration or infinite repeat counts for the app transition through + // ActivityOption#makeCustomAnimation or WindowManager#overridePendingTransition. + a.restrictDuration(MAX_APP_TRANSITION_DURATION); + } + if (DEBUG_ANIM) { + logWithStack(TAG, "Loaded animation " + a + " for " + this + + ", duration: " + ((a != null) ? a.getDuration() : 0)); + } final int containingWidth = frame.width(); final int containingHeight = frame.height(); a.initialize(containingWidth, containingHeight, width, height); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8b4a2dd36e6c..b438d044d102 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -55,6 +55,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; @@ -1182,6 +1183,13 @@ public class WindowManagerService extends IWindowManager.Stub return WindowManagerGlobal.ADD_PERMISSION_DENIED; } + if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) { + Slog.w(TAG_WM, + "Attempted to add presentation window to a non-suitable display. " + + "Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + AppWindowToken atoken = null; final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token |