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

Commit ba7df2f0 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Android (Google) Code Review
Browse files

Merge "Don't show keyboard configured notification for Virtual device" into main

parents 8087ef78 20e49a48
Loading
Loading
Loading
Loading
+39 −11
Original line number Original line Diff line number Diff line
@@ -76,6 +76,8 @@ import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.input.KeyboardMetricsCollector.KeyboardConfigurationEvent;
import com.android.server.input.KeyboardMetricsCollector.KeyboardConfigurationEvent;
import com.android.server.input.KeyboardMetricsCollector.LayoutSelectionCriteria;
import com.android.server.input.KeyboardMetricsCollector.LayoutSelectionCriteria;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -197,7 +199,7 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
        final KeyboardIdentifier keyboardIdentifier = new KeyboardIdentifier(inputDevice);
        final KeyboardIdentifier keyboardIdentifier = new KeyboardIdentifier(inputDevice);
        KeyboardConfiguration config = mConfiguredKeyboards.get(deviceId);
        KeyboardConfiguration config = mConfiguredKeyboards.get(deviceId);
        if (config == null) {
        if (config == null) {
            config = new KeyboardConfiguration();
            config = new KeyboardConfiguration(deviceId);
            mConfiguredKeyboards.put(deviceId, config);
            mConfiguredKeyboards.put(deviceId, config);
        }
        }


