Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3812,6 +3812,7 @@ package android.app { method public void onPerformDirectAction(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>); method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration); method @Deprecated public void onPictureInPictureModeChanged(boolean); method public void onPictureInPictureRequested(); method @CallSuper protected void onPostCreate(@Nullable android.os.Bundle); method public void onPostCreate(@Nullable android.os.Bundle, @Nullable android.os.PersistableBundle); method @CallSuper protected void onPostResume(); Loading Loading @@ -5102,6 +5103,7 @@ package android.app { method public void callActivityOnDestroy(android.app.Activity); method public void callActivityOnNewIntent(android.app.Activity, android.content.Intent); method public void callActivityOnPause(android.app.Activity); method public void callActivityOnPictureInPictureRequested(@NonNull android.app.Activity); method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle); method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle, @Nullable android.os.PersistableBundle); method public void callActivityOnRestart(android.app.Activity); api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ package android.app { method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedStack(int, android.graphics.Rect); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeDockedStack(android.graphics.Rect, android.graphics.Rect); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizePinnedStack(int, android.graphics.Rect, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeTask(int, android.graphics.Rect); Loading core/java/android/app/Activity.java +11 −0 Original line number Diff line number Diff line Loading @@ -2837,6 +2837,17 @@ public class Activity extends ContextThemeWrapper return getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE); } /** * Called by the system when picture in picture mode should be entered if supported. */ public void onPictureInPictureRequested() { // Previous recommendation was for apps to enter picture-in-picture in onUserLeaveHint() // which is sent after onPause(). This new method allows the system to request the app to // go into picture-in-picture decoupling it from life cycle events. For backwards // compatibility we schedule the life cycle events if the app didn't override this method. mMainThread.schedulePauseAndReturnToCurrentState(mToken); } void dispatchMovedToDisplay(int displayId, Configuration config) { updateDisplay(displayId); onMovedToDisplay(displayId, config); Loading core/java/android/app/ActivityTaskManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; Loading Loading @@ -433,4 +434,18 @@ public class ActivityTaskManager { throw e.rethrowFromSystemServer(); } } /** * Requests that an activity should enter picture-in-picture mode if possible. * @hide */ @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull IBinder token) { try { getService().requestPictureInPictureMode(token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } core/java/android/app/ActivityThread.java +67 −0 Original line number Diff line number Diff line Loading @@ -41,8 +41,10 @@ import android.app.servertransaction.ActivityRelaunchItem; import android.app.servertransaction.ActivityResultItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.PendingTransactionActions.StopInfo; import android.app.servertransaction.ResumeActivityItem; import android.app.servertransaction.TransactionExecutor; import android.app.servertransaction.TransactionExecutorHelper; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -522,6 +524,8 @@ public final class ActivityThread extends ClientTransactionHandler { boolean startsNotResumed; public final boolean isForward; int pendingConfigChanges; // Whether we are in the process of performing on user leaving. boolean mIsUserLeaving; Window mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; Loading Loading @@ -3763,6 +3767,66 @@ public final class ActivityThread extends ClientTransactionHandler { } } @Override public void handlePictureInPictureRequested(IBinder token) { final ActivityClientRecord r = mActivities.get(token); if (r == null) { Log.w(TAG, "Activity to request PIP to no longer exists"); return; } r.activity.onPictureInPictureRequested(); } /** * Cycle activity through onPause and onUserLeaveHint so that PIP is entered if supported, then * return to its previous state. This allows activities that rely on onUserLeaveHint instead of * onPictureInPictureRequested to enter picture-in-picture. */ public void schedulePauseAndReturnToCurrentState(IBinder token) { final ActivityClientRecord r = mActivities.get(token); if (r == null) { Log.w(TAG, "Activity to request pause with user leaving hint to no longer exists"); return; } if (r.mIsUserLeaving) { // The activity is about to perform user leaving, so there's no need to cycle ourselves. return; } final int prevState = r.getLifecycleState(); if (prevState != ON_RESUME && prevState != ON_PAUSE) { return; } switch (prevState) { case ON_RESUME: // Schedule a PAUSE then return to RESUME. schedulePauseWithUserLeavingHint(r); scheduleResume(r); break; case ON_PAUSE: // Schedule a RESUME then return to PAUSE. scheduleResume(r); schedulePauseWithUserLeavingHint(r); break; } } private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) { final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.activity.isFinishing(), /* userLeaving */ true, r.activity.mConfigChangeFlags, /* dontReport */ false)); executeTransaction(transaction); } private void scheduleResume(ActivityClientRecord r) { final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false)); executeTransaction(transaction); } private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { final ActivityClientRecord r = mActivities.get(token); if (r != null) { Loading Loading @@ -4483,6 +4547,7 @@ public final class ActivityThread extends ClientTransactionHandler { if (r != null) { if (userLeaving) { performUserLeavingActivity(r); r.mIsUserLeaving = false; } r.activity.mConfigChangeFlags |= configChanges; Loading @@ -4497,6 +4562,8 @@ public final class ActivityThread extends ClientTransactionHandler { } final void performUserLeavingActivity(ActivityClientRecord r) { r.mIsUserLeaving = true; mInstrumentation.callActivityOnPictureInPictureRequested(r.activity); mInstrumentation.callActivityOnUserLeaving(r.activity); } Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -3812,6 +3812,7 @@ package android.app { method public void onPerformDirectAction(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.os.Bundle>); method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration); method @Deprecated public void onPictureInPictureModeChanged(boolean); method public void onPictureInPictureRequested(); method @CallSuper protected void onPostCreate(@Nullable android.os.Bundle); method public void onPostCreate(@Nullable android.os.Bundle, @Nullable android.os.PersistableBundle); method @CallSuper protected void onPostResume(); Loading Loading @@ -5102,6 +5103,7 @@ package android.app { method public void callActivityOnDestroy(android.app.Activity); method public void callActivityOnNewIntent(android.app.Activity, android.content.Intent); method public void callActivityOnPause(android.app.Activity); method public void callActivityOnPictureInPictureRequested(@NonNull android.app.Activity); method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle); method public void callActivityOnPostCreate(@NonNull android.app.Activity, @Nullable android.os.Bundle, @Nullable android.os.PersistableBundle); method public void callActivityOnRestart(android.app.Activity);
api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ package android.app { method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedStack(int, android.graphics.Rect); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull android.os.IBinder); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeDockedStack(android.graphics.Rect, android.graphics.Rect); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizePinnedStack(int, android.graphics.Rect, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void resizeTask(int, android.graphics.Rect); Loading
core/java/android/app/Activity.java +11 −0 Original line number Diff line number Diff line Loading @@ -2837,6 +2837,17 @@ public class Activity extends ContextThemeWrapper return getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE); } /** * Called by the system when picture in picture mode should be entered if supported. */ public void onPictureInPictureRequested() { // Previous recommendation was for apps to enter picture-in-picture in onUserLeaveHint() // which is sent after onPause(). This new method allows the system to request the app to // go into picture-in-picture decoupling it from life cycle events. For backwards // compatibility we schedule the life cycle events if the app didn't override this method. mMainThread.schedulePauseAndReturnToCurrentState(mToken); } void dispatchMovedToDisplay(int displayId, Configuration config) { updateDisplay(displayId); onMovedToDisplay(displayId, config); Loading
core/java/android/app/ActivityTaskManager.java +15 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.app; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; Loading Loading @@ -433,4 +434,18 @@ public class ActivityTaskManager { throw e.rethrowFromSystemServer(); } } /** * Requests that an activity should enter picture-in-picture mode if possible. * @hide */ @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void requestPictureInPictureMode(@NonNull IBinder token) { try { getService().requestPictureInPictureMode(token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }
core/java/android/app/ActivityThread.java +67 −0 Original line number Diff line number Diff line Loading @@ -41,8 +41,10 @@ import android.app.servertransaction.ActivityRelaunchItem; import android.app.servertransaction.ActivityResultItem; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.PendingTransactionActions; import android.app.servertransaction.PendingTransactionActions.StopInfo; import android.app.servertransaction.ResumeActivityItem; import android.app.servertransaction.TransactionExecutor; import android.app.servertransaction.TransactionExecutorHelper; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -522,6 +524,8 @@ public final class ActivityThread extends ClientTransactionHandler { boolean startsNotResumed; public final boolean isForward; int pendingConfigChanges; // Whether we are in the process of performing on user leaving. boolean mIsUserLeaving; Window mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; Loading Loading @@ -3763,6 +3767,66 @@ public final class ActivityThread extends ClientTransactionHandler { } } @Override public void handlePictureInPictureRequested(IBinder token) { final ActivityClientRecord r = mActivities.get(token); if (r == null) { Log.w(TAG, "Activity to request PIP to no longer exists"); return; } r.activity.onPictureInPictureRequested(); } /** * Cycle activity through onPause and onUserLeaveHint so that PIP is entered if supported, then * return to its previous state. This allows activities that rely on onUserLeaveHint instead of * onPictureInPictureRequested to enter picture-in-picture. */ public void schedulePauseAndReturnToCurrentState(IBinder token) { final ActivityClientRecord r = mActivities.get(token); if (r == null) { Log.w(TAG, "Activity to request pause with user leaving hint to no longer exists"); return; } if (r.mIsUserLeaving) { // The activity is about to perform user leaving, so there's no need to cycle ourselves. return; } final int prevState = r.getLifecycleState(); if (prevState != ON_RESUME && prevState != ON_PAUSE) { return; } switch (prevState) { case ON_RESUME: // Schedule a PAUSE then return to RESUME. schedulePauseWithUserLeavingHint(r); scheduleResume(r); break; case ON_PAUSE: // Schedule a RESUME then return to PAUSE. scheduleResume(r); schedulePauseWithUserLeavingHint(r); break; } } private void schedulePauseWithUserLeavingHint(ActivityClientRecord r) { final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); transaction.setLifecycleStateRequest(PauseActivityItem.obtain(r.activity.isFinishing(), /* userLeaving */ true, r.activity.mConfigChangeFlags, /* dontReport */ false)); executeTransaction(transaction); } private void scheduleResume(ActivityClientRecord r) { final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token); transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false)); executeTransaction(transaction); } private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) { final ActivityClientRecord r = mActivities.get(token); if (r != null) { Loading Loading @@ -4483,6 +4547,7 @@ public final class ActivityThread extends ClientTransactionHandler { if (r != null) { if (userLeaving) { performUserLeavingActivity(r); r.mIsUserLeaving = false; } r.activity.mConfigChangeFlags |= configChanges; Loading @@ -4497,6 +4562,8 @@ public final class ActivityThread extends ClientTransactionHandler { } final void performUserLeavingActivity(ActivityClientRecord r) { r.mIsUserLeaving = true; mInstrumentation.callActivityOnPictureInPictureRequested(r.activity); mInstrumentation.callActivityOnUserLeaving(r.activity); } Loading