Show Physical keyboards only after everything has been loaded

This patch loads all physical keyboards at once and only updates the
screen after that returns. Previously, each keyboard's data was
loaded individually and the screen was updated for each keyboard
when the data was received.

Bug: 27549590
Change-Id: I05d80d74df14fb7bfaa0ce76a1f8919889865108
This commit is contained in:
Abodunrinwa Toki
2016-04-11 11:30:30 +01:00
parent 77359ad761
commit 6118469cae

View File

@@ -54,6 +54,7 @@ import libcore.util.Objects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
implements InputManager.InputDeviceListener { implements InputManager.InputDeviceListener {
@@ -64,7 +65,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
private static final String IM_SUBTYPE_MODE_KEYBOARD = "keyboard"; private static final String IM_SUBTYPE_MODE_KEYBOARD = "keyboard";
@NonNull @NonNull
private final ArrayList<HardKeyboardDeviceInfo> mLastHardKeyboards = new ArrayList<>(); private final List<HardKeyboardDeviceInfo> mLastHardKeyboards = new ArrayList<>();
@NonNull @NonNull
private final HashSet<Integer> mLoaderIDs = new HashSet<>(); private final HashSet<Integer> mLoaderIDs = new HashSet<>();
@@ -119,32 +120,42 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
unregisterShowVirtualKeyboardSettingsObserver(); unregisterShowVirtualKeyboardSettingsObserver();
} }
public void onLoadFinishedInternal(final int loaderId, @NonNull final Keyboards data, public void onLoadFinishedInternal(
@NonNull final PreferenceCategory preferenceCategory) { final int loaderId, @NonNull final List<Keyboards> keyboardsList) {
if (!mLoaderIDs.remove(loaderId)) { if (!mLoaderIDs.remove(loaderId)) {
// Already destroyed loader. Ignore. // Already destroyed loader. Ignore.
return; return;
} }
final InputDeviceIdentifier deviceId = data.mInputDeviceIdentifier; final PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceCategory.removeAll(); preferenceScreen.removeAll();
for (Keyboards.KeyboardInfo info : data.mKeyboardInfoList) { for (Keyboards keyboards : keyboardsList) {
Preference pref = new Preference(getPrefContext(), null); final PreferenceCategory category = new PreferenceCategory(getPrefContext(), null);
final InputMethodInfo imi = info.mImi; category.setTitle(keyboards.mDeviceInfo.mDeviceName);
final InputMethodSubtype imSubtype = info.mImSubtype; category.setOrder(0);
if (imi != null && imSubtype != null) { preferenceScreen.addPreference(category);
pref.setTitle(getDisplayName(getContext(), imi, imSubtype)); for (Keyboards.KeyboardInfo info : keyboards.mKeyboardInfoList) {
KeyboardLayout layout = info.mLayout; Preference pref = new Preference(getPrefContext(), null);
if (layout != null) { final InputMethodInfo imi = info.mImi;
pref.setSummary(layout.getLabel()); final InputMethodSubtype imSubtype = info.mImSubtype;
if (imi != null && imSubtype != null) {
pref.setTitle(getDisplayName(getContext(), imi, imSubtype));
KeyboardLayout layout = info.mLayout;
if (layout != null) {
pref.setSummary(layout.getLabel());
}
pref.setOnPreferenceClickListener(preference -> {
showKeyboardLayoutScreen(
keyboards.mDeviceInfo.mDeviceIdentifier, imi, imSubtype);
return true;
});
category.addPreference(pref);
} }
pref.setOnPreferenceClickListener(preference -> {
showKeyboardLayoutScreen(deviceId, imi, imSubtype);
return true;
});
preferenceCategory.addPreference(pref);
} }
} }
mKeyboardAssistanceCategory.setOrder(1);
preferenceScreen.addPreference(mKeyboardAssistanceCategory);
updateShowVirtualKeyboardSwitch();
} }
@Override @Override
@@ -184,27 +195,13 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
final ArrayList<HardKeyboardDeviceInfo> newHardKeyboards = getHardKeyboards(); final ArrayList<HardKeyboardDeviceInfo> newHardKeyboards = getHardKeyboards();
if (!Objects.equal(newHardKeyboards, mLastHardKeyboards)) { if (!Objects.equal(newHardKeyboards, mLastHardKeyboards)) {
clearLoader(); clearLoader();
final PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.removeAll();
mLastHardKeyboards.clear(); mLastHardKeyboards.clear();
mLastHardKeyboards.addAll(newHardKeyboards); mLastHardKeyboards.addAll(newHardKeyboards);
final int N = newHardKeyboards.size(); getLoaderManager().initLoader(mNextLoaderId, null,
for (int i = 0; i < N; ++i) { new Callbacks(getContext(), this, mLastHardKeyboards));
final HardKeyboardDeviceInfo deviceInfo = newHardKeyboards.get(i); mLoaderIDs.add(mNextLoaderId);
final PreferenceCategory category = new PreferenceCategory(getPrefContext(), null); ++mNextLoaderId;
category.setTitle(deviceInfo.mDeviceName);
category.setOrder(0);
getLoaderManager().initLoader(mNextLoaderId, null,
new Callbacks(getContext(), this, deviceInfo.mDeviceIdentifier, category));
mLoaderIDs.add(mNextLoaderId);
++mNextLoaderId;
preferenceScreen.addPreference(category);
}
mKeyboardAssistanceCategory.setOrder(1);
preferenceScreen.addPreference(mKeyboardAssistanceCategory);
} }
updateShowVirtualKeyboardSwitch();
} }
private void showKeyboardLayoutScreen( private void showKeyboardLayoutScreen(
@@ -272,56 +269,49 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
context.getString(R.string.physical_device_title), imSubtypeName, imeName); context.getString(R.string.physical_device_title), imSubtypeName, imeName);
} }
private static final class Callbacks private static final class Callbacks implements LoaderManager.LoaderCallbacks<List<Keyboards>> {
implements LoaderManager.LoaderCallbacks<PhysicalKeyboardFragment.Keyboards> {
@NonNull @NonNull
final Context mContext; final Context mContext;
@NonNull @NonNull
final PhysicalKeyboardFragment mPhysicalKeyboardFragment; final PhysicalKeyboardFragment mPhysicalKeyboardFragment;
@NonNull @NonNull
final InputDeviceIdentifier mInputDeviceIdentifier; final List<HardKeyboardDeviceInfo> mHardKeyboards;
@NonNull
final PreferenceCategory mPreferenceCategory;
public Callbacks( public Callbacks(
@NonNull Context context, @NonNull Context context,
@NonNull PhysicalKeyboardFragment physicalKeyboardFragment, @NonNull PhysicalKeyboardFragment physicalKeyboardFragment,
@NonNull InputDeviceIdentifier inputDeviceIdentifier, @NonNull List<HardKeyboardDeviceInfo> hardKeyboards) {
@NonNull PreferenceCategory preferenceCategory) {
mContext = context; mContext = context;
mPhysicalKeyboardFragment = physicalKeyboardFragment; mPhysicalKeyboardFragment = physicalKeyboardFragment;
mInputDeviceIdentifier = inputDeviceIdentifier; mHardKeyboards = hardKeyboards;
mPreferenceCategory = preferenceCategory;
} }
@Override @Override
public Loader<Keyboards> onCreateLoader(int id, Bundle args) { public Loader<List<Keyboards>> onCreateLoader(int id, Bundle args) {
return new KeyboardLayoutLoader(mContext, mInputDeviceIdentifier); return new KeyboardLayoutLoader(mContext, mHardKeyboards);
} }
@Override @Override
public void onLoadFinished(Loader<Keyboards> loader, Keyboards data) { public void onLoadFinished(Loader<List<Keyboards>> loader, List<Keyboards> data) {
mPhysicalKeyboardFragment.onLoadFinishedInternal(loader.getId(), data, mPhysicalKeyboardFragment.onLoadFinishedInternal(loader.getId(), data);
mPreferenceCategory);
} }
@Override @Override
public void onLoaderReset(Loader<Keyboards> loader) { public void onLoaderReset(Loader<List<Keyboards>> loader) {
} }
} }
private static final class KeyboardLayoutLoader extends AsyncTaskLoader<Keyboards> { private static final class KeyboardLayoutLoader extends AsyncTaskLoader<List<Keyboards>> {
@NonNull @NonNull
private final InputDeviceIdentifier mInputDeviceIdentifier; private final List<HardKeyboardDeviceInfo> mHardKeyboards;
public KeyboardLayoutLoader( public KeyboardLayoutLoader(
@NonNull Context context, @NonNull Context context,
@NonNull InputDeviceIdentifier inputDeviceIdentifier) { @NonNull List<HardKeyboardDeviceInfo> hardKeyboards) {
super(context); super(context);
mInputDeviceIdentifier = Preconditions.checkNotNull(inputDeviceIdentifier); mHardKeyboards = Preconditions.checkNotNull(hardKeyboards);
} }
@Override private Keyboards loadInBackground(HardKeyboardDeviceInfo deviceInfo) {
public Keyboards loadInBackground() {
final ArrayList<Keyboards.KeyboardInfo> keyboardInfoList = new ArrayList<>(); final ArrayList<Keyboards.KeyboardInfo> keyboardInfoList = new ArrayList<>();
final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class); final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
final InputManager im = getContext().getSystemService(InputManager.class); final InputManager im = getContext().getSystemService(InputManager.class);
@@ -333,12 +323,21 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
continue; continue;
} }
final KeyboardLayout layout = im.getKeyboardLayoutForInputDevice( final KeyboardLayout layout = im.getKeyboardLayoutForInputDevice(
mInputDeviceIdentifier, imi, subtype); deviceInfo.mDeviceIdentifier, imi, subtype);
keyboardInfoList.add(new Keyboards.KeyboardInfo(imi, subtype, layout)); keyboardInfoList.add(new Keyboards.KeyboardInfo(imi, subtype, layout));
} }
} }
} }
return new Keyboards(mInputDeviceIdentifier, keyboardInfoList); return new Keyboards(deviceInfo, keyboardInfoList);
}
@Override
public List<Keyboards> loadInBackground() {
List<Keyboards> keyboardsList = new ArrayList<>(mHardKeyboards.size());
for (HardKeyboardDeviceInfo deviceInfo : mHardKeyboards) {
keyboardsList.add(loadInBackground(deviceInfo));
}
return keyboardsList;
} }
@Override @Override
@@ -395,14 +394,14 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
public static final class Keyboards { public static final class Keyboards {
@NonNull @NonNull
public final InputDeviceIdentifier mInputDeviceIdentifier; public final HardKeyboardDeviceInfo mDeviceInfo;
@NonNull @NonNull
public final ArrayList<KeyboardInfo> mKeyboardInfoList; public final ArrayList<KeyboardInfo> mKeyboardInfoList;
public Keyboards( public Keyboards(
@NonNull final InputDeviceIdentifier inputDeviceIdentifier, @NonNull final HardKeyboardDeviceInfo deviceInfo,
@NonNull final ArrayList<KeyboardInfo> keyboardInfoList) { @NonNull final ArrayList<KeyboardInfo> keyboardInfoList) {
mInputDeviceIdentifier = inputDeviceIdentifier; mDeviceInfo = deviceInfo;
mKeyboardInfoList = keyboardInfoList; mKeyboardInfoList = keyboardInfoList;
} }