Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b6c6697 authored by Jose Lima's avatar Jose Lima Committed by Jose Ricardo Lima
Browse files

Renamed "media playing" APIs to "visible behind"

   - Request from API Review: rename the media playing APIs to a more
     generic name, reflecting the background visibility feature these
     methods actually control.
   - Made the new isActivityVisibleBehind().
   - Changed convertFromTranslucent() and convertToTranslucent() to be
     SystemApi.

Bug: 16959028
Change-Id: I526eac22f44273b3254dd6201f89194d13e597e2
parent c12035cd
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -3438,7 +3438,6 @@ package android.app {
    method public void onAttachFragment(android.app.Fragment);
    method public void onAttachedToWindow();
    method public void onBackPressed();
    method public void onBackgroundMediaPlayingChanged(boolean);
    method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence);
    method public void onConfigurationChanged(android.content.res.Configuration);
    method public void onContentChanged();
@@ -3495,13 +3494,13 @@ package android.app {
    method public boolean onSearchRequested();
    method protected void onStart();
    method protected void onStop();
    method public void onStopMediaPlaying();
    method protected void onTitleChanged(java.lang.CharSequence, int);
    method public boolean onTouchEvent(android.view.MotionEvent);
    method public boolean onTrackballEvent(android.view.MotionEvent);
    method public void onTrimMemory(int);
    method public void onUserInteraction();
    method protected void onUserLeaveHint();
    method public void onVisibleBehindCancelled();
    method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
    method public void onWindowFocusChanged(boolean);
    method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
@@ -3513,6 +3512,7 @@ package android.app {
    method public void registerForContextMenu(android.view.View);
    method public final deprecated void removeDialog(int);
    method public void reportFullyDrawn();
    method public boolean requestVisibleBehind(boolean);
    method public final boolean requestWindowFeature(int);
    method public final void runOnUiThread(java.lang.Runnable);
    method public void setActionBar(android.widget.Toolbar);
@@ -3531,7 +3531,6 @@ package android.app {
    method public void setImmersive(boolean);
    method public void setIntent(android.content.Intent);
    method public final void setMediaController(android.media.session.MediaController);
    method public boolean setMediaPlaying(boolean);
    method public final void setProgress(int);
    method public final void setProgressBarIndeterminate(boolean);
    method public final void setProgressBarIndeterminateVisibility(boolean);
@@ -5238,8 +5237,8 @@ package android.app {
    field public static java.lang.String ACTION_EXIT_CAR_MODE;
    field public static java.lang.String ACTION_EXIT_DESK_MODE;
    field public static final int DISABLE_CAR_MODE_GO_HOME = 1; // 0x1
    field public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 1; // 0x1
    field public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 2; // 0x2
    field public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 1; // 0x1
    field public static final int MODE_NIGHT_AUTO = 0; // 0x0
    field public static final int MODE_NIGHT_NO = 1; // 0x1
    field public static final int MODE_NIGHT_YES = 2; // 0x2
+57 −52
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.internal.policy.PolicyManager;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
@@ -747,8 +748,8 @@ public class Activity extends ContextThemeWrapper
        }
    };

    // Most recent call to setMediaPlaying().
    boolean mMediaPlaying;
    // Most recent call to requestVisibleBehind().
    boolean mVisibleBehind;

    ArrayMap<String, LoaderManagerImpl> mAllLoaderManagers;
    LoaderManagerImpl mLoaderManager;
@@ -5314,6 +5315,7 @@ public class Activity extends ContextThemeWrapper
     *
     * @hide
     */
    @SystemApi
    public void convertFromTranslucent() {
        try {
            mTranslucentCallback = null;
@@ -5350,6 +5352,7 @@ public class Activity extends ContextThemeWrapper
     *
     * @hide
     */
    @SystemApi
    public boolean convertToTranslucent(TranslucentConversionListener callback,
            ActivityOptions options) {
        boolean drawComplete;
@@ -5406,12 +5409,13 @@ public class Activity extends ContextThemeWrapper
    }

    /**
     * Activities that want to show media behind a translucent activity above them must call this
     * method anytime before a return from {@link #onPause()}. If this call is successful
     * then the activity should continue to play media when {@link #onPause()} is called, but must
     * stop playing and release resources prior to or within the call to
     * {@link #onStopMediaPlaying()}. If this call returns false the activity must stop
     * playing and release resources immediately.
     * Activities that want to remain visible behind a translucent activity above them must call
     * this method anytime before a return from {@link #onPause()}. If this call is successful
     * then the activity will remain visible when {@link #onPause()} is called, and can continue to
     * play media in the background, but it must stop playing and release resources prior to or
     * within the call to {@link #onVisibleBehindCancelled()}. If this call returns false, the 
     * activity will not be visible in the background, and must release any media resources 
     * immediately.
     *
     * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop
     * for dialog and translucent activities.
@@ -5419,85 +5423,86 @@ public class Activity extends ContextThemeWrapper
     * <p>False will be returned any time this method is call between the return of onPause and
     *      the next call to onResume.
     *
     * @param playing true to notify the system that media is starting or continuing playing,
     *                false to indicate that media has stopped or is stopping. Resources must
     *                be released when passing false to this method.
     * @return the resulting play state. If true the activity may continue playing media beyond
     *      {@link #onPause()}, if false then the caller must stop playing and immediately
     *      release all media resources. Returning false may occur in lieu of a call to
     *      onReleaseMediaResources() so the return value must be checked.
     * @param visible true to notify the system that the activity wishes to be visible behind other
     *                translucent activities, false to indicate otherwise. Resources must be
     *                released when passing false to this method.
     * @return the resulting visibiity state. If true the activity may remain visible beyond
     *      {@link #onPause()}. If false then the activity may not count on being visible behind
     *      other translucent activities, and must stop any media playback and release resources.
     *      Returning false may occur in lieu of a call to onVisibleBehindCancelled() so the return
     *      value must be checked.
     *
     * @see #isBackgroundMediaPlaying()
     * @see #onStopMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     * @see #onVisibleBehindCancelled()
     * @see #onBackgroundVisibleBehindChanged(boolean)
     */
    public boolean setMediaPlaying(boolean playing) {
    public boolean requestVisibleBehind(boolean visible) {
        if (!mResumed) {
            // Do not permit paused or stopped activities to start playing.
            playing = false;
            // Do not permit paused or stopped activities to do this.
            visible = false;
        }
        try {
            mMediaPlaying = ActivityManagerNative.getDefault().setMediaPlaying(mToken, playing) &&
                    playing;
            mVisibleBehind = ActivityManagerNative.getDefault()
                    .requestVisibleBehind(mToken, visible) && visible;
        } catch (RemoteException e) {
            mMediaPlaying = false;
            mVisibleBehind = false;
        }
        return mMediaPlaying;
        return mVisibleBehind;
    }

    /**
     * Called when a translucent activity over playing media is becoming opaque or another
     * activity is being launched. Activities that call {@link #setMediaPlaying(boolean)}
     * must implement this method to at the minimum call
     * <code>super.onStopMediaPlayback()</code>.
     * Called when a translucent activity over this activity is becoming opaque or another
     * activity is being launched. Activities that override this method must call
     * <code>super.onVisibleBehindCancelled()</code> or a SuperNotCalledException will be thrown.
     *
     * <p>When this method is called the activity has 500 msec to release the media resources.
     * <p>When this method is called the activity has 500 msec to release any resources it may be
     * using while visible in the background.
     * If the activity has not returned from this method in 500 msec the system will destroy
     * the activity and kill the process in order to recover the media resources for another
     * the activity and kill the process in order to recover the resources for another
     * process. Otherwise {@link #onStop()} will be called following return.
     *
     * @see #setMediaPlaying(boolean)
     * @see #isBackgroundMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     * @see #requestVisibleBehind(boolean)
     * @see #onBackgroundVisibleBehindChanged(boolean)
     */
    public void onStopMediaPlaying() {
    public void onVisibleBehindCancelled() {
        mCalled = true;
    }

    /**
     * Translucent activities may call this to determine if there is an activity below it that
     * is playing media.
     * Translucent activities may call this to determine if there is an activity below them that
     * is currently set to be visible in the background.
     *
     * @return true if media is playing according to the most recent call to
     * {@link #setMediaPlaying(boolean)}, false otherwise.
     * @return true if an activity below is set to visible according to the most recent call to
     * {@link #requestVisibleBehind(boolean)}, false otherwise.
     *
     * @see #setMediaPlaying(boolean)
     * @see #onStopMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     * @see #requestVisibleBehind(boolean)
     * @see #onVisibleBehindCancelled()
     * @see #onBackgroundVisibleBehindChanged(boolean)
     * @hide
     */
    public boolean isBackgroundMediaPlaying() {
    @SystemApi
    public boolean isBackgroundVisibleBehind() {
        try {
            return ActivityManagerNative.getDefault().isBackgroundMediaPlaying(mToken);
            return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken);
        } catch (RemoteException e) {
        }
        return false;
    }

    /**
     * The topmost foreground activity will receive this call when an activity below it either
     * starts or stops playing media.
     * The topmost foreground activity will receive this call when the background visibility state
     * of the activity below it changes.
     *
     * This call may be a consequence of {@link #setMediaPlaying(boolean)} or might be
     * This call may be a consequence of {@link #requestVisibleBehind(boolean)} or might be
     * due to a background activity finishing itself.
     *
     * @param playing true if media playback is starting, false if it is stopping.
     * @param visible true if a background activity is visible, false otherwise.
     *
     * @see #setMediaPlaying(boolean)
     * @see #isBackgroundMediaPlaying()
     * @see #onStopMediaPlaying()
     * @see #requestVisibleBehind(boolean)
     * @see #onVisibleBehindCancelled()
     * @hide
     */
    public void onBackgroundMediaPlayingChanged(boolean playing) {
    @SystemApi
    public void onBackgroundVisibleBehindChanged(boolean visible) {
    }

    /**
+16 −15
Original line number Diff line number Diff line
@@ -2197,29 +2197,29 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case SET_MEDIA_PLAYING_TRANSACTION: {
        case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            boolean enable = data.readInt() > 0;
            boolean success = setMediaPlaying(token, enable);
            boolean success = requestVisibleBehind(token, enable);
            reply.writeNoException();
            reply.writeInt(success ? 1 : 0);
            return true;
        }

        case IS_BG_MEDIA_PLAYING_TRANSACTION: {
        case IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            final boolean enabled = isBackgroundMediaPlaying(token);
            final boolean enabled = isBackgroundVisibleBehind(token);
            reply.writeNoException();
            reply.writeInt(enabled ? 1 : 0);
            return true;
        }

        case MEDIA_RESOURCES_RELEASED_TRANSACTION: {
        case BACKGROUND_RESOURCES_RELEASED_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            mediaResourcesReleased(token);
            backgroundResourcesReleased(token);
            reply.writeNoException();
            return true;
        }
@@ -5101,13 +5101,13 @@ class ActivityManagerProxy implements IActivityManager
    }

    @Override
    public boolean setMediaPlaying(IBinder token, boolean playing) throws RemoteException {
    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(playing ? 1 : 0);
        mRemote.transact(SET_MEDIA_PLAYING_TRANSACTION, data, reply, 0);
        data.writeInt(visible ? 1 : 0);
        mRemote.transact(REQUEST_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
        reply.readException();
        boolean success = reply.readInt() > 0;
        data.recycle();
@@ -5116,26 +5116,27 @@ class ActivityManagerProxy implements IActivityManager
    }

    @Override
    public boolean isBackgroundMediaPlaying(IBinder token) throws RemoteException {
    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(IS_BG_MEDIA_PLAYING_TRANSACTION, data, reply, 0);
        mRemote.transact(IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
        reply.readException();
        final boolean playing = reply.readInt() > 0;
        final boolean visible = reply.readInt() > 0;
        data.recycle();
        reply.recycle();
        return playing;
        return visible;
    }

    @Override
    public void mediaResourcesReleased(IBinder token) throws RemoteException {
    public void backgroundResourcesReleased(IBinder token) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(MEDIA_RESOURCES_RELEASED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
        mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply,
                IBinder.FLAG_ONEWAY);
        reply.readException();
        data.recycle();
        reply.recycle();
+20 −20
Original line number Diff line number Diff line
@@ -1155,13 +1155,13 @@ public final class ActivityThread {
        }

        @Override
        public void scheduleStopMediaPlaying(IBinder token) {
            sendMessage(H.STOP_MEDIA_PLAYING, token);
        public void scheduleCancelVisibleBehind(IBinder token) {
            sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
        }

        @Override
        public void scheduleBackgroundMediaPlayingChanged(IBinder token, boolean playing) {
            sendMessage(H.BACKGROUND_MEDIA_PLAYING_CHANGED, token, playing ? 1 : 0);
        public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
            sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
        }

        public void scheduleEnterAnimationComplete(IBinder token) {
@@ -1217,8 +1217,8 @@ public final class ActivityThread {
        public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
        public static final int INSTALL_PROVIDER        = 145;
        public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
        public static final int STOP_MEDIA_PLAYING = 147;
        public static final int BACKGROUND_MEDIA_PLAYING_CHANGED = 148;
        public static final int CANCEL_VISIBLE_BEHIND = 147;
        public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
        public static final int ENTER_ANIMATION_COMPLETE = 149;

        String codeToString(int code) {
@@ -1270,8 +1270,8 @@ public final class ActivityThread {
                    case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
                    case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
                    case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
                    case STOP_MEDIA_PLAYING: return "STOP_MEDIA_PLAYING";
                    case BACKGROUND_MEDIA_PLAYING_CHANGED: return "BACKGROUND_MEDIA_PLAYING_CHANGED";
                    case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
                    case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
                    case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
                }
            }
@@ -1491,11 +1491,11 @@ public final class ActivityThread {
                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
                    onNewActivityOptions(pair.first, pair.second);
                    break;
                case STOP_MEDIA_PLAYING:
                    handleStopMediaPlaying((IBinder) msg.obj);
                case CANCEL_VISIBLE_BEHIND:
                    handleCancelVisibleBehind((IBinder) msg.obj);
                    break;
                case BACKGROUND_MEDIA_PLAYING_CHANGED:
                    handleOnBackgroundMediaPlayingChanged((IBinder) msg.obj, msg.arg1 > 0);
                case BACKGROUND_VISIBLE_BEHIND_CHANGED:
                    handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
                    break;
                case ENTER_ANIMATION_COMPLETE:
                    handleEnterAnimationComplete((IBinder) msg.obj);
@@ -2488,31 +2488,31 @@ public final class ActivityThread {
        }
    }

    public void handleStopMediaPlaying(IBinder token) {
    public void handleCancelVisibleBehind(IBinder token) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            final Activity activity = r.activity;
            if (activity.mMediaPlaying) {
            if (activity.mVisibleBehind) {
                activity.mCalled = false;
                activity.onStopMediaPlaying();
                activity.onVisibleBehindCancelled();
                // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
                if (!activity.mCalled) {
                    throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
                            " did not call through to super.onStopMediaPlayback()");
                            " did not call through to super.onVisibleBehindCancelled()");
                }
                activity.mMediaPlaying = false;
                activity.mVisibleBehind = false;
            }
        }
        try {
            ActivityManagerNative.getDefault().mediaResourcesReleased(token);
            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
        } catch (RemoteException e) {
        }
    }

    public void handleOnBackgroundMediaPlayingChanged(IBinder token, boolean playing) {
    public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            r.activity.onBackgroundMediaPlayingChanged(playing);
            r.activity.onBackgroundVisibleBehindChanged(visible);
        }
    }

+10 −8
Original line number Diff line number Diff line
@@ -648,21 +648,21 @@ public abstract class ApplicationThreadNative extends Binder
            return true;
        }

        case STOP_MEDIA_PLAYING_TRANSACTION:
        case CANCEL_VISIBLE_BEHIND_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            scheduleStopMediaPlaying(token);
            scheduleCancelVisibleBehind(token);
            reply.writeNoException();
            return true;
        }

        case BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION:
        case BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            boolean enabled = data.readInt() > 0;
            scheduleBackgroundMediaPlayingChanged(token, enabled);
            scheduleBackgroundVisibleBehindChanged(token, enabled);
            reply.writeNoException();
            return true;
        }
@@ -1334,21 +1334,23 @@ class ApplicationThreadProxy implements IApplicationThread {
    }

    @Override
    public void scheduleStopMediaPlaying(IBinder token) throws RemoteException {
    public void scheduleCancelVisibleBehind(IBinder token) throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(STOP_MEDIA_PLAYING_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
        mRemote.transact(CANCEL_VISIBLE_BEHIND_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
        data.recycle();
    }

    @Override
    public void scheduleBackgroundMediaPlayingChanged(IBinder token, boolean enabled) throws RemoteException {
    public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        data.writeInterfaceToken(IApplicationThread.descriptor);
        data.writeStrongBinder(token);
        data.writeInt(enabled ? 1 : 0);
        mRemote.transact(BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
        mRemote.transact(BACKGROUND_VISIBLE_BEHIND_CHANGED_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }

Loading