Merge "Simplify ImeTargetChangeListener impl a bit" into main
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index f041f4d..083f1db 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -52,6 +52,7 @@
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HapClientProfile;
@@ -104,6 +105,7 @@
private final AudioManager mAudioManager;
private final LocalBluetoothProfileManager mProfileManager;
private final HapClientProfile mHapClientProfile;
+ private final UiEventLogger mUiEventLogger;
private HearingDevicesListAdapter mDeviceListAdapter;
private HearingDevicesPresetsController mPresetsController;
private Context mApplicationContext;
@@ -163,7 +165,8 @@
DialogTransitionAnimator dialogTransitionAnimator,
@Nullable LocalBluetoothManager localBluetoothManager,
@Main Handler handler,
- AudioManager audioManager) {
+ AudioManager audioManager,
+ UiEventLogger uiEventLogger) {
mApplicationContext = applicationContext;
mShowPairNewDevice = showPairNewDevice;
mSystemUIDialogFactory = systemUIDialogFactory;
@@ -174,6 +177,7 @@
mAudioManager = audioManager;
mProfileManager = localBluetoothManager.getProfileManager();
mHapClientProfile = mProfileManager.getHapClientProfile();
+ mUiEventLogger = uiEventLogger;
}
@Override
@@ -187,6 +191,7 @@
@Override
public void onDeviceItemGearClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_GEAR_CLICK);
dismissDialogIfExists();
Intent intent = new Intent(ACTION_BLUETOOTH_DEVICE_DETAILS);
Bundle bundle = new Bundle();
@@ -198,13 +203,21 @@
}
@Override
- public void onDeviceItemOnClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
+ public void onDeviceItemClicked(@NonNull DeviceItem deviceItem, @NonNull View view) {
CachedBluetoothDevice cachedBluetoothDevice = deviceItem.getCachedBluetoothDevice();
switch (deviceItem.getType()) {
- case ACTIVE_MEDIA_BLUETOOTH_DEVICE, CONNECTED_BLUETOOTH_DEVICE ->
- cachedBluetoothDevice.disconnect();
- case AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> cachedBluetoothDevice.setActive();
- case SAVED_BLUETOOTH_DEVICE -> cachedBluetoothDevice.connect();
+ case ACTIVE_MEDIA_BLUETOOTH_DEVICE, CONNECTED_BLUETOOTH_DEVICE -> {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_DISCONNECT);
+ cachedBluetoothDevice.disconnect();
+ }
+ case AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_SET_ACTIVE);
+ cachedBluetoothDevice.setActive();
+ }
+ case SAVED_BLUETOOTH_DEVICE -> {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_CONNECT);
+ cachedBluetoothDevice.connect();
+ }
}
}
@@ -262,6 +275,7 @@
if (mLocalBluetoothManager == null) {
return;
}
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_DIALOG_SHOW);
mPairButton = dialog.requireViewById(R.id.pair_new_device_button);
mDeviceList = dialog.requireViewById(R.id.device_list);
mPresetSpinner = dialog.requireViewById(R.id.preset_spinner);
@@ -341,12 +355,17 @@
}
});
+ // Refresh the spinner and setSelection(index, false) before setOnItemSelectedListener() to
+ // avoid extra onItemSelected() get called when first register the listener.
+ final List<BluetoothHapPresetInfo> presetInfos = mPresetsController.getAllPresetInfo();
+ final int activePresetIndex = mPresetsController.getActivePresetIndex();
+ refreshPresetInfoAdapter(presetInfos, activePresetIndex);
mPresetSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_PRESET_SELECT);
mPresetsController.selectPreset(
mPresetsController.getAllPresetInfo().get(position).getIndex());
- mPresetSpinner.setSelection(position);
}
@Override
@@ -354,9 +373,6 @@
// Do nothing
}
});
- final List<BluetoothHapPresetInfo> presetInfos = mPresetsController.getAllPresetInfo();
- final int activePresetIndex = mPresetsController.getActivePresetIndex();
- refreshPresetInfoAdapter(presetInfos, activePresetIndex);
mPresetSpinner.setVisibility(
(activeHearingDevice != null && activeHearingDevice.isConnectedHapClientDevice()
&& !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE);
@@ -365,6 +381,7 @@
private void setupPairNewDeviceButton(SystemUIDialog dialog, @Visibility int visibility) {
if (visibility == VISIBLE) {
mPairButton.setOnClickListener(v -> {
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_PAIR);
dismissDialogIfExists();
final Intent intent = new Intent(Settings.ACTION_HEARING_DEVICE_PAIRING_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
@@ -413,7 +430,7 @@
final int size = mPresetInfoAdapter.getCount();
for (int position = 0; position < size; position++) {
if (presetInfos.get(position).getIndex() == activePresetIndex) {
- mPresetSpinner.setSelection(position);
+ mPresetSpinner.setSelection(position, /* animate= */ false);
}
}
}
@@ -464,12 +481,15 @@
text.setText(item.getToolName());
Intent intent = item.getToolIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- view.setOnClickListener(
- v -> {
- dismissDialogIfExists();
- mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
- mDialogTransitionAnimator.createActivityTransitionController(view));
- });
+ view.setOnClickListener(v -> {
+ final String name = intent.getComponent() != null
+ ? intent.getComponent().flattenToString()
+ : intent.getPackage() + "/" + intent.getAction();
+ mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_RELATED_TOOL_CLICK, 0, name);
+ dismissDialogIfExists();
+ mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
+ mDialogTransitionAnimator.createActivityTransitionController(view));
+ });
return view;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
index 737805b..b46b8fe 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
@@ -96,7 +96,7 @@
* @param deviceItem bluetooth device item
* @param view the view that was clicked
*/
- void onDeviceItemOnClicked(@NonNull DeviceItem deviceItem, @NonNull View view);
+ void onDeviceItemClicked(@NonNull DeviceItem deviceItem, @NonNull View view);
}
private static class DeviceItemViewHolder extends RecyclerView.ViewHolder {
@@ -119,7 +119,7 @@
public void bindView(DeviceItem item, HearingDeviceItemCallback callback) {
mContainer.setEnabled(item.isEnabled());
- mContainer.setOnClickListener(view -> callback.onDeviceItemOnClicked(item, view));
+ mContainer.setOnClickListener(view -> callback.onDeviceItemClicked(item, view));
Integer backgroundResId = item.getBackground();
if (backgroundResId != null) {
mContainer.setBackground(mContext.getDrawable(item.getBackground()));
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.java
new file mode 100644
index 0000000..3fbe56e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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.accessibility.hearingaid;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+public enum HearingDevicesUiEvent implements UiEventLogger.UiEventEnum {
+
+ @UiEvent(doc = "Hearing devices dialog is shown")
+ HEARING_DEVICES_DIALOG_SHOW(1848),
+ @UiEvent(doc = "Pair new device")
+ HEARING_DEVICES_PAIR(1849),
+ @UiEvent(doc = "Connect to the device")
+ HEARING_DEVICES_CONNECT(1850),
+ @UiEvent(doc = "Disconnect from the device")
+ HEARING_DEVICES_DISCONNECT(1851),
+ @UiEvent(doc = "Set the device as active device")
+ HEARING_DEVICES_SET_ACTIVE(1852),
+ @UiEvent(doc = "Click on the device gear to enter device detail page")
+ HEARING_DEVICES_GEAR_CLICK(1853),
+ @UiEvent(doc = "Select a preset from preset spinner")
+ HEARING_DEVICES_PRESET_SELECT(1854),
+ @UiEvent(doc = "Click on related tool")
+ HEARING_DEVICES_RELATED_TOOL_CLICK(1856);
+
+ private final int mId;
+
+ HearingDevicesUiEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index 5ea5c21..d3b7d22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -52,6 +52,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -123,6 +124,8 @@
@Mock
private AudioManager mAudioManager;
@Mock
+ private UiEventLogger mUiEventLogger;
+ @Mock
private CachedBluetoothDevice mCachedDevice;
@Mock
private BluetoothDevice mDevice;
@@ -179,6 +182,7 @@
anyInt(), any());
assertThat(intentCaptor.getValue().getAction()).isEqualTo(
Settings.ACTION_HEARING_DEVICE_PAIRING_SETTINGS);
+ verify(mUiEventLogger).log(HearingDevicesUiEvent.HEARING_DEVICES_PAIR);
}
@Test
@@ -192,7 +196,7 @@
anyInt(), any());
assertThat(intentCaptor.getValue().getAction()).isEqualTo(
HearingDevicesDialogDelegate.ACTION_BLUETOOTH_DEVICE_DETAILS);
-
+ verify(mUiEventLogger).log(HearingDevicesUiEvent.HEARING_DEVICES_GEAR_CLICK);
}
@Test
@@ -200,9 +204,10 @@
setUpDeviceListDialog();
when(mHearingDeviceItem.getType()).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE);
- mDialogDelegate.onDeviceItemOnClicked(mHearingDeviceItem, new View(mContext));
+ mDialogDelegate.onDeviceItemClicked(mHearingDeviceItem, new View(mContext));
verify(mCachedDevice).disconnect();
+ verify(mUiEventLogger).log(HearingDevicesUiEvent.HEARING_DEVICES_DISCONNECT);
}
@Test
@@ -304,7 +309,8 @@
mDialogTransitionAnimator,
mLocalBluetoothManager,
new Handler(mTestableLooper.getLooper()),
- mAudioManager
+ mAudioManager,
+ mUiEventLogger
);
mDialog = mDialogDelegate.createDialog();
@@ -326,7 +332,8 @@
mDialogTransitionAnimator,
mLocalBluetoothManager,
new Handler(mTestableLooper.getLooper()),
- mAudioManager
+ mAudioManager,
+ mUiEventLogger
);
mDialog = mDialogDelegate.createDialog();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d9bc467..8d652ef 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1126,6 +1126,21 @@
}
});
}
+
+ @Override
+ public void onUserStopped(@NonNull TargetUser user) {
+ final int userId = user.getUserIdentifier();
+ // Called on ActivityManager thread.
+ SecureSettingsWrapper.onUserStopped(userId);
+ mService.mIoHandler.post(() -> {
+ final var additionalSubtypeMap = AdditionalSubtypeMapRepository.get(userId);
+ final var settings = InputMethodManagerService.queryInputMethodServicesInternal(
+ mService.mContext, userId, additionalSubtypeMap,
+ DirectBootAwareness.AUTO).getMethodMap();
+ InputMethodSettingsRepository.put(userId,
+ InputMethodSettings.create(settings, userId));
+ });
+ }
}
@GuardedBy("ImfLock.class")
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
index c208a5b..476888e 100644
--- a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
@@ -377,6 +377,23 @@
}
/**
+ * Called when a user is stopped, which changes the user storage to the locked state again.
+ *
+ * @param userId the ID of the user whose storage is being locked again.
+ */
+ @AnyThread
+ static void onUserStopped(@UserIdInt int userId) {
+ final LockedUserImpl lockedUserImpl = new LockedUserImpl(userId, sContentResolver);
+ synchronized (sMutationLock) {
+ final ReaderWriter current = sUserMap.get(userId);
+ if (current == null || current instanceof LockedUserImpl) {
+ return;
+ }
+ sUserMap = sUserMap.cloneWithPutOrSelf(userId, lockedUserImpl);
+ }
+ }
+
+ /**
* Put the given string {@code value} to {@code key}.
*
* @param key a secure settings key.
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 4425079..a0d5ea8 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -501,9 +501,9 @@
mPm.setUpCustomResolverActivity(pkg, pkgSetting);
}
- // When upgrading a package, pkgSetting is copied from oldPkgSetting. Clear the app
- // metadata file path for the new package.
- if (oldPkgSetting != null) {
+ // When upgrading a package, clear the app metadata file path for the new package.
+ if (oldPkgSetting != null
+ && oldPkgSetting.getLastUpdateTime() < pkgSetting.getLastUpdateTime()) {
pkgSetting.setAppMetadataFilePath(null);
pkgSetting.setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN);
}