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

Commit dd27fede authored by Kyunglyul Hyun's avatar Kyunglyul Hyun Committed by Automerger Merge Worker
Browse files

Merge "Bind provider services when necessary" into sc-dev am: a00481f6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14774944

Change-Id: I36e9cd9b399be58c17daadd42394b5a6cd040254
parents b793470e a00481f6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -26,9 +26,9 @@ import android.os.Bundle;
 */
oneway interface IMediaRoute2ProviderServiceCallback {
    // TODO: Change it to updateRoutes?
    void updateState(in MediaRoute2ProviderInfo providerInfo);
    void notifyProviderUpdated(in MediaRoute2ProviderInfo providerInfo);
    void notifySessionCreated(long requestId, in RoutingSessionInfo sessionInfo);
    void notifySessionUpdated(in RoutingSessionInfo sessionInfo);
    void notifySessionsUpdated(in List<RoutingSessionInfo> sessionInfo);
    void notifySessionReleased(in RoutingSessionInfo sessionInfo);
    void notifyRequestFailed(long requestId, int reason);
}
+32 −10
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ public abstract class MediaRoute2ProviderService extends Service {
    private final Object mSessionLock = new Object();
    private final Object mRequestIdsLock = new Object();
    private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false);
    private final AtomicBoolean mSessionUpdateScheduled = new AtomicBoolean(false);
    private MediaRoute2ProviderServiceStub mStub;
    private IMediaRoute2ProviderServiceCallback mRemoteCallback;
    private volatile MediaRoute2ProviderInfo mProviderInfo;
