Merge "freezer: add internal per-process callbacks" into main
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 22804a2..0c786cb 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -29,6 +29,7 @@
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastPrintWriter;
import java.lang.annotation.Retention;
@@ -1260,7 +1261,7 @@
}
public void autoCork() {
- if (Looper.getMainLooper() == null) {
+ if (getLooper() == null) {
// We're not ready to auto-cork yet, so just invalidate the cache immediately.
if (DEBUG) {
Log.w(TAG, "invalidating instead of autocorking early in init: "
@@ -1322,7 +1323,7 @@
@GuardedBy("mLock")
private Handler getHandlerLocked() {
if (mHandler == null) {
- mHandler = new Handler(Looper.getMainLooper()) {
+ mHandler = new Handler(getLooper()) {
@Override
public void handleMessage(Message msg) {
AutoCorker.this.handleMessage(msg);
@@ -1331,6 +1332,14 @@
}
return mHandler;
}
+
+ /**
+ * Return a looper for auto-uncork messages. Messages should be processed on the
+ * background thread, not on the main thread.
+ */
+ private static Looper getLooper() {
+ return BackgroundThread.getHandler().getLooper();
+ }
}
/**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index af0272e..df288f9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3065,10 +3065,13 @@
frameworks/base/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java -->
<integer name="config_userTypePackageWhitelistMode">13</integer> <!-- 1+4+8 -->
- <!-- Whether the main user is a permanent admin user. If the main user is a permanent admin user
- it can't be deleted or downgraded to non-admin status.
- This is generally only relevant on headless system user mode devices; on other devices, the
- main user is the system user which is always a permanent admin anyway. -->
+ <!-- Whether the device will automatically (at first boot) have a designated main user and treat
+ it as a permanent admin.
+ Since the main user is a permanent admin user it can't be deleted or downgraded to
+ non-admin status.
+ This is generally only relevant on headless system user mode (HSUM) devices; on other
+ devices, the main user is the system user which is always a permanent admin anyway.
+ Note that HSUM devices without this enabled will not automatically have a main user. -->
<bool name="config_isMainUserPermanentAdmin">true</bool>
<!-- Whether switch to headless system user is allowed. If allowed,
@@ -3079,7 +3082,7 @@
<bool name="config_enableMultiUserUI">false</bool>
<!-- Whether multiple admins are allowed on the device. If set to true, new users can be created
- with admin privileges and admin privileges can be granted/revoked from existing users. -->
+ with admin privileges and admin privileges can be granted/revoked from existing users. -->
<bool name="config_enableMultipleAdmins">false</bool>
<!-- Whether there is a communal profile which should always be running.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
index cd442cf..99ed2d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
@@ -21,7 +21,6 @@
import android.telephony.TelephonyManager.EXTRA_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_SPN
-import android.telephony.TelephonyManager.EXTRA_SPN
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
@@ -97,8 +96,7 @@
fun Intent.toNetworkNameModel(separator: String): NetworkNameModel? {
val showSpn = getBooleanExtra(EXTRA_SHOW_SPN, false)
- val spn = getStringExtra(EXTRA_SPN)
- val dataSpn = getStringExtra(EXTRA_DATA_SPN)
+ val spn = getStringExtra(EXTRA_DATA_SPN)
val showPlmn = getBooleanExtra(EXTRA_SHOW_PLMN, false)
val plmn = getStringExtra(EXTRA_PLMN)
@@ -114,12 +112,6 @@
}
str.append(spn)
}
- if (showSpn && dataSpn != null) {
- if (str.isNotEmpty()) {
- str.append(separator)
- }
- str.append(dataSpn)
- }
return if (str.isNotEmpty()) NetworkNameModel.IntentDerived(str.toString()) else null
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 9d83d5f..8fd0b31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -59,7 +59,6 @@
import android.telephony.TelephonyManager.ERI_OFF
import android.telephony.TelephonyManager.ERI_ON
import android.telephony.TelephonyManager.EXTRA_CARRIER_ID
-import android.telephony.TelephonyManager.EXTRA_DATA_SPN
import android.telephony.TelephonyManager.EXTRA_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN
import android.telephony.TelephonyManager.EXTRA_SHOW_SPN
@@ -86,6 +85,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
+import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength
@@ -93,6 +93,8 @@
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor
@@ -110,8 +112,6 @@
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
@@ -815,11 +815,9 @@
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- // spnIntent() sets all values to true and test strings
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
job.cancel()
}
@@ -833,19 +831,17 @@
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
// WHEN an intent with a different subId is sent
val wrongSubIntent = spnIntent(subId = 101)
- captor.lastValue.onReceive(context, wrongSubIntent)
+ captor.value!!.onReceive(context, wrongSubIntent)
// THEN the previous intent's name is still used
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
job.cancel()
}
@@ -859,10 +855,9 @@
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
- assertThat(latest)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
+ assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
val intentWithoutInfo =
spnIntent(
@@ -870,7 +865,7 @@
showPlmn = false,
)
- captor.lastValue.onReceive(context, intentWithoutInfo)
+ captor.value!!.onReceive(context, intentWithoutInfo)
assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
@@ -889,88 +884,10 @@
val intent = spnIntent()
val captor = argumentCaptor<BroadcastReceiver>()
verify(context).registerReceiver(captor.capture(), any())
- captor.lastValue.onReceive(context, intent)
+ captor.value!!.onReceive(context, intent)
// The value is still there despite no active subscribers
- assertThat(underTest.networkName.value)
- .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN$SEP$DATA_SPN"))
- }
-
- @Test
- fun networkName_allFieldsSet() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
-
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = SPN,
- dataSpn = null,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
- }
-
- @Test
- fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = null,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
- }
-
- @Test
- fun networkName_showPlmn_noShowSPN() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = false,
- spn = SPN,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = PLMN,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN"))
- }
-
- @Test
- fun networkName_showPlmn_plmnNull_showSpn() =
- testScope.runTest {
- val latest by collectLastValue(underTest.networkName)
- val captor = argumentCaptor<BroadcastReceiver>()
- verify(context).registerReceiver(captor.capture(), any())
- val intent =
- spnIntent(
- subId = SUB_1_ID,
- showSpn = true,
- spn = SPN,
- dataSpn = DATA_SPN,
- showPlmn = true,
- plmn = null,
- )
- captor.lastValue.onReceive(context, intent)
- assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN$SEP$DATA_SPN"))
+ assertThat(underTest.networkName.value).isEqualTo(intent.toNetworkNameModel(SEP))
}
@Test
@@ -1211,16 +1128,14 @@
private fun spnIntent(
subId: Int = SUB_1_ID,
showSpn: Boolean = true,
- spn: String? = SPN,
- dataSpn: String? = DATA_SPN,
+ spn: String = SPN,
showPlmn: Boolean = true,
- plmn: String? = PLMN,
+ plmn: String = PLMN,
): Intent =
Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED).apply {
putExtra(EXTRA_SUBSCRIPTION_INDEX, subId)
putExtra(EXTRA_SHOW_SPN, showSpn)
putExtra(EXTRA_SPN, spn)
- putExtra(EXTRA_DATA_SPN, dataSpn)
putExtra(EXTRA_SHOW_PLMN, showPlmn)
putExtra(EXTRA_PLMN, plmn)
}
@@ -1233,7 +1148,6 @@
private const val SEP = "-"
private const val SPN = "testSpn"
- private const val DATA_SPN = "testDataSpn"
private const val PLMN = "testPlmn"
}
}
diff --git a/packages/overlays/HsumConfigOverlay/Android.bp b/packages/overlays/HsumConfigOverlay/Android.bp
new file mode 100644
index 0000000..050b1f0
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/Android.bp
@@ -0,0 +1,16 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+runtime_resource_overlay {
+ name: "HsumConfigOverlay",
+ certificate: "platform",
+
+ product_specific: true,
+ sdk_version: "current",
+}
diff --git a/packages/overlays/HsumConfigOverlay/AndroidManifest.xml b/packages/overlays/HsumConfigOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..cd7a879
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.internal.overlay.hsumconfig"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android" android:priority="2" android:isStatic="true" />
+</manifest>
diff --git a/packages/overlays/HsumConfigOverlay/OWNERS b/packages/overlays/HsumConfigOverlay/OWNERS
new file mode 100644
index 0000000..79dd1c9
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/OWNERS
@@ -0,0 +1,2 @@
+# People who can approve submission
+include platform/frameworks/base:/MULTIUSER_OWNERS
diff --git a/packages/overlays/HsumConfigOverlay/res/values/config.xml b/packages/overlays/HsumConfigOverlay/res/values/config.xml
new file mode 100644
index 0000000..7dbdfc7
--- /dev/null
+++ b/packages/overlays/HsumConfigOverlay/res/values/config.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<!-- Default configuration for Headless System User Mode (HSUM) builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether multiple admins are allowed on the device. If set to true, new users can be created
+ with admin privileges and admin privileges can be granted/revoked from existing users. -->
+ <bool name="config_enableMultipleAdmins">true</bool>
+
+ <!-- Whether the device will automatically (at first boot) have a designated main user and treat
+ it as a permanent admin.
+ Since the main user is a permanent admin user it can't be deleted or downgraded to
+ non-admin status.
+ This is generally only relevant on headless system user mode (HSUM) devices; on other
+ devices, the main user is the system user which is always a permanent admin anyway.
+ Note that HSUM devices without this enabled will not automatically have a main user. -->
+ <bool name="config_isMainUserPermanentAdmin">true</bool>
+
+ <!-- Maximum number of users we allow to be running at a time.
+ Note that this includes the headless system user. -->
+ <integer name="config_multiuserMaxRunningUsers">4</integer>
+
+</resources>
diff --git a/services/Android.bp b/services/Android.bp
index dce6aa7..ded7379 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -108,6 +108,8 @@
filegroup {
name: "services-non-updatable-sources",
srcs: [
+ ":incremental_aidl",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core-sources-am-wm",
"core/java/com/android/server/am/package.html",
@@ -377,4 +379,8 @@
},
},
api_surface: "system-server",
+ sdk_version: "module_current",
+ libs: [
+ "framework-annotations-lib",
+ ],
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 363c1d8..89d7961 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -30,6 +30,18 @@
],
}
+filegroup {
+ name: "services.core-aidl-sources",
+ srcs: [
+ ":dumpstate_aidl",
+ ":framework_native_aidl",
+ ":gsiservice_aidl",
+ ":installd_aidl",
+ ":storaged_aidl",
+ ":vold_aidl",
+ ],
+}
+
java_library_static {
name: "services-config-update",
srcs: [
@@ -120,14 +132,9 @@
":android.hardware.tv.hdmi.earc-V1-java-source",
":statslog-art-java-gen",
":statslog-contexthub-java-gen",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core.protologsrc",
- ":dumpstate_aidl",
- ":framework_native_aidl",
- ":gsiservice_aidl",
- ":installd_aidl",
- ":storaged_aidl",
- ":vold_aidl",
":platform-compat-config",
":platform-compat-overrides",
":display-device-config",
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 1ccc48d..2de4482 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -157,7 +157,7 @@
private int mLastMaxChargingVoltage;
private int mLastChargeCounter;
private int mLastBatteryCycleCount;
- private int mLastCharingState;
+ private int mLastChargingState;
/**
* The last seen charging policy. This requires the
* {@link android.Manifest.permission#BATTERY_STATS} permission and should therefore not be
@@ -555,7 +555,7 @@
|| mHealthInfo.batteryChargeCounterUah != mLastChargeCounter
|| mInvalidCharger != mLastInvalidCharger
|| mHealthInfo.batteryCycleCount != mLastBatteryCycleCount
- || mHealthInfo.chargingState != mLastCharingState)) {
+ || mHealthInfo.chargingState != mLastChargingState)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -738,7 +738,7 @@
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
mLastBatteryCycleCount = mHealthInfo.batteryCycleCount;
- mLastCharingState = mHealthInfo.chargingState;
+ mLastChargingState = mHealthInfo.chargingState;
}
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index fdf0ba6..79e09d7 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2229,7 +2229,7 @@
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
- && idMatch(r, subId, phoneId)) {
+ && idMatchRelaxed(r, subId, phoneId)) {
try {
r.callback.onPreciseDataConnectionStateChanged(preciseState);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ac43e86..53b04df 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -2032,8 +2032,11 @@
synchronized (mCachedAbsVolDrivingStreamsLock) {
mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
- mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
- stream);
+ boolean enabled = true;
+ if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ enabled = mAvrcpAbsVolSupported;
+ }
+ mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", enabled, stream);
});
}
@@ -4831,6 +4834,20 @@
private void onUpdateContextualVolumes() {
final int streamType = getBluetoothContextualVolumeStream();
+ synchronized (mCachedAbsVolDrivingStreamsLock) {
+ mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
+ boolean enabled = true;
+ if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ enabled = mAvrcpAbsVolSupported;
+ }
+ if (stream != streamType) {
+ mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/"",
+ enabled, streamType);
+ }
+ return streamType;
+ });
+ }
+
final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
final Set<Integer> absVolumeMultiModeCaseDevices =
AudioSystem.intersectionAudioDeviceTypes(
@@ -6450,17 +6467,6 @@
// change of mode may require volume to be re-applied on some devices
onUpdateContextualVolumes();
- synchronized (mCachedAbsVolDrivingStreamsLock) {
- mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
- int streamToDriveAbs = getBluetoothContextualVolumeStream();
- if (stream != streamToDriveAbs) {
- mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/
- "", /*enabled*/true, streamToDriveAbs);
- }
- return streamToDriveAbs;
- });
- }
-
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
// connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwner(mode, pid, uid);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
index 35fae18..b72a34d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuControllerNew.java
@@ -135,8 +135,8 @@
final RecyclerView recyclerView = contentView
.requireViewById(com.android.internal.R.id.list);
recyclerView.setAdapter(new Adapter(items, selectedIndex, inflater, onClickListener));
- // Scroll to the currently selected IME.
- recyclerView.scrollToPosition(selectedIndex);
+ // Scroll to the currently selected IME. This must run after the recycler view is laid out.
+ recyclerView.post(() -> recyclerView.scrollToPosition(selectedIndex));
// Indicate that the list can be scrolled.
recyclerView.setScrollIndicators(
hasLanguageSettingsButton ? View.SCROLL_INDICATOR_BOTTOM : 0);