@@ -1093,19 +1095,26 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {


    @MainThread
    @MainThread
    private void maybeUpdateNotification() {
    private void maybeUpdateNotification() {
        if (mConfiguredKeyboards.size() == 0) {
        List<KeyboardConfiguration> configurations = new ArrayList<>();
            hideKeyboardLayoutNotification();
            return;
        }
        for (int i = 0; i < mConfiguredKeyboards.size(); i++) {
        for (int i = 0; i < mConfiguredKeyboards.size(); i++) {
            int deviceId = mConfiguredKeyboards.keyAt(i);
            KeyboardConfiguration config = mConfiguredKeyboards.valueAt(i);
            if (isVirtualDevice(deviceId)) {
                continue;
            }
            // If we have a keyboard with no selected layouts, we should always show missing
            // If we have a keyboard with no selected layouts, we should always show missing
            // layout notification even if there are other keyboards that are configured properly.
            // layout notification even if there are other keyboards that are configured properly.
            if (!mConfiguredKeyboards.valueAt(i).hasConfiguredLayouts()) {
            if (!config.hasConfiguredLayouts()) {
                showMissingKeyboardLayoutNotification();
                showMissingKeyboardLayoutNotification();
                return;
                return;
            }
            }
            configurations.add(config);
        }
        }
        showConfiguredKeyboardLayoutNotification();
        if (configurations.size() == 0) {
            hideKeyboardLayoutNotification();
            return;
        }
        showConfiguredKeyboardLayoutNotification(configurations);
    }
    }


    @MainThread
    @MainThread
@@ -1185,10 +1194,11 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
    }
    }


    @MainThread
    @MainThread
    private void showConfiguredKeyboardLayoutNotification() {
    private void showConfiguredKeyboardLayoutNotification(
            List<KeyboardConfiguration> configurations) {
        final Resources r = mContext.getResources();
        final Resources r = mContext.getResources();


        if (mConfiguredKeyboards.size() != 1) {
        if (configurations.size() != 1) {
            showKeyboardLayoutNotification(
            showKeyboardLayoutNotification(
                    r.getString(R.string.keyboard_layout_notification_multiple_selected_title),
                    r.getString(R.string.keyboard_layout_notification_multiple_selected_title),
                    r.getString(R.string.keyboard_layout_notification_multiple_selected_message),
                    r.getString(R.string.keyboard_layout_notification_multiple_selected_message),
@@ -1196,8 +1206,8 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
            return;
            return;
        }
        }


        final InputDevice inputDevice = getInputDevice(mConfiguredKeyboards.keyAt(0));
        final KeyboardConfiguration config = configurations.get(0);
        final KeyboardConfiguration config = mConfiguredKeyboards.valueAt(0);
        final InputDevice inputDevice = getInputDevice(config.getDeviceId());
        if (inputDevice == null || !config.hasConfiguredLayouts()) {
        if (inputDevice == null || !config.hasConfiguredLayouts()) {
            return;
            return;
        }
        }
@@ -1356,6 +1366,13 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
        return false;
        return false;
    }
    }


    @VisibleForTesting
    public boolean isVirtualDevice(int deviceId) {
        VirtualDeviceManagerInternal vdm = LocalServices.getService(
                VirtualDeviceManagerInternal.class);
        return vdm == null || vdm.isInputDeviceOwnedByVirtualDevice(deviceId);
    }

    private static int[] getScriptCodes(@Nullable Locale locale) {
    private static int[] getScriptCodes(@Nullable Locale locale) {
        if (locale == null) {
        if (locale == null) {
            return new int[0];
            return new int[0];
@@ -1430,11 +1447,22 @@ class KeyboardLayoutManager implements InputManager.InputDeviceListener {
    }
    }


    private static class KeyboardConfiguration {
    private static class KeyboardConfiguration {

        // If null or empty, it means no layout is configured for the device. And user needs to
        // If null or empty, it means no layout is configured for the device. And user needs to
        // manually set up the device.
        // manually set up the device.
        @Nullable
        @Nullable
        private Set<String> mConfiguredLayouts;
        private Set<String> mConfiguredLayouts;


        private final int mDeviceId;

        private KeyboardConfiguration(int deviceId) {
            mDeviceId = deviceId;
        }

        private int getDeviceId() {
            return mDeviceId;
        }

        private boolean hasConfiguredLayouts() {
        private boolean hasConfiguredLayouts() {
            return mConfiguredLayouts != null && !mConfiguredLayouts.isEmpty();
            return mConfiguredLayouts != null && !mConfiguredLayouts.isEmpty();
        }
        }
+47 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.input
package com.android.server.input


import android.app.NotificationManager
import android.content.Context
import android.content.Context
import android.content.ContextWrapper
import android.content.ContextWrapper
import android.content.pm.ActivityInfo
import android.content.pm.ActivityInfo
@@ -129,6 +130,8 @@ class KeyboardLayoutManagerTests {


    @Mock
    @Mock
    private lateinit var packageManager: PackageManager
    private lateinit var packageManager: PackageManager
    @Mock
    private lateinit var notificationManager: NotificationManager
    private lateinit var keyboardLayoutManager: KeyboardLayoutManager
    private lateinit var keyboardLayoutManager: KeyboardLayoutManager


    private lateinit var imeInfo: InputMethodInfo
    private lateinit var imeInfo: InputMethodInfo
@@ -163,6 +166,8 @@ class KeyboardLayoutManagerTests {
        keyboardLayoutManager = Mockito.spy(
        keyboardLayoutManager = Mockito.spy(
            KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
            KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
        )
        )
        Mockito.`when`(context.getSystemService(Mockito.eq(Context.NOTIFICATION_SERVICE)))
                .thenReturn(notificationManager)
        setupInputDevices()
        setupInputDevices()
        setupBroadcastReceiver()
        setupBroadcastReceiver()
        setupIme()
        setupIme()
@@ -946,6 +951,48 @@ class KeyboardLayoutManagerTests {
        }
        }
    }
    }


    @Test
    fun testNotificationShown_onInputDeviceChanged() {
        val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
        Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
        Mockito.doReturn(false).`when`(keyboardLayoutManager).isVirtualDevice(
            ArgumentMatchers.eq(keyboardDevice.id)
        )
        NewSettingsApiFlag(true).use {
            keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
            ExtendedMockito.verify(
                notificationManager,
                Mockito.times(1)
            ).notifyAsUser(
                ArgumentMatchers.isNull(),
                ArgumentMatchers.anyInt(),
                ArgumentMatchers.any(),
                ArgumentMatchers.any()
            )
        }
    }

    @Test
    fun testNotificationNotShown_onInputDeviceChanged_forVirtualDevice() {
        val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
        Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
        Mockito.doReturn(true).`when`(keyboardLayoutManager).isVirtualDevice(
            ArgumentMatchers.eq(keyboardDevice.id)
        )
        NewSettingsApiFlag(true).use {
            keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
            ExtendedMockito.verify(
                notificationManager,
                Mockito.never()
            ).notifyAsUser(
                ArgumentMatchers.isNull(),
                ArgumentMatchers.anyInt(),
                ArgumentMatchers.any(),
                ArgumentMatchers.any()
            )
        }
    }

    private fun assertCorrectLayout(
    private fun assertCorrectLayout(
        device: InputDevice,
        device: InputDevice,
        imeSubtype: InputMethodSubtype,
        imeSubtype: InputMethodSubtype,