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

Commit 427f7429 authored by Youngsang Cho's avatar Youngsang Cho Committed by Android (Google) Code Review
Browse files

Merge "TIF: Add onInputAdded and onInputRemoved" into lmp-dev

parents 55982169 8e6b51b0
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -16642,8 +16642,8 @@ package android.media.tv {
    method public int getInputState(java.lang.String);
    method public android.media.tv.TvInputInfo getTvInputInfo(java.lang.String);
    method public java.util.List<android.media.tv.TvInputInfo> getTvInputList();
    method public void registerListener(android.media.tv.TvInputManager.TvInputListener, android.os.Handler);
    method public void unregisterListener(android.media.tv.TvInputManager.TvInputListener);
    method public void registerCallback(android.media.tv.TvInputManager.TvInputCallback, android.os.Handler);
    method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
    field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
    field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
    field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
@@ -16653,8 +16653,10 @@ package android.media.tv {
    field public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; // 0x2
  }
  public static abstract class TvInputManager.TvInputListener {
    ctor public TvInputManager.TvInputListener();
  public static abstract class TvInputManager.TvInputCallback {
    ctor public TvInputManager.TvInputCallback();
    method public void onInputAdded(java.lang.String);
    method public void onInputRemoved(java.lang.String);
    method public void onInputStateChanged(java.lang.String, int);
  }
+2 −0
Original line number Diff line number Diff line
@@ -22,4 +22,6 @@ package android.media.tv;
 */
oneway interface ITvInputManagerCallback {
    void onInputStateChanged(in String inputId, int state);
    void onInputAdded(in String inputId);
    void onInputRemoved(in String inputId);
}
+96 −42
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ public final class TvInputManager {
     * The TV input is connected.
     * <p>
     * State for {@link #getInputState} and {@link
     * TvInputManager.TvInputListener#onInputStateChanged}.
     * TvInputManager.TvInputCallback#onInputStateChanged}.
     * </p>
     */
    public static final int INPUT_STATE_CONNECTED = 0;
@@ -82,7 +82,7 @@ public final class TvInputManager {
     * fully ready.
     * <p>
     * State for {@link #getInputState} and {@link
     * TvInputManager.TvInputListener#onInputStateChanged}.
     * TvInputManager.TvInputCallback#onInputStateChanged}.
     * </p>
     */
    public static final int INPUT_STATE_CONNECTED_STANDBY = 1;
@@ -90,7 +90,7 @@ public final class TvInputManager {
     * The TV input is disconnected.
     * <p>
     * State for {@link #getInputState} and {@link
     * TvInputManager.TvInputListener#onInputStateChanged}.
     * TvInputManager.TvInputCallback#onInputStateChanged}.
     * </p>
     */
    public static final int INPUT_STATE_DISCONNECTED = 2;
@@ -100,8 +100,8 @@ public final class TvInputManager {
    private final Object mLock = new Object();

    // @GuardedBy(mLock)
    private final List<TvInputListenerRecord> mTvInputListenerRecordsList =
            new LinkedList<TvInputListenerRecord>();
    private final List<TvInputCallbackRecord> mTvInputCallbackRecordsList =
            new LinkedList<TvInputCallbackRecord>();

    // A mapping from TV input ID to the state of corresponding input.
    // @GuardedBy(mLock)
@@ -296,12 +296,12 @@ public final class TvInputManager {
    /**
     * Interface used to monitor status of the TV input.
     */
    public abstract static class TvInputListener {
    public abstract static class TvInputCallback {
        /**
         * This is called when the state of a given TV input is changed.
         *
         * @param inputId the id of the TV input.
         * @param state state of the TV input. The value is one of the following:
         * @param inputId The id of the TV input.
         * @param state State of the TV input. The value is one of the following:
         * <ul>
         * <li>{@link TvInputManager#INPUT_STATE_CONNECTED}
         * <li>{@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY}
@@ -310,26 +310,60 @@ public final class TvInputManager {
         */
        public void onInputStateChanged(String inputId, int state) {
        }

        /**
         * This is called when a TV input is added.
         *
         * @param inputId The id of the TV input.
         */
        public void onInputAdded(String inputId) {
        }

        /**
         * This is called when a TV input is removed.
         *
         * @param inputId The id of the TV input.
         */
        public void onInputRemoved(String inputId) {
        }
    }

    private static final class TvInputListenerRecord {
        private final TvInputListener mListener;
    private static final class TvInputCallbackRecord {
        private final TvInputCallback mCallback;
        private final Handler mHandler;

        public TvInputListenerRecord(TvInputListener listener, Handler handler) {
            mListener = listener;
        public TvInputCallbackRecord(TvInputCallback callback, Handler handler) {
            mCallback = callback;
            mHandler = handler;
        }

        public TvInputListener getListener() {
            return mListener;
        public TvInputCallback getCallback() {
            return mCallback;
        }

        public void postInputStateChanged(final String inputId, final int state) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mCallback.onInputStateChanged(inputId, state);
                }
            });
        }

        public void postInputAdded(final String inputId) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mCallback.onInputAdded(inputId);
                }
            });
        }

        public void postStateChanged(final String inputId, final int state) {
        public void postInputRemoved(final String inputId) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mListener.onInputStateChanged(inputId, state);
                    mCallback.onInputRemoved(inputId);
                }
            });
        }
@@ -451,8 +485,28 @@ public final class TvInputManager {
            public void onInputStateChanged(String inputId, int state) {
                synchronized (mLock) {
                    mStateMap.put(inputId, state);
                    for (TvInputListenerRecord record : mTvInputListenerRecordsList) {
                        record.postStateChanged(inputId, state);
                    for (TvInputCallbackRecord record : mTvInputCallbackRecordsList) {
                        record.postInputStateChanged(inputId, state);
                    }
                }
            }

            @Override
            public void onInputAdded(String inputId) {
                synchronized (mLock) {
                    mStateMap.put(inputId, INPUT_STATE_CONNECTED);
                    for (TvInputCallbackRecord record : mTvInputCallbackRecordsList) {
                        record.postInputAdded(inputId);
                    }
                }
            }

            @Override
            public void onInputRemoved(String inputId) {
                synchronized (mLock) {
                    mStateMap.remove(inputId);
                    for (TvInputCallbackRecord record : mTvInputCallbackRecordsList) {
                        record.postInputRemoved(inputId);
                    }
                }
            }
@@ -499,7 +553,7 @@ public final class TvInputManager {
     * <li>{@link #INPUT_STATE_DISCONNECTED}
     * </ul>
     *
     * @param inputId the id of the TV input.
     * @param inputId The id of the TV input.
     * @throws IllegalArgumentException if the argument is {@code null} or if there is no
     *        {@link TvInputInfo} corresponding to {@code inputId}.
     */
@@ -517,39 +571,39 @@ public final class TvInputManager {
    }

    /**
     * Registers a {@link TvInputListener}.
     * Registers a {@link TvInputCallback}.
     *
     * @param listener a listener used to monitor status of the TV inputs.
     * @param handler a {@link Handler} that the status change will be delivered to.
     * @param callback A callback used to monitor status of the TV inputs.
     * @param handler A {@link Handler} that the status change will be delivered to.
     * @throws IllegalArgumentException if any of the arguments is {@code null}.
     */
    public void registerListener(TvInputListener listener, Handler handler) {
        if (listener == null) {
            throw new IllegalArgumentException("listener cannot be null");
    public void registerCallback(TvInputCallback callback, Handler handler) {
        if (callback == null) {
            throw new IllegalArgumentException("callback cannot be null");
        }
        if (handler == null) {
            throw new IllegalArgumentException("handler cannot be null");
        }
        synchronized (mLock) {
            mTvInputListenerRecordsList.add(new TvInputListenerRecord(listener, handler));
            mTvInputCallbackRecordsList.add(new TvInputCallbackRecord(callback, handler));
        }
    }

    /**
     * Unregisters the existing {@link TvInputListener}.
     * Unregisters the existing {@link TvInputCallback}.
     *
     * @param listener the existing listener to remove.
     * @param callback The existing callback to remove.
     * @throws IllegalArgumentException if any of the arguments is {@code null}.
     */
    public void unregisterListener(final TvInputListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener cannot be null");
    public void unregisterCallback(final TvInputCallback callback) {
        if (callback == null) {
            throw new IllegalArgumentException("callback cannot be null");
        }
        synchronized (mLock) {
            for (Iterator<TvInputListenerRecord> it = mTvInputListenerRecordsList.iterator();
            for (Iterator<TvInputCallbackRecord> it = mTvInputCallbackRecordsList.iterator();
                    it.hasNext(); ) {
                TvInputListenerRecord record = it.next();
                if (record.getListener() == listener) {
                TvInputCallbackRecord record = it.next();
                if (record.getCallback() == callback) {
                    it.remove();
                    break;
                }
@@ -564,9 +618,9 @@ public final class TvInputManager {
     * the given TV input.
     * </p>
     *
     * @param inputId the id of the TV input.
     * @param callback a callback used to receive the created session.
     * @param handler a {@link Handler} that the session creation will be delivered to.
     * @param inputId The id of the TV input.
     * @param callback A callback used to receive the created session.
     * @param handler A {@link Handler} that the session creation will be delivered to.
     * @throws IllegalArgumentException if any of the arguments is {@code null}.
     * @hide
     */
@@ -752,7 +806,7 @@ public final class TvInputManager {
        /**
         * Select a track.
         *
         * @param track the track to be selected.
         * @param track The track to be selected.
         * @see #getTracks()
         */
        public void selectTrack(TvTrackInfo track) {
@@ -773,7 +827,7 @@ public final class TvInputManager {
        /**
         * Unselect a track.
         *
         * @param track the track to be selected.
         * @param track The track to be selected.
         * @see #getTracks()
         */
        public void unselectTrack(TvTrackInfo track) {
@@ -880,10 +934,10 @@ public final class TvInputManager {
        /**
         * Dispatches an input event to this session.
         *
         * @param event {@link InputEvent} to dispatch.
         * @param event An {@link InputEvent} to dispatch.
         * @param token A token used to identify the input event later in the callback.
         * @param callback A callback used to receive the dispatch result.
         * @param handler {@link Handler} that the dispatch result will be delivered to.
         * @param handler A {@link Handler} that the dispatch result will be delivered to.
         * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns
         *         {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns
         *         {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will
@@ -927,7 +981,7 @@ public final class TvInputManager {
            /**
             * Called when the dispatched input event is finished.
             *
             * @param token a token passed to {@link #dispatchInputEvent}.
             * @param token A token passed to {@link #dispatchInputEvent}.
             * @param handled {@code true} if the dispatched input event was handled properly.
             *            {@code false} otherwise.
             */
+52 −14
Original line number Diff line number Diff line
@@ -212,9 +212,7 @@ public final class TvInputManagerService extends SystemService {
    private void buildTvInputListLocked(int userId) {
        UserState userState = getUserStateLocked(userId);

        Map<String, TvInputState> oldInputMap = userState.inputMap;
        userState.inputMap = new HashMap<String, TvInputState>();

        Map<String, TvInputState> inputMap = new HashMap<String, TvInputState>();
        userState.packageSet.clear();

        if (DEBUG) Slog.d(TAG, "buildTvInputList");
@@ -250,12 +248,12 @@ public final class TvInputManagerService extends SystemService {

                for (TvInputInfo info : infoList) {
                    if (DEBUG) Slog.d(TAG, "add " + info.getId());
                    TvInputState state = oldInputMap.get(info.getId());
                    TvInputState state = userState.inputMap.get(info.getId());
                    if (state == null) {
                        state = new TvInputState();
                    }
                    userState.inputMap.put(info.getId(), state);
                    state.mInfo = info;
                    inputMap.put(info.getId(), state);
                }

                // Reconnect the service if existing input is updated.
@@ -266,7 +264,21 @@ public final class TvInputManagerService extends SystemService {
                Slog.e(TAG, "Can't load TV input " + si.name, e);
            }
        }
        oldInputMap.clear();

        for (String inputId : inputMap.keySet()) {
            if (!userState.inputMap.containsKey(inputId)) {
                notifyInputAddedLocked(userState, inputId);
            }
        }

        for (String inputId : userState.inputMap.keySet()) {
            if (!inputMap.containsKey(inputId)) {
                notifyInputRemovedLocked(userState, inputId);
            }
        }

        userState.inputMap.clear();
        userState.inputMap = inputMap;
    }

    private void switchUser(int userId) {
@@ -694,10 +706,36 @@ public final class TvInputManagerService extends SystemService {
        }
    }

    private void notifyStateChangedLocked(UserState userState, String inputId,
    private void notifyInputAddedLocked(UserState userState, String inputId) {
        if (DEBUG) {
            Slog.d(TAG, "notifyInputAdded: inputId = " + inputId);
        }
        for (ITvInputManagerCallback callback : userState.callbackSet) {
            try {
                callback.onInputAdded(inputId);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to report added input to callback.");
            }
        }
    }

    private void notifyInputRemovedLocked(UserState userState, String inputId) {
        if (DEBUG) {
            Slog.d(TAG, "notifyInputRemovedLocked: inputId = " + inputId);
        }
        for (ITvInputManagerCallback callback : userState.callbackSet) {
            try {
                callback.onInputRemoved(inputId);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to report removed input to callback.");
            }
        }
    }

    private void notifyInputStateChangedLocked(UserState userState, String inputId,
            int state, ITvInputManagerCallback targetCallback) {
        if (DEBUG) {
            Slog.d(TAG, "notifyStateChangedLocked: inputId = " + inputId
            Slog.d(TAG, "notifyInputStateChangedLocked: inputId = " + inputId
                    + "; state = " + state);
        }
        if (targetCallback == null) {
@@ -729,7 +767,7 @@ public final class TvInputManagerService extends SystemService {
            return;
        }
        if (oldState != state) {
            notifyStateChangedLocked(userState, inputId, state, null);
            notifyInputStateChangedLocked(userState, inputId, state, null);
        }
    }

@@ -779,7 +817,7 @@ public final class TvInputManagerService extends SystemService {
                    UserState userState = getUserStateLocked(resolvedUserId);
                    userState.callbackSet.add(callback);
                    for (TvInputState state : userState.inputMap.values()) {
                        notifyStateChangedLocked(userState, state.mInfo.getId(),
                        notifyInputStateChangedLocked(userState, state.mInfo.getId(),
                                state.mState, callback);
                    }
                }
@@ -1200,8 +1238,8 @@ public final class TvInputManagerService extends SystemService {

                    pw.println("inputMap: inputId -> TvInputState");
                    pw.increaseIndent();
                    for (TvInputState state : userState.inputMap.values()) {
                        pw.println(state.toString());
                    for (Map.Entry<String, TvInputState> entry: userState.inputMap.entrySet()) {
                        pw.println(entry.getKey() + ": " + entry.getValue());
                    }
                    pw.decreaseIndent();

@@ -1477,7 +1515,7 @@ public final class TvInputManagerService extends SystemService {
                for (TvInputState inputState : userState.inputMap.values()) {
                    if (inputState.mInfo.getComponent().equals(name)
                            && inputState.mState != INPUT_STATE_DISCONNECTED) {
                        notifyStateChangedLocked(userState, inputState.mInfo.getId(),
                        notifyInputStateChangedLocked(userState, inputState.mInfo.getId(),
                                inputState.mState, null);
                    }
                }
@@ -1526,7 +1564,7 @@ public final class TvInputManagerService extends SystemService {

                    for (TvInputState inputState : userState.inputMap.values()) {
                        if (inputState.mInfo.getComponent().equals(name)) {
                            notifyStateChangedLocked(userState, inputState.mInfo.getId(),
                            notifyInputStateChangedLocked(userState, inputState.mInfo.getId(),
                                    INPUT_STATE_DISCONNECTED, null);
                        }
                    }