Merge "External TV Input Logging: get actual input id for logging" into main
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 0ab6d57..06a8516 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -96,6 +96,8 @@
     /* A map from a HDMI logical address to the matching TV input ID. */
     private final SparseArray<String> mHdmiInputIdMap = new SparseArray<>();
     private final Map<String, TvInputInfo> mInputMap = new ArrayMap<>();
+    /* A map from a HDMI input parent ID to the related input IDs. */
+    private final Map<String, List<String>> mHdmiParentInputMap = new ArrayMap<>();
 
     private final AudioManager mAudioManager;
     private final IHdmiHotplugEventListener mHdmiHotplugEventListener =
@@ -293,6 +295,12 @@
         }
     }
 
+    public Map<String, List<String>> getHdmiParentInputMap() {
+        synchronized (mLock) {
+            return Collections.unmodifiableMap(mHdmiParentInputMap);
+        }
+    }
+
     private boolean checkUidChangedLocked(
             Connection connection, int callingUid, int resolvedUserId) {
         Integer connectionCallingUid = connection.getCallingUidLocked();
@@ -379,12 +387,15 @@
             }
             mHdmiInputIdMap.put(id, info.getId());
             mInputMap.put(info.getId(), info);
+            if (!mHdmiParentInputMap.containsKey(parentId)) {
+                mHdmiParentInputMap.put(parentId, new ArrayList<String>());
+            }
+            mHdmiParentInputMap.get(parentId).add(info.getId());
         }
     }
 
     public void removeHardwareInput(String inputId) {
         synchronized (mLock) {
-            mInputMap.remove(inputId);
             int hardwareIndex = indexOfEqualValue(mHardwareInputIdMap, inputId);
             if (hardwareIndex >= 0) {
                 mHardwareInputIdMap.removeAt(hardwareIndex);
@@ -393,6 +404,17 @@
             if (deviceIndex >= 0) {
                 mHdmiInputIdMap.removeAt(deviceIndex);
             }
+            if (mInputMap.containsKey(inputId)) {
+                String parentId = mInputMap.get(inputId).getParentId();
+                if (parentId != null && mHdmiParentInputMap.containsKey(parentId)) {
+                    List<String> parentInputList = mHdmiParentInputMap.get(parentId);
+                    parentInputList.remove(inputId);
+                    if (parentInputList.isEmpty()) {
+                        mHdmiParentInputMap.remove(parentId);
+                    }
+                }
+                mInputMap.remove(inputId);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 2559b84..b12ecc3 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -1839,22 +1839,22 @@
                         getSessionLocked(sessionToken, callingUid, resolvedUserId).tune(
                                 channelUri, params);
                         UserState userState = getOrCreateUserStateLocked(resolvedUserId);
-                        SessionState sessionState = getSessionStateLocked(sessionToken, callingUid,
-                                userState);
+                        SessionState sessionState =
+                                getSessionStateLocked(sessionToken, callingUid, userState);
                         if (!sessionState.isCurrent
                                 || !Objects.equals(sessionState.currentChannel, channelUri)) {
                             sessionState.isCurrent = true;
                             sessionState.currentChannel = channelUri;
                             notifyCurrentChannelInfosUpdatedLocked(userState);
                             if (!sessionState.isRecordingSession) {
-                                if (mOnScreenInputId == null
-                                    || !TextUtils.equals(mOnScreenInputId, sessionState.inputId)) {
+                                String actualInputId = getActualInputId(sessionState);
+                                if (!TextUtils.equals(mOnScreenInputId, actualInputId)) {
                                     logExternalInputEvent(
-                                        FrameworkStatsLog
-                                                .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED,
-                                        sessionState.inputId, sessionState);
+                                            FrameworkStatsLog
+                                                    .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED,
+                                            actualInputId, sessionState);
                                 }
-                                mOnScreenInputId = sessionState.inputId;
+                                mOnScreenInputId = actualInputId;
                                 mOnScreenSessionState = sessionState;
                             }
                         }
@@ -2977,6 +2977,31 @@
         }
     }
 
+    // get the actual input id of the specific sessionState.
+    // e.g. if an HDMI port has a CEC device plugged in, the actual input id of the HDMI
+    // session should be the input id of CEC device instead of the default HDMI input id.
+    @GuardedBy("mLock")
+    private String getActualInputId(SessionState sessionState) {
+        UserState userState = getOrCreateUserStateLocked(sessionState.userId);
+        TvInputState tvInputState = userState.inputMap.get(sessionState.inputId);
+        TvInputInfo tvInputInfo = tvInputState.info;
+        String actualInputId = sessionState.inputId;
+        switch (tvInputInfo.getType()) {
+            case TvInputInfo.TYPE_HDMI:
+                // TODO: find a better approach towards active CEC device in future
+                Map<String, List<String>> hdmiParentInputMap =
+                        mTvInputHardwareManager.getHdmiParentInputMap();
+                if (hdmiParentInputMap.containsKey(sessionState.inputId)) {
+                    List<String> parentInputList = hdmiParentInputMap.get(sessionState.inputId);
+                    actualInputId = parentInputList.get(0);
+                }
+                break;
+            default:
+                break;
+        }
+        return actualInputId;
+    }
+
     @Nullable
     private static TvInputState getTvInputState(
             SessionState sessionState,
@@ -3078,6 +3103,7 @@
                 hdmiPort);
     }
 
+    @GuardedBy("mLock")
     private void logExternalInputEvent(int eventType, String inputId, SessionState sessionState) {
         UserState userState = getOrCreateUserStateLocked(sessionState.userId);
         TvInputState tvInputState = userState.inputMap.get(inputId);
@@ -3617,13 +3643,14 @@
                         mSessionState.currentChannel = channelUri;
                         notifyCurrentChannelInfosUpdatedLocked(userState);
                         if (!mSessionState.isRecordingSession) {
-                            if (mOnScreenInputId == null
-                                || !TextUtils.equals(mOnScreenInputId, mSessionState.inputId)) {
+                            String actualInputId = getActualInputId(mSessionState);
+                            if (!TextUtils.equals(mOnScreenInputId, actualInputId)) {
                                 logExternalInputEvent(
-                                    FrameworkStatsLog.EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED,
-                                    mSessionState.inputId, mSessionState);
+                                        FrameworkStatsLog
+                                                .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED,
+                                        actualInputId, mSessionState);
                             }
-                            mOnScreenInputId = mSessionState.inputId;
+                            mOnScreenInputId = actualInputId;
                             mOnScreenSessionState = mSessionState;
                         }
                     }