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

Commit 7cda0f09 authored by Jaewan Kim's avatar Jaewan Kim
Browse files

MediaSession2: Avoid binding from system service if able

MediaController2 had bounded to session service whenever it's created.
It was to increase binding counter for a session service to keep it
running while any controller exists, but it doesn't make sense for the
system service which creates controllers only to monitor changes in a
session.

Avoid binding from system service if able.

Bug: 73872399
Test: Run all MediaComponents tests
Change-Id: I16c81d67771e3716b646c8a48df5411bb4cf0527
parent 006b7eeb
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -39,8 +39,10 @@ import android.media.update.MediaController2Provider;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
import android.support.annotation.GuardedBy;
import android.util.Log;

@@ -125,6 +127,24 @@ public class MediaController2Impl implements MediaController2Provider {
            connectToSession(SessionToken2Impl.from(mToken).getSessionBinder());
        } else {
            // Session service
            if (Process.myUid() == Process.SYSTEM_UID) {
                // It's system server (MediaSessionService) that wants to monitor session.
                // Don't bind if able..
                IMediaSession2 binder = SessionToken2Impl.from(mToken).getSessionBinder();
                if (binder != null) {
                    // Use binder in the session token instead of bind by its own.
                    // Otherwise server will holds the binding to the service *forever* and service
                    // will never stop.
                    mServiceConnection = null;
                    connectToSession(SessionToken2Impl.from(mToken).getSessionBinder());
                    return;
                } else if (DEBUG) {
                    // Should happen only when system server wants to dispatch media key events to
                    // a dead service.
                    Log.d(TAG, "System server binds to a session service. Should unbind"
                            + " immediately after the use.");
                }
            }
            mServiceConnection = new SessionServiceConnection();
            connectToService();
        }
@@ -150,8 +170,15 @@ public class MediaController2Impl implements MediaController2Provider {
        //    If a service wants to keep running, it should be either foreground service or
        //    bounded service. But there had been request for the feature for system apps
        //    and using bindService() will be better fit with it.
        // TODO(jaewan): Use bindServiceAsUser()??
        boolean result = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        boolean result;
        if (Process.myUid() == Process.SYSTEM_UID) {
            // Use bindServiceAsUser() for binding from system service to avoid following warning.
            // ContextImpl: Calling a method in the system process without a qualified user
            result = mContext.bindServiceAsUser(intent, mServiceConnection, Context.BIND_AUTO_CREATE,
                    UserHandle.getUserHandleForUid(mToken.getUid()));
        } else {
            result = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        }
        if (!result) {
            Log.w(TAG, "bind to " + mToken + " failed");
        } else if (DEBUG) {
+2 −2
Original line number Diff line number Diff line
@@ -148,10 +148,10 @@ public class MediaSession2Impl implements MediaSession2Provider {
                    + " session services define the same id=" + id);
        } else if (libraryService != null) {
            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_LIBRARY_SERVICE,
                    mContext.getPackageName(), libraryService, id, null).getInstance();
                    mContext.getPackageName(), libraryService, id, mSessionStub).getInstance();
        } else if (sessionService != null) {
            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION_SERVICE,
                    mContext.getPackageName(), sessionService, id, null).getInstance();
                    mContext.getPackageName(), sessionService, id, mSessionStub).getInstance();
        } else {
            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION,
                    mContext.getPackageName(), null, id, mSessionStub).getInstance();
+0 −2
Original line number Diff line number Diff line
@@ -727,13 +727,11 @@ public class MediaController2Test extends MediaSession2TestBase {
        testControllerAfterSessionIsGone(id);
    }

    @Ignore
    @Test
    public void testClose_sessionService() throws InterruptedException {
        testCloseFromService(MockMediaSessionService2.ID);
    }

    @Ignore
    @Test
    public void testClose_libraryService() throws InterruptedException {
        testCloseFromService(MockMediaLibraryService2.ID);