Loading services/core/java/com/android/server/wm/ActivityClientController.java +30 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import android.view.RemoteAnimationDefinition; import android.window.SizeConfigurationBuckets; import android.window.TransitionInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.protolog.common.ProtoLog; Loading @@ -108,6 +109,9 @@ import com.android.server.pm.KnownPackages; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.uri.GrantUri; import com.android.server.uri.NeededUriGrants; import com.android.server.utils.quota.Categorizer; import com.android.server.utils.quota.Category; import com.android.server.utils.quota.CountQuotaTracker; import com.android.server.vr.VrManagerInternal; /** Loading @@ -123,6 +127,13 @@ class ActivityClientController extends IActivityClientController.Stub { private final ActivityTaskSupervisor mTaskSupervisor; private final Context mContext; // Prevent malicious app abusing the Activity#setPictureInPictureParams API @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker; // Limit to 60 times / minute private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60; // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000; /** Wrapper around VoiceInteractionServiceManager. */ private AssistUtils mAssistUtils; Loading Loading @@ -1035,6 +1046,25 @@ class ActivityClientController extends IActivityClientController.Stub { + ": Current activity does not support picture-in-picture."); } // Rate limit how frequent an app can request aspect ratio change via // Activity#setPictureInPictureParams final int userId = UserHandle.getCallingUserId(); if (mSetPipAspectRatioQuotaTracker == null) { mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext, Categorizer.SINGLE_CATEGORIZER); mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY, SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS); } if (r.pictureInPictureArgs.hasSetAspectRatio() && params.hasSetAspectRatio() && !r.pictureInPictureArgs.getAspectRatio().equals( params.getAspectRatio()) && !mSetPipAspectRatioQuotaTracker.noteEvent( userId, r.packageName, "setPipAspectRatio")) { throw new IllegalStateException(caller + ": Too many PiP aspect ratio change requests from " + r.packageName); } final float minAspectRatio = mContext.getResources().getFloat( com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); final float maxAspectRatio = mContext.getResources().getFloat( Loading services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +6 −0 Original line number Diff line number Diff line Loading @@ -1235,6 +1235,12 @@ public class WindowOrganizerTests extends WindowTestsBase { assertNotNull(o.mInfo); assertNotNull(o.mInfo.pictureInPictureParams); // Bypass the quota check, which causes NPE in current test setup. if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) { mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker .setEnabled(false); } final PictureInPictureParams p2 = new PictureInPictureParams.Builder() .setAspectRatio(new Rational(3, 4)).build(); mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2); Loading Loading
services/core/java/com/android/server/wm/ActivityClientController.java +30 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ import android.view.RemoteAnimationDefinition; import android.window.SizeConfigurationBuckets; import android.window.TransitionInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.protolog.common.ProtoLog; Loading @@ -108,6 +109,9 @@ import com.android.server.pm.KnownPackages; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.uri.GrantUri; import com.android.server.uri.NeededUriGrants; import com.android.server.utils.quota.Categorizer; import com.android.server.utils.quota.Category; import com.android.server.utils.quota.CountQuotaTracker; import com.android.server.vr.VrManagerInternal; /** Loading @@ -123,6 +127,13 @@ class ActivityClientController extends IActivityClientController.Stub { private final ActivityTaskSupervisor mTaskSupervisor; private final Context mContext; // Prevent malicious app abusing the Activity#setPictureInPictureParams API @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker; // Limit to 60 times / minute private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60; // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000; /** Wrapper around VoiceInteractionServiceManager. */ private AssistUtils mAssistUtils; Loading Loading @@ -1035,6 +1046,25 @@ class ActivityClientController extends IActivityClientController.Stub { + ": Current activity does not support picture-in-picture."); } // Rate limit how frequent an app can request aspect ratio change via // Activity#setPictureInPictureParams final int userId = UserHandle.getCallingUserId(); if (mSetPipAspectRatioQuotaTracker == null) { mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext, Categorizer.SINGLE_CATEGORIZER); mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY, SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS); } if (r.pictureInPictureArgs.hasSetAspectRatio() && params.hasSetAspectRatio() && !r.pictureInPictureArgs.getAspectRatio().equals( params.getAspectRatio()) && !mSetPipAspectRatioQuotaTracker.noteEvent( userId, r.packageName, "setPipAspectRatio")) { throw new IllegalStateException(caller + ": Too many PiP aspect ratio change requests from " + r.packageName); } final float minAspectRatio = mContext.getResources().getFloat( com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); final float maxAspectRatio = mContext.getResources().getFloat( Loading
services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +6 −0 Original line number Diff line number Diff line Loading @@ -1235,6 +1235,12 @@ public class WindowOrganizerTests extends WindowTestsBase { assertNotNull(o.mInfo); assertNotNull(o.mInfo.pictureInPictureParams); // Bypass the quota check, which causes NPE in current test setup. if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) { mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker .setEnabled(false); } final PictureInPictureParams p2 = new PictureInPictureParams.Builder() .setAspectRatio(new Rational(3, 4)).build(); mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2); Loading