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

Commit 43b75cad authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Fix exception of unregisterCallback when callback is not registered"

parents 83152b1e 36932057
Loading
Loading
Loading
Loading
+33 −36
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -128,8 +129,6 @@ public final class TvInputManagerService extends SystemService {

    private final WatchLogHandler mWatchLogHandler;

    private IBinder.DeathRecipient mDeathRecipient;

    public TvInputManagerService(Context context) {
        super(context);

@@ -484,7 +483,7 @@ public final class TvInputManagerService extends SystemService {
            userState.packageSet.clear();
            userState.contentRatingSystemList.clear();
            userState.clientStateMap.clear();
            userState.callbackSet.clear();
            userState.mCallbacks.kill();
            userState.mainSessionToken = null;

            mUserStates.remove(userId);
@@ -749,39 +748,45 @@ public final class TvInputManagerService extends SystemService {
        if (DEBUG) {
            Slog.d(TAG, "notifyInputAddedLocked(inputId=" + inputId + ")");
        }
        for (ITvInputManagerCallback callback : userState.callbackSet) {
        int n = userState.mCallbacks.beginBroadcast();
        for (int i = 0; i < n; ++i) {
            try {
                callback.onInputAdded(inputId);
                userState.mCallbacks.getBroadcastItem(i).onInputAdded(inputId);
            } catch (RemoteException e) {
                Slog.e(TAG, "failed to report added input to callback", e);
            }
        }
        userState.mCallbacks.finishBroadcast();
    }

    private void notifyInputRemovedLocked(UserState userState, String inputId) {
        if (DEBUG) {
            Slog.d(TAG, "notifyInputRemovedLocked(inputId=" + inputId + ")");
        }
        for (ITvInputManagerCallback callback : userState.callbackSet) {
        int n = userState.mCallbacks.beginBroadcast();
        for (int i = 0; i < n; ++i) {
            try {
                callback.onInputRemoved(inputId);
                userState.mCallbacks.getBroadcastItem(i).onInputRemoved(inputId);
            } catch (RemoteException e) {
                Slog.e(TAG, "failed to report removed input to callback", e);
            }
        }
        userState.mCallbacks.finishBroadcast();
    }

    private void notifyInputUpdatedLocked(UserState userState, String inputId) {
        if (DEBUG) {
            Slog.d(TAG, "notifyInputUpdatedLocked(inputId=" + inputId + ")");
        }
        for (ITvInputManagerCallback callback : userState.callbackSet) {
        int n = userState.mCallbacks.beginBroadcast();
        for (int i = 0; i < n; ++i) {
            try {
                callback.onInputUpdated(inputId);
                userState.mCallbacks.getBroadcastItem(i).onInputUpdated(inputId);
            } catch (RemoteException e) {
                Slog.e(TAG, "failed to report updated input to callback", e);
            }
        }
        userState.mCallbacks.finishBroadcast();
    }

    private void notifyInputStateChangedLocked(UserState userState, String inputId,
@@ -791,13 +796,15 @@ public final class TvInputManagerService extends SystemService {
                    + ", state=" + state + ")");
        }
        if (targetCallback == null) {
            for (ITvInputManagerCallback callback : userState.callbackSet) {
            int n = userState.mCallbacks.beginBroadcast();
            for (int i = 0; i < n; ++i) {
                try {
                    callback.onInputStateChanged(inputId, state);
                    userState.mCallbacks.getBroadcastItem(i).onInputStateChanged(inputId, state);
                } catch (RemoteException e) {
                    Slog.e(TAG, "failed to report state change to callback", e);
                }
            }
            userState.mCallbacks.finishBroadcast();
        } else {
            try {
                targetCallback.onInputStateChanged(inputId, state);
@@ -819,13 +826,15 @@ public final class TvInputManagerService extends SystemService {
        }
        inputState.info = inputInfo;

        for (ITvInputManagerCallback callback : userState.callbackSet) {
        int n = userState.mCallbacks.beginBroadcast();
        for (int i = 0; i < n; ++i) {
            try {
                callback.onTvInputInfoUpdated(inputInfo);
                userState.mCallbacks.getBroadcastItem(i).onTvInputInfoUpdated(inputInfo);
            } catch (RemoteException e) {
                Slog.e(TAG, "failed to report updated input info to callback", e);
            }
        }
        userState.mCallbacks.finishBroadcast();
    }

    private void setStateLocked(String inputId, int state, int userId) {
@@ -1003,22 +1012,8 @@ public final class TvInputManagerService extends SystemService {
            try {
                synchronized (mLock) {
                    final UserState userState = getOrCreateUserStateLocked(resolvedUserId);
                    userState.callbackSet.add(callback);
                    mDeathRecipient = new IBinder.DeathRecipient() {
                        @Override
                        public void binderDied() {
                            synchronized (mLock) {
                                if (userState.callbackSet != null) {
                                    userState.callbackSet.remove(callback);
                                }
                            }
                        }
                    };

                    try {
                        callback.asBinder().linkToDeath(mDeathRecipient, 0);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "client process has already died", e);
                    if (!userState.mCallbacks.register(callback)) {
                        Slog.e(TAG, "client process has already died");
                    }
                }
            } finally {
@@ -1034,8 +1029,7 @@ public final class TvInputManagerService extends SystemService {
            try {
                synchronized (mLock) {
                    UserState userState = getOrCreateUserStateLocked(resolvedUserId);
                    userState.callbackSet.remove(callback);
                    callback.asBinder().unlinkToDeath(mDeathRecipient, 0);
                    userState.mCallbacks.unregister(callback);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
@@ -2104,11 +2098,13 @@ public final class TvInputManagerService extends SystemService {
                    }
                    pw.decreaseIndent();

                    pw.println("callbackSet:");
                    pw.println("mCallbacks:");
                    pw.increaseIndent();
                    for (ITvInputManagerCallback callback : userState.callbackSet) {
                        pw.println(callback.toString());
                    int n = userState.mCallbacks.beginBroadcast();
                    for (int j = 0; j < n; ++j) {
                        pw.println(userState.mCallbacks.getRegisteredCallbackItem(j).toString());
                    }
                    userState.mCallbacks.finishBroadcast();
                    pw.decreaseIndent();

                    pw.println("mainSessionToken: " + userState.mainSessionToken);
@@ -2139,8 +2135,9 @@ public final class TvInputManagerService extends SystemService {
        // A mapping from the token of a TV input session to its state.
        private final Map<IBinder, SessionState> sessionStateMap = new HashMap<>();

        // A set of callbacks.
        private final Set<ITvInputManagerCallback> callbackSet = new HashSet<>();
        // A list of callbacks.
        private final RemoteCallbackList<ITvInputManagerCallback> mCallbacks =
                new RemoteCallbackList<ITvInputManagerCallback>();

        // The token of a "main" TV input session.
        private IBinder mainSessionToken = null;