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

Commit 2659074d authored by danielwbhuang's avatar danielwbhuang Committed by Daniel Huang
Browse files

Handling multiple profiles for PK layout selection

1. Use new @hide IMM#getEnabledInputMethodSubtypeListAsUser()
2. Use ProfileSelectFragment

Demo: https://screencast.googleplex.com/cast/NjMzNTA2NTA2NDczNDcyMHwxNTUyMjQ1ZS03YQ

Bug: 275106096
Test: manual
Change-Id: I51cfd16fc7162e2b24782017b9366b0aad36f915
parent b232ba29
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
import com.android.settings.inputmethod.NewKeyboardLayoutEnabledLocalesFragment;
import com.android.settings.location.LocationServices;

import java.util.Map;
@@ -49,5 +50,7 @@ public class ProfileFragmentBridge {
                ProfileSelectStorageFragment.class.getName());
        FRAGMENT_MAP.put(AvailableVirtualKeyboardFragment.class.getName(),
                ProfileSelectKeyboardFragment.class.getName());
        FRAGMENT_MAP.put(NewKeyboardLayoutEnabledLocalesFragment.class.getName(),
                ProfileSelectPhysicalKeyboardFragment.class.getName());
    }
}
+72 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

package com.android.settings.dashboard.profileselector;

import android.hardware.input.InputDeviceIdentifier;
import android.os.Bundle;
import android.provider.Settings;

import androidx.fragment.app.Fragment;

import com.android.settings.R;
import com.android.settings.inputmethod.NewKeyboardLayoutEnabledLocalesFragment;

/**
 * When current user has work profile, this fragment used following fragments to represent the
 * enabled IMEs keyboard layout settings page.
 *
 * <p>{@link NewKeyboardLayoutEnabledLocalesFragment} used to show both of personal/work user
 * enabled IMEs and their physical keyboard layouts.</p>
 */
public final class ProfileSelectPhysicalKeyboardFragment extends ProfileSelectFragment {

    private InputDeviceIdentifier mInputDeviceIdentifier;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        Bundle arguments = getArguments();
        mInputDeviceIdentifier =
                arguments.getParcelable(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER);
    }

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.keyboard_settings_enabled_locales_list;
    }

    @Override
    public Fragment[] getFragments() {
        final Bundle personalOnly = new Bundle();
        personalOnly.putInt(EXTRA_PROFILE, ProfileType.PERSONAL);
        final Fragment personalFragment = new NewKeyboardLayoutEnabledLocalesFragment();
        personalOnly.putParcelable(
                Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, mInputDeviceIdentifier);
        personalFragment.setArguments(personalOnly);

        final Bundle workOnly = new Bundle();
        workOnly.putInt(EXTRA_PROFILE, ProfileType.WORK);
        final Fragment workFragment = new NewKeyboardLayoutEnabledLocalesFragment();
        workOnly.putParcelable(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, mInputDeviceIdentifier);
        workFragment.setArguments(workOnly);

        return new Fragment[]{
                personalFragment,
                workFragment
        };
    }
}
+63 −37
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodInfo;
@@ -34,8 +35,10 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.inputmethod.NewKeyboardSettingsUtils.KeyboardInfo;

import java.util.ArrayList;
@@ -56,6 +59,39 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
    private Context mContext;
    private ArrayList<KeyboardInfo> mKeyboardInfoList = new ArrayList<>();

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        mContext = context;
        final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
        final int currentUserId = UserHandle.myUserId();
        final int newUserId;
        final UserManager userManager = mContext.getSystemService(UserManager.class);

        switch (profileType) {
            case ProfileSelectFragment.ProfileType.WORK: {
                // If the user is a managed profile user, use currentUserId directly. Or get the
                // managed profile userId instead.
                newUserId = userManager.isManagedProfile()
                        ? currentUserId : Utils.getManagedProfileId(userManager, currentUserId);
                break;
            }
            case ProfileSelectFragment.ProfileType.PERSONAL: {
                final UserHandle primaryUser = userManager.getPrimaryUser().getUserHandle();
                newUserId = primaryUser.getIdentifier();
                break;
            }
            default:
                newUserId = currentUserId;
        }

        mUserId = newUserId;
        mIm = mContext.getSystemService(InputManager.class);
        mImm = mContext.getSystemService(InputMethodManager.class);
        mInputDeviceId = -1;
    }

    @Override
    public void onActivityCreated(final Bundle icicle) {
        super.onActivityCreated(icicle);
@@ -74,13 +110,39 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
        }
        final String title = inputDevice.getName();
        getActivity().setTitle(title);
    }

    @Override
    public void onStart() {
        super.onStart();
        mIm.registerInputDeviceListener(this, null);
        InputDevice inputDevice =
                NewKeyboardSettingsUtils.getInputDevice(mIm, mInputDeviceIdentifier);
        if (inputDevice == null) {
            getActivity().finish();
            return;
        }
        mInputDeviceId = inputDevice.getId();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateCheckedState();
    }

    @Override
    public void onStop() {
        super.onStop();
        mIm.unregisterInputDeviceListener(this);
        mInputDeviceId = -1;
    }

    private void updateCheckedState() {
        if (NewKeyboardSettingsUtils.getInputDevice(mIm, mInputDeviceIdentifier) == null) {
            return;
        }

        PreferenceScreen preferenceScreen = getPreferenceScreen();
        preferenceScreen.removeAll();
        List<InputMethodInfo> infoList = mImm.getEnabledInputMethodListAsUser(mUserId);
@@ -95,7 +157,7 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
        for (InputMethodInfo info : infoList) {
            mKeyboardInfoList.clear();
            List<InputMethodSubtype> subtypes =
                    mImm.getEnabledInputMethodSubtypeList(info, true);
                    mImm.getEnabledInputMethodSubtypeListAsUser(info.getId(), true, mUserId);
            for (InputMethodSubtype subtype : subtypes) {
                if (subtype.isSuitableForPhysicalKeyboardLayoutMapping()) {
                    mapLanguageWithLayout(info, subtype);
@@ -188,42 +250,6 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getContext();
        mIm = mContext.getSystemService(InputManager.class);
        mImm = mContext.getSystemService(InputMethodManager.class);
        mInputDeviceId = -1;
        mUserId = UserHandle.myUserId();
    }

    @Override
    public void onStart() {
        super.onStart();
        mIm.registerInputDeviceListener(this, null);
        InputDevice inputDevice =
                NewKeyboardSettingsUtils.getInputDevice(mIm, mInputDeviceIdentifier);
        if (inputDevice == null) {
            getActivity().finish();
            return;
        }
        mInputDeviceId = inputDevice.getId();
    }

    @Override
    public void onStop() {
        super.onStop();
        mIm.unregisterInputDeviceListener(this);
        mInputDeviceId = -1;
    }

    @Override
    public void onResume() {
        super.onResume();
        updateCheckedState();
    }

    @Override
    protected String getLogTag() {
        return TAG;