@@ -287,16 +288,8 @@ public abstract class MediaRoute2ProviderService extends Service {
                Log.w(TAG, "notifySessionUpdated: Ignoring unknown session info.");
                return;
            }

            if (mRemoteCallback == null) {
                return;
            }
            try {
                mRemoteCallback.notifySessionUpdated(sessionInfo);
            } catch (RemoteException ex) {
                Log.w(TAG, "Failed to notify session info changed.");
            }
        }
        scheduleUpdateSessions();
    }

    /**
@@ -479,6 +472,7 @@ public abstract class MediaRoute2ProviderService extends Service {
    void setCallback(IMediaRoute2ProviderServiceCallback callback) {
        mRemoteCallback = callback;
        schedulePublishState();
        scheduleUpdateSessions();
    }

    void schedulePublishState() {
@@ -497,12 +491,40 @@ public abstract class MediaRoute2ProviderService extends Service {
        }

        try {
            mRemoteCallback.updateState(mProviderInfo);
            mRemoteCallback.notifyProviderUpdated(mProviderInfo);
        } catch (RemoteException ex) {
            Log.w(TAG, "Failed to publish provider state.", ex);
        }
    }

    void scheduleUpdateSessions() {
        if (mSessionUpdateScheduled.compareAndSet(false, true)) {
            mHandler.post(this::updateSessions);
        }
    }

    private void updateSessions() {
        if (!mSessionUpdateScheduled.compareAndSet(true, false)) {
            return;
        }

        if (mRemoteCallback == null) {
            return;
        }

        List<RoutingSessionInfo> sessions;
        synchronized (mSessionLock) {
            sessions = new ArrayList<>(mSessionInfo.values());
        }

        try {
            mRemoteCallback.notifySessionsUpdated(sessions);
        } catch (RemoteException ex) {
            Log.w(TAG, "Failed to notify session info changed.");
        }

    }

    /**
     * Adds a requestId in the request ID list whose max size is {@link #MAX_REQUEST_IDS_SIZE}.
     * When the max size is reached, the first element is removed (FIFO).
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ abstract class MediaRoute2Provider {
        mUniqueId = componentName.flattenToShortString();
    }

    public void setCallback(MediaRoute2ProviderServiceProxy.Callback callback) {
    public void setCallback(Callback callback) {
        mCallback = callback;
    }

+70 −38
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.server.media;

import static android.media.MediaRoute2ProviderService.REQUEST_ID_NONE;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
@@ -43,6 +47,7 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@@ -64,6 +69,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
    private Connection mActiveConnection;
    private boolean mConnectionReady;

    private boolean mIsManagerScanning;
    private RouteDiscoveryPreference mLastDiscoveryPreference = null;

    @GuardedBy("mLock")
@@ -86,6 +92,13 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        pw.println(prefix + "  mConnectionReady=" + mConnectionReady);
    }

    public void setManagerScanning(boolean managerScanning) {
        if (mIsManagerScanning != managerScanning) {
            mIsManagerScanning = managerScanning;
            updateBinding();
        }
    }

    @Override
    public void requestCreateSession(long requestId, String packageName, String routeId,
            Bundle sessionHints) {
@@ -209,7 +222,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
            // Bind when there is a discovery preference or an active route session.
            return (mLastDiscoveryPreference != null
                    && !mLastDiscoveryPreference.getPreferredFeatures().isEmpty())
                    || !getSessionInfos().isEmpty();
                    || !getSessionInfos().isEmpty()
                    || mIsManagerScanning;
        }
        return false;
    }
@@ -311,13 +325,12 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        }
    }

    private void onProviderStateUpdated(Connection connection,
            MediaRoute2ProviderInfo providerInfo) {
    private void onProviderUpdated(Connection connection, MediaRoute2ProviderInfo providerInfo) {
        if (mActiveConnection != connection) {
            return;
        }
        if (DEBUG) {
            Slog.d(TAG, this + ": State changed ");
            Slog.d(TAG, this + ": updated");
        }
        setAndNotifyProviderState(providerInfo);
    }
@@ -350,40 +363,44 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        mCallback.onSessionCreated(this, requestId, newSession);
    }

    private void onSessionUpdated(Connection connection, RoutingSessionInfo updatedSession) {
        if (mActiveConnection != connection) {
            return;
    private int findSessionByIdLocked(RoutingSessionInfo session) {
        for (int i = 0; i < mSessionInfos.size(); i++) {
            if (TextUtils.equals(mSessionInfos.get(i).getId(), session.getId())) {
                return i;
            }
        if (updatedSession == null) {
            Slog.w(TAG, "onSessionUpdated: Ignoring null session sent from "
                    + mComponentName);
            return;
        }
        return -1;
    }

        updatedSession = assignProviderIdForSession(updatedSession);

        boolean found = false;
        synchronized (mLock) {
            for (int i = 0; i < mSessionInfos.size(); i++) {
                if (mSessionInfos.get(i).getId().equals(updatedSession.getId())) {
                    mSessionInfos.set(i, updatedSession);
                    found = true;
                    break;
                }
    private void onSessionsUpdated(Connection connection, List<RoutingSessionInfo> sessions) {
        if (mActiveConnection != connection) {
            return;
        }

            if (!found) {
                for (RoutingSessionInfo releasingSession : mReleasingSessions) {
                    if (TextUtils.equals(releasingSession.getId(), updatedSession.getId())) {
                        return;
        int targetIndex = 0;
        synchronized (mLock) {
            for (RoutingSessionInfo session : sessions) {
                if (session == null) continue;
                session = assignProviderIdForSession(session);

                int sourceIndex = findSessionByIdLocked(session);
                if (sourceIndex < 0) {
                    mSessionInfos.add(targetIndex++, session);
                    dispatchSessionCreated(REQUEST_ID_NONE, session);
                } else if (sourceIndex < targetIndex) {
                    Slog.w(TAG, "Ignoring duplicate session ID: " + session.getId());
                } else {
                    mSessionInfos.set(sourceIndex, session);
                    Collections.swap(mSessionInfos, sourceIndex, targetIndex++);
                    dispatchSessionUpdated(session);
                }
            }
                Slog.w(TAG, "onSessionUpdated: Matching session info not found");
                return;
            for (int i = mSessionInfos.size() - 1; i >= targetIndex; i--) {
                RoutingSessionInfo releasedSession = mSessionInfos.remove(i);
                dispatchSessionReleased(releasedSession);
            }
        }

        mCallback.onSessionUpdated(this, updatedSession);
    }

    private void onSessionReleased(Connection connection, RoutingSessionInfo releaedSession) {
@@ -424,6 +441,21 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        mCallback.onSessionReleased(this, releaedSession);
    }

    private void dispatchSessionCreated(long requestId, RoutingSessionInfo session) {
        mHandler.sendMessage(
                obtainMessage(mCallback::onSessionCreated, this, requestId, session));
    }

    private void dispatchSessionUpdated(RoutingSessionInfo session) {
        mHandler.sendMessage(
                obtainMessage(mCallback::onSessionUpdated, this, session));
    }

    private void dispatchSessionReleased(RoutingSessionInfo session) {
        mHandler.sendMessage(
                obtainMessage(mCallback::onSessionReleased, this, session));
    }

    private RoutingSessionInfo assignProviderIdForSession(RoutingSessionInfo sessionInfo) {
        return new RoutingSessionInfo.Builder(sessionInfo)
                .setOwnerPackageName(mComponentName.getPackageName())
@@ -436,7 +468,7 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
            return;
        }

        if (requestId == MediaRoute2ProviderService.REQUEST_ID_NONE) {
        if (requestId == REQUEST_ID_NONE) {
            Slog.w(TAG, "onRequestFailed: Ignoring requestId REQUEST_ID_NONE");
            return;
        }
@@ -561,16 +593,16 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
            mHandler.post(() -> onConnectionDied(Connection.this));
        }

        void postProviderStateUpdated(MediaRoute2ProviderInfo providerInfo) {
            mHandler.post(() -> onProviderStateUpdated(Connection.this, providerInfo));
        void postProviderUpdated(MediaRoute2ProviderInfo providerInfo) {
            mHandler.post(() -> onProviderUpdated(Connection.this, providerInfo));
        }

        void postSessionCreated(long requestId, RoutingSessionInfo sessionInfo) {
            mHandler.post(() -> onSessionCreated(Connection.this, requestId, sessionInfo));
        }

        void postSessionUpdated(RoutingSessionInfo sessionInfo) {
            mHandler.post(() -> onSessionUpdated(Connection.this, sessionInfo));
        void postSessionsUpdated(List<RoutingSessionInfo> sessionInfo) {
            mHandler.post(() -> onSessionsUpdated(Connection.this, sessionInfo));
        }

        void postSessionReleased(RoutingSessionInfo sessionInfo) {
@@ -595,10 +627,10 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        }

        @Override
        public void updateState(MediaRoute2ProviderInfo providerInfo) {
        public void notifyProviderUpdated(MediaRoute2ProviderInfo providerInfo) {
            Connection connection = mConnectionRef.get();
            if (connection != null) {
                connection.postProviderStateUpdated(providerInfo);
                connection.postProviderUpdated(providerInfo);
            }
        }

@@ -611,10 +643,10 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
        }

        @Override
        public void notifySessionUpdated(RoutingSessionInfo sessionInfo) {
        public void notifySessionsUpdated(List<RoutingSessionInfo> sessionInfo) {
            Connection connection = mConnectionRef.get();
            if (connection != null) {
                connection.postSessionUpdated(sessionInfo);
                connection.postSessionsUpdated(sessionInfo);
            }
        }

+10 −0
Original line number Diff line number Diff line
@@ -2156,6 +2156,8 @@ class MediaRouter2ServiceImpl {
            List<RouterRecord> routerRecords = getRouterRecords();
            List<ManagerRecord> managerRecords = getManagerRecords();

            boolean shouldBindProviders = false;

            if (service.mPowerManager.isInteractive()) {
                boolean isManagerScanning = managerRecords.stream().anyMatch(manager ->
                        manager.mIsScanning && service.mActivityManager
@@ -2166,6 +2168,7 @@ class MediaRouter2ServiceImpl {
                    discoveryPreferences = routerRecords.stream()
                            .map(record -> record.mDiscoveryPreference)
                            .collect(Collectors.toList());
                    shouldBindProviders = true;
                } else {
                    discoveryPreferences = routerRecords.stream().filter(record ->
                            service.mActivityManager.getPackageImportance(record.mPackageName)
@@ -2175,6 +2178,13 @@ class MediaRouter2ServiceImpl {
                }
            }

            for (MediaRoute2Provider provider : mRouteProviders) {
                if (provider instanceof MediaRoute2ProviderServiceProxy) {
                    ((MediaRoute2ProviderServiceProxy) provider)
                            .setManagerScanning(shouldBindProviders);
                }
            }

            synchronized (service.mLock) {
                RouteDiscoveryPreference newPreference =
                        new RouteDiscoveryPreference.Builder(discoveryPreferences).build();