Merge "Add system prompt for system language change after <Set Menu Language> CEC message"
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 5874385..ec55e12 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -105,6 +105,12 @@
             "android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1";
 
     /**
+     * Used as an extra field in the Set Menu Language intent. Contains the requested locale.
+     * @hide
+     */
+    public static final String EXTRA_LOCALE = "android.hardware.hdmi.extra.LOCALE";
+
+    /**
      * Volume value for mute state.
      */
     public static final int AVR_VOLUME_MUTED = 101;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4e9aec7..c4fe1a4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10665,6 +10665,15 @@
         public static final String FAST_PAIR_SCAN_ENABLED = "fast_pair_scan_enabled";
 
         /**
+         * Setting to store denylisted system languages by the CEC {@code <Set Menu Language>}
+         * confirmation dialog.
+         *
+         * @hide
+         */
+        public static final String HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST =
+                "hdmi_cec_set_menu_language_denylist";
+
+        /**
          * These entries are considered common between the personal and the managed profile,
          * since the managed profile doesn't get to change them.
          */
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 73568c1..a06b2cb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2891,6 +2891,11 @@
     <string name="config_sensorUseStartedActivity" translatable="false"
             >com.android.systemui/com.android.systemui.sensorprivacy.SensorUseStartedActivity</string>
 
+    <!-- Component name of the activity used to ask a user to confirm system language change after
+         receiving <Set Menu Language> CEC message. -->
+    <string name="config_hdmiCecSetMenuLanguageActivity"
+            >com.android.systemui/com.android.systemui.hdmi.HdmiCecSetMenuLanguageActivity</string>
+
     <!-- Name of the dialog that is used to request the user's consent for a Platform VPN -->
     <string name="config_platformVpnConfirmDialogComponent" translatable="false"
             >com.android.vpndialogs/com.android.vpndialogs.PlatformVpnConfirmDialog</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 94043ed..4c1cc4d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -375,6 +375,7 @@
   <java-symbol type="string" name="config_usbConfirmActivity" />
   <java-symbol type="string" name="config_usbResolverActivity" />
   <java-symbol type="string" name="config_sensorUseStartedActivity" />
+  <java-symbol type="string" name="config_hdmiCecSetMenuLanguageActivity" />
   <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" />
   <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" />
   <java-symbol type="integer" name="config_minNumVisibleRecentTasks_grid" />
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index d95644a..ae350ec 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -74,5 +74,6 @@
         <permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
         <permission name="android.permission.FORCE_STOP_PACKAGES" />
         <permission name="android.permission.ACCESS_FPS_COUNTER" />
+        <permission name="android.permission.CHANGE_CONFIGURATION" />
     </privapp-permissions>
 </permissions>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2e6a58f..55bf6e5 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -303,6 +303,9 @@
     <uses-permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND" />
     <uses-permission android:name="android.permission.SET_CLIP_SOURCE" />
 
+    <!-- To change system language (HDMI CEC) -->
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
@@ -486,6 +489,16 @@
             android:excludeFromRecents="true">
         </activity>
 
+        <!-- started from HdmiCecLocalDevicePlayback -->
+        <activity android:name=".hdmi.HdmiCecSetMenuLanguageActivity"
+                  android:exported="true"
+                  android:launchMode="singleTop"
+                  android:permission="android.permission.CHANGE_CONFIGURATION"
+                  android:theme="@style/BottomSheet"
+                  android:finishOnCloseSystemDialogs="true"
+                  android:excludeFromRecents="true">
+        </activity>
+
         <!-- started from SensoryPrivacyService -->
         <activity android:name=".sensorprivacy.SensorUseStartedActivity"
                   android:exported="true"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 75ae52c..4dca0b0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -123,6 +123,18 @@
     <!-- Message of notification shown when trying to enable USB debugging but a secondary user is the current foreground user. -->
     <string name="usb_debugging_secondary_user_message">The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user.</string>
 
