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

Commit 6c1153b4 authored by Yixiao Luo's avatar Yixiao Luo
Browse files

External TV Input Logging: implement display name lookup table and filtering

Bug: 279185950
Test: manual

Change-Id: Ic2b621a1e188d8ddf94b788ba556a21a537eb994
parent d8f9519d
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright (C) 2023 The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->

<!-- These resources are around just to allow their values to be customized
     for different hardware and product builds.  Do not translate.

     NOTE: The naming convention is "config_camelCaseValue". Some legacy
     entries do not follow the convention, but all new entries should. -->

<resources>
    <bool name="config_tvExternalInputLoggingDisplayNameFilterEnabled">false</bool>

    <string-array name="config_tvExternalInputLoggingDeviceOnScreenDisplayNames">
        <item>Chromecast</item>
        <item>Chromecast HD</item>
        <item>SHIELD</item>
        <item>Roku</item>
        <item>Roku Express 4</item>
        <item>Home Theater</item>
        <item>Fire TV Stick</item>
        <item>PlayStation 5</item>
        <item>NintendoSwitch</item>
    </string-array>

    <string-array name="config_tvExternalInputLoggingDeviceBrandNames">
        <item>Chromecast</item>
        <item>SHIELD</item>
        <item>Roku</item>
        <item>Apple</item>
        <item>Fire TV</item>
        <item>PlayStation</item>
        <item>Nintendo</item>
    </string-array>
</resources>
+5 −0
Original line number Diff line number Diff line
@@ -5221,4 +5221,9 @@

  <!-- Whether we order unlocking and waking -->
  <java-symbol type="bool" name="config_orderUnlockAndWake" />

  <!-- External TV Input Logging Configs -->
  <java-symbol type="bool" name="config_tvExternalInputLoggingDisplayNameFilterEnabled" />
  <java-symbol type="array" name="config_tvExternalInputLoggingDeviceOnScreenDisplayNames" />
  <java-symbol type="array" name="config_tvExternalInputLoggingDeviceBrandNames" />
</resources>
+43 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Rect;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
@@ -94,6 +95,7 @@ import android.util.SparseArray;
import android.view.InputChannel;
import android.view.Surface;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
@@ -177,6 +179,11 @@ public final class TvInputManagerService extends SystemService {

    private final ActivityManager mActivityManager;

    private boolean mExternalInputLoggingDisplayNameFilterEnabled = false;
    private final HashSet<String> mExternalInputLoggingDeviceOnScreenDisplayNames =
            new HashSet<String>();
    private final List<String> mExternalInputLoggingDeviceBrandNames = new ArrayList<String>();

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

@@ -192,6 +199,8 @@ public final class TvInputManagerService extends SystemService {
        synchronized (mLock) {
            getOrCreateUserStateLocked(mCurrentUserId);
        }

        initExternalInputLoggingConfigs();
    }

    @Override
@@ -224,6 +233,21 @@ public final class TvInputManagerService extends SystemService {
        }
    }

    private void initExternalInputLoggingConfigs() {
        mExternalInputLoggingDisplayNameFilterEnabled = mContext.getResources().getBoolean(
                R.bool.config_tvExternalInputLoggingDisplayNameFilterEnabled);
        if (!mExternalInputLoggingDisplayNameFilterEnabled) {
            return;
        }
        final String[] deviceOnScreenDisplayNames = mContext.getResources().getStringArray(
                R.array.config_tvExternalInputLoggingDeviceOnScreenDisplayNames);
        final String[] deviceBrandNames = mContext.getResources().getStringArray(
                R.array.config_tvExternalInputLoggingDeviceBrandNames);
        mExternalInputLoggingDeviceOnScreenDisplayNames.addAll(
                Arrays.asList(deviceOnScreenDisplayNames));
        mExternalInputLoggingDeviceBrandNames.addAll(Arrays.asList(deviceBrandNames));
    }

    private void registerBroadcastReceivers() {
        PackageMonitor monitor = new PackageMonitor() {
            private void buildTvInputList(String[] packages) {
@@ -3073,6 +3097,9 @@ public final class TvInputManagerService extends SystemService {
                hdmiPort = hdmiDeviceInfo.getPortId();
                if (hdmiDeviceInfo.isCecDevice()) {
                    displayName = hdmiDeviceInfo.getDisplayName();
                    if (mExternalInputLoggingDisplayNameFilterEnabled) {
                        displayName = filterExternalInputLoggingDisplayName(displayName);
                    }
                    vendorId = hdmiDeviceInfo.getVendorId();
                }
            }
@@ -3082,6 +3109,22 @@ public final class TvInputManagerService extends SystemService {
                inputType, vendorId, hdmiPort, tifSessionId, displayName);
    }

    private String filterExternalInputLoggingDisplayName(String displayName) {
        String nullDisplayName = "NULL_DISPLAY_NAME", filteredDisplayName = "FILTERED_DISPLAY_NAME";
        if (displayName == null) {
            return nullDisplayName;
        }
        if (mExternalInputLoggingDeviceOnScreenDisplayNames.contains(displayName)) {
            return displayName;
        }
        for (String brandName : mExternalInputLoggingDeviceBrandNames) {
            if (displayName.toUpperCase().contains(brandName.toUpperCase())) {
                return brandName;
            }
        }
        return filteredDisplayName;
    }

    private static final class UserState {
        // A mapping from the TV input id to its TvInputState.
        private Map<String, TvInputState> inputMap = new HashMap<>();