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

Commit b0a11172 authored by Craig Mautner's avatar Craig Mautner Committed by Android (Google) Code Review
Browse files

Merge "Add Media Playing API"

parents 1670f0dd ee2e45ac
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3334,6 +3334,7 @@ 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();
@@ -3389,6 +3390,7 @@ 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);
@@ -3423,6 +3425,7 @@ package android.app {
    method public void setFinishOnTouchOutside(boolean);
    method public void setImmersive(boolean);
    method public void setIntent(android.content.Intent);
    method public boolean setMediaPlaying(boolean);
    method public final void setProgress(int);
    method public final void setProgressBarIndeterminate(boolean);
    method public final void setProgressBarIndeterminateVisibility(boolean);
+101 −2
Original line number Diff line number Diff line
@@ -744,6 +744,9 @@ public class Activity extends ContextThemeWrapper
        }
    };

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

    ArrayMap<String, LoaderManagerImpl> mAllLoaderManagers;
    LoaderManagerImpl mLoaderManager;

@@ -764,6 +767,7 @@ public class Activity extends ContextThemeWrapper
    // protected by synchronized (this) 
    int mResultCode = RESULT_CANCELED;
    Intent mResultData = null;

    private TranslucentConversionListener mTranslucentCallback;
    private boolean mChangeCanvasToTranslucent;

@@ -5323,6 +5327,101 @@ public class Activity extends ContextThemeWrapper
        return null;
    }

    /**
     * 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.
     *
     * <p>Only fullscreen opaque activities may make this call. I.e. this call is a nop
     * for dialog and translucent activities.
     *
     * <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.
     *
     * @see #isBackgroundMediaPlaying()
     * @see #onStopMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     */
    public boolean setMediaPlaying(boolean playing) {
        if (!mResumed) {
            // Do not permit paused or stopped activities to start playing.
            playing = false;
        }
        try {
            mMediaPlaying = ActivityManagerNative.getDefault().setMediaPlaying(mToken, playing) &&
                    playing;
        } catch (RemoteException e) {
            mMediaPlaying = false;
        }
        return mMediaPlaying;
    }

    /**
     * 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>.
     *
     * <p>When this method is called the activity has 500 msec to release the media resources.
     * 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
     * process. Otherwise {@link #onStop()} will be called following return.
     *
     * @see #setMediaPlaying(boolean)
     * @see #isBackgroundMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     */
    public void onStopMediaPlaying() {
        mCalled = true;
    }

    /**
     * Translucent activities may call this to determine if there is an activity below it that
     * is playing media.
     *
     * @return true if media is playing according to the most recent call to
     * {@link #setMediaPlaying(boolean)}, false otherwise.
     *
     * @see #setMediaPlaying(boolean)
     * @see #onStopMediaPlaying()
     * @see #onBackgroundMediaPlayingChanged(boolean)
     * @hide
     */
    public boolean isBackgroundMediaPlaying() {
        try {
            return ActivityManagerNative.getDefault().isBackgroundMediaPlaying(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.
     *
     * This call may be a consequence of {@link #setMediaPlaying(boolean)} or might be
     * due to a background activity finishing itself.
     *
     * @param playing true if media playback is starting, false if it is stopping.
     *
     * @see #setMediaPlaying(boolean)
     * @see #isBackgroundMediaPlaying()
     * @see #onStopMediaPlaying()
     */
    public void onBackgroundMediaPlayingChanged(boolean playing) {
    }

    /**
     * Adjust the current immersive mode setting.
     *
+68 −0
Original line number Diff line number Diff line
@@ -2176,6 +2176,33 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            reply.writeNoException();
            return true;
        }

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

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

        case MEDIA_RESOURCES_RELEASED: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            mediaResourcesReleased(token);
            reply.writeNoException();
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -5007,5 +5034,46 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    @Override
    public boolean setMediaPlaying(IBinder token, boolean playing) 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);
        reply.readException();
        boolean success = reply.readInt() > 0;
        data.recycle();
        reply.recycle();
        return success;
    }

    @Override
    public boolean isBackgroundMediaPlaying(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);
        reply.readException();
        final boolean playing = reply.readInt() > 0;
        data.recycle();
        reply.recycle();
        return playing;
    }

    @Override
    public void mediaResourcesReleased(IBinder token) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(token);
        mRemote.transact(MEDIA_RESOURCES_RELEASED, data, reply, IBinder.FLAG_ONEWAY);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

    private IBinder mRemote;
}
+47 −0
Original line number Diff line number Diff line
@@ -1153,6 +1153,16 @@ public final class ActivityThread {
        public final void updateTimePrefs(boolean is24Hour) {
            DateFormat.set24HourTimePref(is24Hour);
        }

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

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

    private class H extends Handler {
@@ -1203,6 +1213,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;

        String codeToString(int code) {
            if (DEBUG_MESSAGES) {
@@ -1253,6 +1265,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";
                }
            }
            return Integer.toString(code);
@@ -1470,6 +1484,11 @@ public final class ActivityThread {
                case ON_NEW_ACTIVITY_OPTIONS:
                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
                    onNewActivityOptions(pair.first, pair.second);
                case STOP_MEDIA_PLAYING:
                    handleStopMediaPlaying((IBinder) msg.obj);
                    break;
                case BACKGROUND_MEDIA_PLAYING_CHANGED:
                    handleOnBackgroundMediaPlayingChanged((IBinder) msg.obj, msg.arg1 > 0);
                    break;
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
@@ -2454,6 +2473,34 @@ public final class ActivityThread {
        }
    }

    public void handleStopMediaPlaying(IBinder token) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            final Activity activity = r.activity;
            if (activity.mMediaPlaying) {
                activity.mCalled = false;
                activity.onStopMediaPlaying();
                // 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()");
                }
                activity.mMediaPlaying = false;
            }
        }
        try {
            ActivityManagerNative.getDefault().mediaResourcesReleased(token);
        } catch (RemoteException e) {
        }
    }

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

    public void handleInstallProvider(ProviderInfo info) {
        installContentProviders(mInitialApplication, Lists.newArrayList(info));
    }
+38 −0
Original line number Diff line number Diff line
@@ -647,6 +647,25 @@ public abstract class ApplicationThreadNative extends Binder
            reply.writeNoException();
            return true;
        }

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

        case BACKGROUND_MEDIA_PLAYING_CHANGED_TRANSACTION:
        {
            data.enforceInterface(IApplicationThread.descriptor);
            IBinder token = data.readStrongBinder();
            boolean enabled = data.readInt() > 0;
            scheduleBackgroundMediaPlayingChanged(token, enabled);
            reply.writeNoException();
            return true;
        }
        }

        return super.onTransact(code, data, reply, flags);
@@ -1304,4 +1323,23 @@ class ApplicationThreadProxy implements IApplicationThread {
        mRemote.transact(UPDATE_TIME_PREFS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
        data.recycle();
    }

    @Override
    public void scheduleStopMediaPlaying(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);
        data.recycle();
    }

    @Override
    public void scheduleBackgroundMediaPlayingChanged(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);
        data.recycle();
    }
}
Loading