+    <!-- Title of confirmation dialog for wireless debugging [CHAR LIMIT=80] -->
+    <string name="hdmi_cec_set_menu_language_title">Do you want to change the system language to <xliff:g id="language" example="German">%1$s</xliff:g>?</string>
+
+    <!-- Description for the <Set Menu Language> confirmation dialog [CHAR LIMIT=NONE] -->
+    <string name="hdmi_cec_set_menu_language_description">System language change requested by another device</string>
+
+    <!-- Button label for accepting language change [CHAR LIMIT=25] -->
+    <string name="hdmi_cec_set_menu_language_accept">Change language</string>
+
+    <!-- Button label for declining language change [CHAR LIMIT=25] -->
+    <string name="hdmi_cec_set_menu_language_decline">Keep current language</string>
+
     <!-- Title of confirmation dialog for wireless debugging [CHAR LIMIT=NONE] -->
     <string name="wifi_debugging_title">Allow wireless debugging on this network?</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 08ed24c..b32c2b6 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -49,6 +49,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.hdmi.HdmiCecSetMenuLanguageHelper;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.media.dialog.MediaOutputDialogFactory;
@@ -250,6 +251,7 @@
     @Inject Lazy<LocationController> mLocationController;
     @Inject Lazy<RotationLockController> mRotationLockController;
     @Inject Lazy<ZenModeController> mZenModeController;
+    @Inject Lazy<HdmiCecSetMenuLanguageHelper> mHdmiCecSetMenuLanguageHelper;
     @Inject Lazy<HotspotController> mHotspotController;
     @Inject Lazy<CastController> mCastController;
     @Inject Lazy<FlashlightController> mFlashlightController;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index bce8784..1653e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 
 import com.android.systemui.ForegroundServicesDialog;
+import com.android.systemui.hdmi.HdmiCecSetMenuLanguageActivity;
 import com.android.systemui.keyguard.WorkLockActivity;
 import com.android.systemui.people.PeopleSpaceActivity;
 import com.android.systemui.people.widget.LaunchConversationActivity;
@@ -120,4 +121,11 @@
     @IntoMap
     @ClassKey(TvUnblockSensorActivity.class)
     public abstract Activity bindTvUnblockSensorActivity(TvUnblockSensorActivity activity);
