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

Commit 2dc5d838 authored by Shenqiu Zhang's avatar Shenqiu Zhang Committed by Android (Google) Code Review
Browse files

Merge "Clean up dead RouterRecords after unbinding them" into main

parents 52d9f07f 74381b8e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -10,6 +10,16 @@ flag {
    bug: "275185436"
}

flag {
    name: "clean_up_dead_router_records_after_unbinding"
    namespace: "media_better_together"
    description: "Fixes a bug of notifying unbound router records that causes DeadObjectException."
    bug: "414836668"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "disable_set_bluetooth_ad2p_on_calls"
    namespace: "media_better_together"
+84 −13
Original line number Diff line number Diff line
@@ -1295,7 +1295,7 @@ class MediaRouter2ServiceImpl {
            throw new RuntimeException("MediaRouter2 died prematurely.", ex);
        }

        userRecord.mRouterRecords.add(routerRecord);
        userRecord.addRouterRecord(routerRecord);
        mAllRouterRecords.put(binder, routerRecord);

        userRecord.mHandler.sendMessage(
@@ -1328,11 +1328,10 @@ class MediaRouter2ServiceImpl {
        Slog.i(
                TAG,
                TextUtils.formatSimple(
                        "unregisterRouter2 | package: %s, router id: %d, died: %b",
                        routerRecord.mPackageName, routerRecord.mRouterId, died));
                        "unregisterRouter2 | %s, died: %b", routerRecord.getDebugString(), died));

        UserRecord userRecord = routerRecord.mUserRecord;
        userRecord.mRouterRecords.remove(routerRecord);
        userRecord.removeRouterRecord(routerRecord);
        routerRecord.mUserRecord.mHandler.sendMessage(
                obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers,
                        routerRecord.mUserRecord.mHandler,
@@ -1899,11 +1898,8 @@ class MediaRouter2ServiceImpl {
        Slog.i(
                TAG,
                TextUtils.formatSimple(
                        "unregisterManager | package: %s, user: %d, manager: %d, died: %b",
                        managerRecord.mOwnerPackageName,
                        userRecord.mUserId,
                        managerRecord.mManagerId,
                        died));
                        "unregisterManager | %s, user: %d, died: %b",
                        managerRecord.getDebugString(), userRecord.mUserId, died));

        userRecord.mManagerRecords.remove(managerRecord);
        managerRecord.dispose();
@@ -2330,7 +2326,7 @@ class MediaRouter2ServiceImpl {
    final class UserRecord {
        public final int mUserId;
        //TODO: make records private for thread-safety
        final ArrayList<RouterRecord> mRouterRecords = new ArrayList<>();
        private final ArrayList<RouterRecord> mRouterRecords = new ArrayList<>();
        final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();

        // @GuardedBy("mLock")
@@ -2354,6 +2350,17 @@ class MediaRouter2ServiceImpl {
            mHandler.init();
        }

        void addRouterRecord(RouterRecord routerRecord) {
            mRouterRecords.add(routerRecord);
        }

        void removeRouterRecord(RouterRecord routerRecord) {
            mRouterRecords.remove(routerRecord);
            if (Flags.cleanUpDeadRouterRecordsAfterUnbinding()) {
                mHandler.removeRouterRecord(routerRecord);
            }
        }

        // TODO: This assumes that only one router exists in a package.
        //       Do this in Android S or later.
        @GuardedBy("mLock")
@@ -2366,6 +2373,16 @@ class MediaRouter2ServiceImpl {
            return null;
        }

        /** Returns true if the given RouterRecord is binded to the service. */
        boolean isRouterRecordBinded(RouterRecord routerRecordToCheck) {
            for (RouterRecord routerRecord : mRouterRecords) {
                if (routerRecord.mRouterId == routerRecordToCheck.mRouterId) {
                    return true;
                }
            }
            return false;
        }

        // @GuardedBy("mLock")
        public void updateDeviceSuggestionsLocked(
                String packageName,
@@ -3046,6 +3063,12 @@ class MediaRouter2ServiceImpl {
        @Override
        public void onSessionCreated(@NonNull MediaRoute2Provider provider,
                long uniqueRequestId, @NonNull RoutingSessionInfo sessionInfo) {
            Slog.i(
                    TAG,
                    "onSessionCreated with uniqueRequestId: "
                            + uniqueRequestId
                            + ", sessionInfo: "
                            + sessionInfo);
            sendMessage(PooledLambda.obtainMessage(UserHandler::onSessionCreatedOnHandler,
                    this, provider, uniqueRequestId, sessionInfo));
        }
@@ -3112,6 +3135,24 @@ class MediaRouter2ServiceImpl {
            }
        }

        public void removeRouterRecord(RouterRecord routerRecord) {
            for (String sessionId : mSessionToRouterMap.keySet()) {
                RouterRecord routerRecordWithSession = mSessionToRouterMap.get(sessionId);
                if (routerRecordWithSession.mRouterId == routerRecord.mRouterId) {
                    // Release the session associated with the RouterRecord being removed. The
                    // onSessionReleasedOnHandler callback will then remove the RouterRecord from
                    // mSessionToRouterMap.
                    sendMessage(
                            PooledLambda.obtainMessage(
                                    UserHandler::releaseSessionOnHandler,
                                    this,
                                    DUMMY_REQUEST_ID,
                                    routerRecordWithSession,
                                    sessionId));
                }
            }
        }

        public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
            pw.println(prefix + "UserHandler");

@@ -3580,6 +3621,16 @@ class MediaRouter2ServiceImpl {
            }

            mSessionCreationRequests.remove(matchingRequest);

            if (Flags.cleanUpDeadRouterRecordsAfterUnbinding()
                    && !mUserRecord.isRouterRecordBinded(matchingRequest.mRouterRecord)) {
                Slog.w(
                        TAG,
                        "Ignoring session creation request for unbound router:"
                                + matchingRequest.mRouterRecord.getDebugString());
                return;
            }

            // Not to show old session
            MediaRoute2Provider oldProvider =
                    findProvider(matchingRequest.mOldSession.getProviderId());
@@ -3650,8 +3701,11 @@ class MediaRouter2ServiceImpl {
                        + sessionInfo);
                return;
            }
            if (!Flags.cleanUpDeadRouterRecordsAfterUnbinding()
                    || mUserRecord.isRouterRecordBinded(routerRecord)) {
                notifySessionInfoChangedToRouters(Arrays.asList(routerRecord), sessionInfo);
            }
        }

        private void onSessionReleasedOnHandler(@NonNull MediaRoute2Provider provider,
                @NonNull RoutingSessionInfo sessionInfo) {
@@ -3666,8 +3720,16 @@ class MediaRouter2ServiceImpl {
                        + sessionInfo);
                return;
            }

            if (Flags.cleanUpDeadRouterRecordsAfterUnbinding()) {
                if (mUserRecord.isRouterRecordBinded(routerRecord)) {
                    routerRecord.notifySessionReleased(sessionInfo);
                }
                mSessionToRouterMap.remove(sessionInfo.getId());
            } else {
                routerRecord.notifySessionReleased(sessionInfo);
            }
        }

        private void onRequestFailedOnHandler(@NonNull MediaRoute2Provider provider,
                long uniqueRequestId, int reason) {
@@ -3721,6 +3783,15 @@ class MediaRouter2ServiceImpl {

            mSessionCreationRequests.remove(matchingRequest);

            if (Flags.cleanUpDeadRouterRecordsAfterUnbinding()
                    && !mUserRecord.isRouterRecordBinded(matchingRequest.mRouterRecord)) {
                Slog.w(
                        TAG,
                        "handleSessionCreationRequestFailed | Ignoring with unbound router:"
                                + matchingRequest.mRouterRecord.getDebugString());
                return false;
            }

            // Notify the requester about the failure.
            // The call should be made by either MediaRouter2 or MediaRouter2Manager.
            if (matchingRequest.mManagerRequestId == MediaRouter2Manager.REQUEST_ID_NONE) {
@@ -3894,7 +3965,7 @@ class MediaRouter2ServiceImpl {
                } catch (RemoteException ex) {
                    Slog.w(
                            TAG,
                            "Failed to notify preferred features changed."
                            "Failed to notify route listing preference changed."
                                    + " Manager probably died.",
                            ex);
                }