+
+    /** Inject into HdmiCecSetMenuLanguageActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(HdmiCecSetMenuLanguageActivity.class)
+    public abstract Activity bindHdmiCecSetMenuLanguageActivity(
+            HdmiCecSetMenuLanguageActivity activity);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageActivity.java b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageActivity.java
new file mode 100644
index 0000000..b304c3c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageActivity.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.systemui.hdmi;
+
+import android.hardware.hdmi.HdmiControlManager;
+import android.os.Bundle;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.tv.TvBottomSheetActivity;
+
+import javax.inject.Inject;
+
+/**
+ * Confirmation dialog shown when Set Menu Language CEC message was received.
+ */
+public class HdmiCecSetMenuLanguageActivity extends TvBottomSheetActivity
+        implements View.OnClickListener {
+    private static final String TAG = HdmiCecSetMenuLanguageActivity.class.getSimpleName();
+
+    private final HdmiCecSetMenuLanguageHelper mHdmiCecSetMenuLanguageHelper;
+
+    @Inject
+    public HdmiCecSetMenuLanguageActivity(
+            HdmiCecSetMenuLanguageHelper hdmiCecSetMenuLanguageHelper) {
+        mHdmiCecSetMenuLanguageHelper = hdmiCecSetMenuLanguageHelper;
+    }
+
+    @Override
+    public final void onCreate(Bundle b) {
+        super.onCreate(b);
+        getWindow().addPrivateFlags(
+                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        String languageTag = getIntent().getStringExtra(HdmiControlManager.EXTRA_LOCALE);
+        mHdmiCecSetMenuLanguageHelper.setLocale(languageTag);
+        if (mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()) {
+            finish();
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        CharSequence title = getString(R.string.hdmi_cec_set_menu_language_title,
+                mHdmiCecSetMenuLanguageHelper.getLocale().getDisplayLanguage());
+        CharSequence text = getString(R.string.hdmi_cec_set_menu_language_description);
+        initUI(title, text);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.bottom_sheet_positive_button) {
+            mHdmiCecSetMenuLanguageHelper.acceptLocale();
+        } else {
+            mHdmiCecSetMenuLanguageHelper.declineLocale();
+        }
+        finish();
+    }
+
+    void initUI(CharSequence title, CharSequence text) {
+        TextView titleTextView = findViewById(R.id.bottom_sheet_title);
+        TextView contentTextView = findViewById(R.id.bottom_sheet_body);
+        ImageView icon = findViewById(R.id.bottom_sheet_icon);
+        ImageView secondIcon = findViewById(R.id.bottom_sheet_second_icon);
+        Button okButton = findViewById(R.id.bottom_sheet_positive_button);
+        Button cancelButton = findViewById(R.id.bottom_sheet_negative_button);
+
+        titleTextView.setText(title);
+        contentTextView.setText(text);
+        icon.setImageResource(com.android.internal.R.drawable.ic_settings_language);
+        secondIcon.setVisibility(View.GONE);
+
+        okButton.setText(R.string.hdmi_cec_set_menu_language_accept);
+        okButton.setOnClickListener(this);
+
+        cancelButton.setText(R.string.hdmi_cec_set_menu_language_decline);
+        cancelButton.setOnClickListener(this);
+        cancelButton.requestFocus();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java
new file mode 100644
index 0000000..1f58112
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelper.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.systemui.hdmi;
+
+import android.provider.Settings;
+
+import com.android.internal.app.LocalePicker;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.util.settings.SecureSettings;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Helper class to separate model and view for system language change initiated by HDMI CEC.
+ */
+@SysUISingleton
+public class HdmiCecSetMenuLanguageHelper {
+    private static final String TAG = HdmiCecSetMenuLanguageHelper.class.getSimpleName();
+    private static final String SEPARATOR = ",";
+
+    private final Executor mBackgroundExecutor;
+    private final SecureSettings mSecureSettings;
+
+    private Locale mLocale;
+    private HashSet<String> mDenylist;
+
+    @Inject
+    public HdmiCecSetMenuLanguageHelper(@Background Executor executor,
+            SecureSettings secureSettings) {
+        mBackgroundExecutor = executor;
+        mSecureSettings = secureSettings;
+        String denylist = mSecureSettings.getString(
+                Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST);
+        mDenylist = new HashSet<>(denylist == null
+                ? Collections.EMPTY_SET
+                : Arrays.asList(denylist.split(SEPARATOR)));
+    }
+
+    /**
+     * Set internal locale based on given language tag.
+     */
+    public void setLocale(String languageTag) {
+        mLocale = Locale.forLanguageTag(languageTag);
+    }
+
+    /**
+     * Returns the locale from {@code <Set Menu Language>} CEC message.
+     */
+    public Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * Returns whether the locale from {@code <Set Menu Language>} CEC message was already
+     * denylisted.
+     */
+    public boolean isLocaleDenylisted() {
+        return mDenylist.contains(mLocale.toLanguageTag());
+    }
+
+    /**
+     * Accepts the new locale and updates system language.
+     */
+    public void acceptLocale() {
+        mBackgroundExecutor.execute(() -> LocalePicker.updateLocale(mLocale));
+    }
+
+    /**
+     * Declines the locale and puts it on the denylist.
+     */
+    public void declineLocale() {
+        mDenylist.add(mLocale.toLanguageTag());
+        mSecureSettings.putString(Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST,
+                String.join(SEPARATOR, mDenylist));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java
new file mode 100644
index 0000000..1171bd2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/hdmi/HdmiCecSetMenuLanguageHelperTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.systemui.hdmi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.provider.Settings;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.settings.SecureSettings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Locale;
+import java.util.concurrent.Executor;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class HdmiCecSetMenuLanguageHelperTest extends SysuiTestCase {
+
+    private HdmiCecSetMenuLanguageHelper mHdmiCecSetMenuLanguageHelper;
+
+    @Mock
+    private Executor mExecutor;
+
+    @Mock
+    private SecureSettings mSecureSettings;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mSecureSettings.getString(
+                Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST)).thenReturn(null);
+        mHdmiCecSetMenuLanguageHelper =
+                new HdmiCecSetMenuLanguageHelper(mExecutor, mSecureSettings);
+    }
+
+    @Test
+    public void testSetGetLocale() {
+        mHdmiCecSetMenuLanguageHelper.setLocale("en");
+        assertThat(mHdmiCecSetMenuLanguageHelper.getLocale()).isEqualTo(Locale.ENGLISH);
+    }
+
+    @Test
+    public void testIsLocaleDenylisted_EmptyByDefault() {
+        mHdmiCecSetMenuLanguageHelper.setLocale("en");
+        assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(false);
+    }
+
+    @Test
+    public void testIsLocaleDenylisted_AcceptLanguage() {
+        mHdmiCecSetMenuLanguageHelper.setLocale("de");
+        mHdmiCecSetMenuLanguageHelper.acceptLocale();
+        assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(false);
+        verify(mExecutor).execute(any());
+    }
+
+    @Test
+    public void testIsLocaleDenylisted_DeclineLanguage() {
+        mHdmiCecSetMenuLanguageHelper.setLocale("de");
+        mHdmiCecSetMenuLanguageHelper.declineLocale();
+        assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true);
+        verify(mSecureSettings).putString(
+                Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de");
+    }
+
+    @Test
+    public void testIsLocaleDenylisted_DeclineTwoLanguages() {
+        mHdmiCecSetMenuLanguageHelper.setLocale("de");
+        mHdmiCecSetMenuLanguageHelper.declineLocale();
+        assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true);
+        verify(mSecureSettings).putString(
+                Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de");
+        mHdmiCecSetMenuLanguageHelper.setLocale("pl");
+        mHdmiCecSetMenuLanguageHelper.declineLocale();
+        assertThat(mHdmiCecSetMenuLanguageHelper.isLocaleDenylisted()).isEqualTo(true);
+        verify(mSecureSettings).putString(
+                Settings.Secure.HDMI_CEC_SET_MENU_LANGUAGE_DENYLIST, "de,pl");
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index b23395f..f413fbd 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -17,10 +17,15 @@
 package com.android.server.hdmi;
 
 import android.annotation.CallSuper;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
@@ -408,7 +413,7 @@
                     // locale from being chosen. 'eng' in the CEC command, for instance,
                     // will always be mapped to en-AU among other variants like en-US, en-GB,
                     // an en-IN, which may not be the expected one.
-                    LocalePicker.updateLocale(localeInfo.getLocale());
+                    startSetMenuLanguageActivity(localeInfo.getLocale());
                     return Constants.HANDLED;
                 }
             }
@@ -420,6 +425,24 @@
         }
     }
 
+    private void startSetMenuLanguageActivity(Locale locale) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Context context = mService.getContext();
+            Intent intent = new Intent();
+            intent.putExtra(HdmiControlManager.EXTRA_LOCALE, locale.toLanguageTag());
+            intent.setComponent(
+                    ComponentName.unflattenFromString(context.getResources().getString(
+                            com.android.internal.R.string.config_hdmiCecSetMenuLanguageActivity)));
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivityAsUser(intent, context.getUser());
+        } catch (ActivityNotFoundException e) {
+            Slog.e(TAG, "unable to start HdmiCecSetMenuLanguageActivity");
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Override
     @Constants.HandleMessageResult
     protected int handleSetSystemAudioMode(HdmiCecMessage message) {