diff options
23 files changed, 418 insertions, 72 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 7f35d4a47adf..7d88149abb28 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -30910,6 +30910,8 @@ package android.os { field public static final int BATTERY_STATUS_NOT_CHARGING = 4; // 0x4 field public static final int BATTERY_STATUS_UNKNOWN = 1; // 0x1 field public static final String EXTRA_BATTERY_LOW = "battery_low"; + field public static final String EXTRA_CHARGING_STATUS = "android.os.extra.CHARGING_STATUS"; + field public static final String EXTRA_CYCLE_COUNT = "android.os.extra.CYCLE_COUNT"; field public static final String EXTRA_HEALTH = "health"; field public static final String EXTRA_ICON_SMALL = "icon-small"; field public static final String EXTRA_LEVEL = "level"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 1d3993106a8f..909a3dca3829 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9152,6 +9152,14 @@ package android.os { public class BatteryManager { method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setChargingStateUpdateDelayMillis(int); + field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_CHARGING_POLICY = 9; // 0x9 + field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_FIRST_USAGE_DATE = 8; // 0x8 + field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_MANUFACTURING_DATE = 7; // 0x7 + field @RequiresPermission(android.Manifest.permission.BATTERY_STATS) public static final int BATTERY_PROPERTY_STATE_OF_HEALTH = 10; // 0xa + field public static final int CHARGING_POLICY_ADAPTIVE_AC = 3; // 0x3 + field public static final int CHARGING_POLICY_ADAPTIVE_AON = 2; // 0x2 + field public static final int CHARGING_POLICY_ADAPTIVE_LONGLIFE = 4; // 0x4 + field public static final int CHARGING_POLICY_DEFAULT = 1; // 0x1 field public static final String EXTRA_EVENTS = "android.os.extra.EVENTS"; field public static final String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP"; } diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index 9235ba15019c..3e509e4d1c2f 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -36,10 +36,12 @@ import android.sysprop.HdmiProperties; import android.util.ArrayMap; import android.util.Log; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ConcurrentUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -69,6 +71,32 @@ public final class HdmiControlManager { private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF; /** + * A cache of the current device's physical address. When device's HDMI out port + * is not connected to any device, it is set to {@link #INVALID_PHYSICAL_ADDRESS}. + * + * <p>Otherwise it is updated by the {@link ClientHotplugEventListener} registered + * with {@link com.android.server.hdmi.HdmiControlService} by the + * {@link #addHotplugEventListener(HotplugEventListener)} and the address is from + * {@link com.android.server.hdmi.HdmiControlService#getPortInfo()} + */ + @GuardedBy("mLock") + private int mLocalPhysicalAddress = INVALID_PHYSICAL_ADDRESS; + + private void setLocalPhysicalAddress(int physicalAddress) { + synchronized (mLock) { + mLocalPhysicalAddress = physicalAddress; + } + } + + private int getLocalPhysicalAddress() { + synchronized (mLock) { + return mLocalPhysicalAddress; + } + } + + private final Object mLock = new Object(); + + /** * Broadcast Action: Display OSD message. * <p>Send when the service has a message to display on screen for events * that need user's attention such as ARC status change. @@ -1094,6 +1122,37 @@ public final class HdmiControlManager { mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH); mIsSwitchDevice = HdmiProperties.is_switch().orElse(false); + addHotplugEventListener(new ClientHotplugEventListener()); + } + + private final class ClientHotplugEventListener implements HotplugEventListener { + + @Override + public void onReceived(HdmiHotplugEvent event) { + List<HdmiPortInfo> ports = new ArrayList<>(); + try { + ports = mService.getPortInfo(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + if (ports.isEmpty()) { + Log.e(TAG, "Can't find port info, not updating connected status. " + + "Hotplug event:" + event); + return; + } + // If the HDMI OUT port is plugged or unplugged, update the mLocalPhysicalAddress + for (HdmiPortInfo port : ports) { + if (port.getId() == event.getPort()) { + if (port.getType() == HdmiPortInfo.PORT_OUTPUT) { + setLocalPhysicalAddress( + event.isConnected() + ? port.getAddress() + : INVALID_PHYSICAL_ADDRESS); + } + break; + } + } + } } private static boolean hasDeviceType(int[] types, int type) { @@ -1464,11 +1523,7 @@ public final class HdmiControlManager { * 1.4b 8.7 Physical Address for more details on the address discovery proccess. */ public int getPhysicalAddress() { - try { - return mService.getPhysicalAddress(); - } catch (RemoteException e) { - return INVALID_PHYSICAL_ADDRESS; - } + return getLocalPhysicalAddress(); } /** @@ -1482,7 +1537,7 @@ public final class HdmiControlManager { */ public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) { Objects.requireNonNull(targetDevice); - int physicalAddress = getPhysicalAddress(); + int physicalAddress = getLocalPhysicalAddress(); if (physicalAddress == INVALID_PHYSICAL_ADDRESS) { return false; } @@ -1501,7 +1556,7 @@ public final class HdmiControlManager { @Deprecated public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) { Objects.requireNonNull(targetDevice); - int physicalAddress = getPhysicalAddress(); + int physicalAddress = getLocalPhysicalAddress(); if (physicalAddress == INVALID_PHYSICAL_ADDRESS) { return false; } diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index 647514486750..a20191cab774 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -1108,6 +1108,11 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { /** * Sets the enabled state of the automatic NAT-T keepalive timers * + * Note that if this builder was constructed with a {@link IkeTunnelConnectionParams}, + * but this is called with {@code true}, the framework will automatically choose the + * appropriate keepalive timer and ignore the settings in the session params embedded + * in the connection params. + * * @param isEnabled {@code true} to enable automatic keepalive timers, based on internal * platform signals. Defaults to {@code false}. * @return this {@link Builder} object to facilitate chaining of method calls diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 6dc80cf4c374..611df0a4ea90 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -26,8 +26,6 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.UserIdInt; import android.app.Activity; -import android.app.ActivityThread; -import android.app.OnActivityPausedListener; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; @@ -1570,17 +1568,11 @@ public final class NfcAdapter { if (activity == null || intent == null) { throw new NullPointerException(); } - if (!activity.isResumed()) { - throw new IllegalStateException("Foreground dispatch can only be enabled " + - "when your activity is resumed"); - } try { TechListParcel parcel = null; if (techLists != null && techLists.length > 0) { parcel = new TechListParcel(techLists); } - ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity, - mForegroundDispatchListener); sService.setForegroundDispatch(intent, filters, parcel); } catch (RemoteException e) { attemptDeadServiceRecovery(e); @@ -1608,25 +1600,8 @@ public final class NfcAdapter { throw new UnsupportedOperationException(); } } - ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, - mForegroundDispatchListener); - disableForegroundDispatchInternal(activity, false); - } - - OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() { - @Override - public void onPaused(Activity activity) { - disableForegroundDispatchInternal(activity, true); - } - }; - - void disableForegroundDispatchInternal(Activity activity, boolean force) { try { sService.setForegroundDispatch(null, null, null); - if (!force && !activity.isResumed()) { - throw new IllegalStateException("You must disable foreground dispatching " + - "while your activity is still resumed"); - } } catch (RemoteException e) { attemptDeadServiceRecovery(e); } diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index 76f857bd91b7..6bc0f6ea947c 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -147,6 +147,18 @@ public class BatteryManager { public static final String EXTRA_SEQUENCE = "seq"; /** + * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}: + * Int value representing the battery charging cycle count. + */ + public static final String EXTRA_CYCLE_COUNT = "android.os.extra.CYCLE_COUNT"; + + /** + * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}: + * Int value representing the battery charging status. + */ + public static final String EXTRA_CHARGING_STATUS = "android.os.extra.CHARGING_STATUS"; + + /** * Extra for {@link android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED}: * Contains list of Bundles representing battery events * @hide @@ -190,6 +202,35 @@ public class BatteryManager { /** Power source is dock. */ public static final int BATTERY_PLUGGED_DOCK = OsProtoEnums.BATTERY_PLUGGED_DOCK; // = 8 + // values for "charge policy" property + /** + * Default policy (e.g. normal). + * @hide + */ + @SystemApi + public static final int CHARGING_POLICY_DEFAULT = OsProtoEnums.CHARGING_POLICY_DEFAULT; // = 1 + /** + * Optimized for battery health using static thresholds (e.g stop at 80%). + * @hide + */ + @SystemApi + public static final int CHARGING_POLICY_ADAPTIVE_AON = + OsProtoEnums.CHARGING_POLICY_ADAPTIVE_AON; // = 2 + /** + * Optimized for battery health using adaptive thresholds. + * @hide + */ + @SystemApi + public static final int CHARGING_POLICY_ADAPTIVE_AC = + OsProtoEnums.CHARGING_POLICY_ADAPTIVE_AC; // = 3 + /** + * Optimized for battery health, devices always connected to power. + * @hide + */ + @SystemApi + public static final int CHARGING_POLICY_ADAPTIVE_LONGLIFE = + OsProtoEnums.CHARGING_POLICY_ADAPTIVE_LONGLIFE; // = 4 + /** @hide */ public static final int BATTERY_PLUGGED_ANY = BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS @@ -254,6 +295,76 @@ public class BatteryManager { */ public static final int BATTERY_PROPERTY_STATUS = 6; + /** + * Battery manufacturing date is reported in epoch. The 0 timepoint + * begins at midnight Coordinated Universal Time (UTC) on January 1, 1970. + * It is a long integer in seconds. + * + * <p class="note"> + * The sender must hold the {@link android.Manifest.permission#BATTERY_STATS} permission. + * + * Example: <code> + * // The value returned from the API can be used to create a Date, used + * // to set the time on a calendar and coverted to a string. + * import java.util.Date; + * + * mBatteryManager = mContext.getSystemService(BatteryManager.class); + * final long manufacturingDate = + * mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE); + * Date date = new Date(manufacturingDate); + * Calendar calendar = Calendar.getInstance(); + * calendar.setTime(date); + * // Convert to yyyy-MM-dd HH:mm:ss format string + * SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + * String dateString = sdf.format(date); + * </code> + * @hide + */ + @RequiresPermission(permission.BATTERY_STATS) + @SystemApi + public static final int BATTERY_PROPERTY_MANUFACTURING_DATE = 7; + + /** + * The date of first usage is reported in epoch. The 0 timepoint + * begins at midnight Coordinated Universal Time (UTC) on January 1, 1970. + * It is a long integer in seconds. + * + * <p class="note"> + * The sender must hold the {@link android.Manifest.permission#BATTERY_STATS} permission. + * + * {@link BATTERY_PROPERTY_MANUFACTURING_DATE for sample code} + * @hide + */ + @RequiresPermission(permission.BATTERY_STATS) + @SystemApi + public static final int BATTERY_PROPERTY_FIRST_USAGE_DATE = 8; + + /** + * Battery charging policy from a CHARGING_POLICY_* value.. + * + * <p class="note"> + * The sender must hold the {@link android.Manifest.permission#BATTERY_STATS} permission. + * + * @hide + */ + @RequiresPermission(permission.BATTERY_STATS) + @SystemApi + public static final int BATTERY_PROPERTY_CHARGING_POLICY = 9; + + /** + * + * Percentage representing the measured battery state of health (remaining + * estimated full charge capacity relative to the rated capacity in %). + * + * <p class="note"> + * The sender must hold the {@link android.Manifest.permission#BATTERY_STATS} permission. + * + * @hide + */ + @RequiresPermission(permission.BATTERY_STATS) + @SystemApi + public static final int BATTERY_PROPERTY_STATE_OF_HEALTH = 10; + private final Context mContext; private final IBatteryStats mBatteryStats; private final IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar; @@ -307,7 +418,6 @@ public class BatteryManager { try { BatteryProperty prop = new BatteryProperty(); - if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) ret = prop.getLong(); else diff --git a/core/jni/android_media_MicrophoneInfo.cpp b/core/jni/android_media_MicrophoneInfo.cpp index 65e30d8b1ea3..18f81254af7d 100644 --- a/core/jni/android_media_MicrophoneInfo.cpp +++ b/core/jni/android_media_MicrophoneInfo.cpp @@ -92,6 +92,7 @@ jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo, env->DeleteLocalRef(jFrequencyResponse); } // Create a list of Pair for channel mapping. + jChannelMappings = env->NewObject(gArrayListClass, gArrayListCstor); const auto &channelMapping = micInfo.channel_mapping; for (size_t i = 0; i < std::size(channelMapping); i++) { int channelMappingType = channelMapping[i]; diff --git a/core/tests/companiontests/OWNERS b/core/tests/companiontests/OWNERS new file mode 100644 index 000000000000..734d8b6c5f43 --- /dev/null +++ b/core/tests/companiontests/OWNERS @@ -0,0 +1 @@ +include /core/java/android/companion/OWNERS
\ No newline at end of file diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 27db41cb9f4e..171349a26569 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -841,7 +841,7 @@ public class RingtoneManager { if (ringtoneUri != null) { final Uri cacheUri = getCacheForType(type, context.getUserId()); try (InputStream in = openRingtone(context, ringtoneUri); - OutputStream out = resolver.openOutputStream(cacheUri)) { + OutputStream out = resolver.openOutputStream(cacheUri, "wt")) { FileUtils.copy(in, out); } catch (IOException e) { Log.w(TAG, "Failed to cache ringtone: " + e); diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java index 2db0a8f4f911..33fc37ea0e6d 100644 --- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java +++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java @@ -25,7 +25,7 @@ import android.text.TextUtils; import android.util.Log; import androidx.core.os.BuildCompat; -import androidx.window.embedding.SplitController; +import androidx.window.embedding.ActivityEmbeddingController; import com.android.settingslib.utils.BuildCompatUtils; @@ -86,7 +86,7 @@ public final class ActivityEmbeddingUtils { * @param activity Activity that needs the check */ public static boolean isActivityEmbedded(Activity activity) { - return SplitController.getInstance().isActivityEmbedded(activity); + return ActivityEmbeddingController.getInstance(activity).isActivityEmbedded(activity); } /** diff --git a/packages/SettingsLib/res/values/styles.xml b/packages/SettingsLib/res/values/styles.xml index 5237b4fa1c3d..172aff76d481 100644 --- a/packages/SettingsLib/res/values/styles.xml +++ b/packages/SettingsLib/res/values/styles.xml @@ -14,7 +14,7 @@ ~ limitations under the License --> -<resources> +<resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <style name="TextAppearanceSmall"> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> </style> @@ -73,7 +73,7 @@ </style> <style name="TextAppearanceBroadcastDialogButton" parent="@android:TextAppearance.DeviceDefault.Headline"> - <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textColor">?androidprv:attr/textColorOnAccent</item> <item name="android:textSize">@dimen/broadcast_dialog_btn_text_size</item> </style> diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 379fe2ae713b..7634c58fd74d 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -149,6 +149,8 @@ public final class BatteryService extends SystemService { private int mLastMaxChargingCurrent; private int mLastMaxChargingVoltage; private int mLastChargeCounter; + private int mLastBatteryCycleCount; + private int mLastCharingState; private int mSequence = 1; @@ -503,7 +505,9 @@ public final class BatteryService extends SystemService { || mHealthInfo.maxChargingCurrentMicroamps != mLastMaxChargingCurrent || mHealthInfo.maxChargingVoltageMicrovolts != mLastMaxChargingVoltage || mHealthInfo.batteryChargeCounterUah != mLastChargeCounter - || mInvalidCharger != mLastInvalidCharger)) { + || mInvalidCharger != mLastInvalidCharger + || mHealthInfo.batteryCycleCount != mLastBatteryCycleCount + || mHealthInfo.chargingState != mLastCharingState)) { if (mPlugType != mLastPlugType) { if (mLastPlugType == BATTERY_PLUGGED_NONE) { @@ -677,6 +681,8 @@ public final class BatteryService extends SystemService { mLastChargeCounter = mHealthInfo.batteryChargeCounterUah; mLastBatteryLevelCritical = mBatteryLevelCritical; mLastInvalidCharger = mInvalidCharger; + mLastBatteryCycleCount = mHealthInfo.batteryCycleCount; + mLastCharingState = mHealthInfo.chargingState; } } @@ -708,6 +714,8 @@ public final class BatteryService extends SystemService { BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.maxChargingVoltageMicrovolts); intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounterUah); + intent.putExtra(BatteryManager.EXTRA_CYCLE_COUNT, mHealthInfo.batteryCycleCount); + intent.putExtra(BatteryManager.EXTRA_CHARGING_STATUS, mHealthInfo.chargingState); if (DEBUG) { Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE + ", info:" + mHealthInfo.toString()); @@ -731,6 +739,8 @@ public final class BatteryService extends SystemService { event.putInt(BatteryManager.EXTRA_TEMPERATURE, mHealthInfo.batteryTemperatureTenthsCelsius); event.putInt(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounterUah); event.putLong(BatteryManager.EXTRA_EVENT_TIMESTAMP, now); + event.putInt(BatteryManager.EXTRA_CYCLE_COUNT, mHealthInfo.batteryCycleCount); + event.putInt(BatteryManager.EXTRA_CHARGING_STATUS, mHealthInfo.chargingState); boolean queueWasEmpty = mBatteryLevelsEventQueue.isEmpty(); mBatteryLevelsEventQueue.add(event); @@ -1241,11 +1251,20 @@ public final class BatteryService extends SystemService { } } - // Reduced IBatteryPropertiesRegistrar that only implements getProperty for usage - // in BatteryManager. + // Reduced IBatteryPropertiesRegistrar that implements getProperty for usage + // in BatteryManager and enforce permissions. private final class BatteryPropertiesRegistrar extends IBatteryPropertiesRegistrar.Stub { @Override public int getProperty(int id, final BatteryProperty prop) throws RemoteException { + switch (id) { + case BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE: + case BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE: + case BatteryManager.BATTERY_PROPERTY_CHARGING_POLICY: + case BatteryManager.BATTERY_PROPERTY_STATE_OF_HEALTH: + mContext.enforceCallingPermission( + android.Manifest.permission.BATTERY_STATS, null); + break; + } return mHealthServiceWrapper.getProperty(id, prop); } @Override diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 730c4108220a..e1ae8d93e091 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -1147,6 +1147,10 @@ import java.util.concurrent.atomic.AtomicBoolean; sendILMsg(MSG_IL_BTA2DP_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs); } + /*package*/ void setLeAudioTimeout(String address, int device, int delayMs) { + sendILMsg(MSG_IL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, address, delayMs); + } + /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) { synchronized (mDeviceStateLock) { mBtHelper.setAvrcpAbsoluteVolumeSupported(supported); @@ -1351,6 +1355,13 @@ import java.util.concurrent.atomic.AtomicBoolean; mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1); } break; + case MSG_IL_BTLEAUDIO_TIMEOUT: + // msg.obj == address of LE Audio device + synchronized (mDeviceStateLock) { + mDeviceInventory.onMakeLeAudioDeviceUnavailableNow( + (String) msg.obj, msg.arg1); + } + break; case MSG_L_A2DP_DEVICE_CONFIG_CHANGE: final BluetoothDevice btDevice = (BluetoothDevice) msg.obj; synchronized (mDeviceStateLock) { @@ -1577,11 +1588,14 @@ import java.util.concurrent.atomic.AtomicBoolean; // process set volume for Le Audio, obj is BleVolumeInfo private static final int MSG_II_SET_LE_AUDIO_OUT_VOLUME = 46; + private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49; + private static boolean isMessageHandledUnderWakelock(int msgId) { switch(msgId) { case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_IL_BTA2DP_TIMEOUT: + case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_L_A2DP_DEVICE_CONFIG_CHANGE: case MSG_TOGGLE_HDMI: case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT: @@ -1672,6 +1686,7 @@ import java.util.concurrent.atomic.AtomicBoolean; case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_IL_BTA2DP_TIMEOUT: + case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_L_A2DP_DEVICE_CONFIG_CHANGE: if (sLastDeviceConnectMsgTime >= time) { // add a little delay to make sure messages are ordered as expected diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index 35da73ef58c0..a74f4154eb85 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -374,7 +374,7 @@ public class AudioDeviceInventory { case BluetoothProfile.LE_AUDIO: case BluetoothProfile.LE_AUDIO_BROADCAST: if (switchToUnavailable) { - makeLeAudioDeviceUnavailable(address, btInfo.mAudioSystemDevice); + makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice); } else if (switchToAvailable) { makeLeAudioDeviceAvailable(address, BtHelper.getName(btInfo.mDevice), streamType, btInfo.mVolume == -1 ? -1 : btInfo.mVolume * 10, @@ -486,6 +486,12 @@ public class AudioDeviceInventory { } } + /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device) { + synchronized (mDevicesLock) { + makeLeAudioDeviceUnavailableNow(address, device); + } + } + /*package*/ void onReportNewRoutes() { int n = mRoutesObservers.beginBroadcast(); if (n > 0) { @@ -883,10 +889,11 @@ public class AudioDeviceInventory { new MediaMetrics.Item(mMetricsId + "disconnectLeAudio") .record(); if (toRemove.size() > 0) { - final int delay = checkSendBecomingNoisyIntentInt(device, 0, + final int delay = checkSendBecomingNoisyIntentInt(device, + AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE); toRemove.stream().forEach(deviceAddress -> - makeLeAudioDeviceUnavailable(deviceAddress, device) + makeLeAudioDeviceUnavailableLater(deviceAddress, device, delay) ); } } @@ -1187,9 +1194,21 @@ public class AudioDeviceInventory { */ mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource); - AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address, name), + final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes( + device, address, name), AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); + if (res != AudioSystem.AUDIO_STATUS_OK) { + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "APM failed to make available LE Audio device addr=" + address + + " error=" + res).printLog(TAG)); + // TODO: connection failed, stop here + // TODO: return; + } else { + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "LE Audio device addr=" + address + " now available").printLog(TAG)); + } + mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address), new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT)); mDeviceBroker.postAccessoryPlugMediaUnmute(device); @@ -1210,11 +1229,23 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") - private void makeLeAudioDeviceUnavailable(String address, int device) { + private void makeLeAudioDeviceUnavailableNow(String address, int device) { if (device != AudioSystem.DEVICE_NONE) { - AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address), + final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes( + device, address), AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); + + if (res != AudioSystem.AUDIO_STATUS_OK) { + AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent( + "APM failed to make unavailable LE Audio device addr=" + address + + " error=" + res).printLog(TAG)); + // TODO: failed to disconnect, stop here + // TODO: return; + } else { + AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent( + "LE Audio device addr=" + address + " made unavailable")).printLog(TAG)); + } mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address)); } @@ -1222,6 +1253,14 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") + private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) { + // the device will be made unavailable later, so consider it disconnected right away + mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address)); + // send the delayed message to make the device unavailable later + mDeviceBroker.setLeAudioTimeout(address, device, delayMs); + } + + @GuardedBy("mDevicesLock") private void setCurrentAudioRouteNameIfPossible(String name, boolean fromA2dp) { synchronized (mCurAudioRoutes) { if (TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 05915d964eb7..acfde9a4cfbb 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -4005,7 +4005,8 @@ public class AudioService extends IAudioService.Stub } } - private void setLeAudioVolumeOnModeUpdate(int mode, int device) { + private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, + int maxIndex) { switch (mode) { case AudioSystem.MODE_IN_COMMUNICATION: case AudioSystem.MODE_IN_CALL: @@ -4023,16 +4024,15 @@ public class AudioService extends IAudioService.Stub // (like the outgoing call) the value of 'device' is not DEVICE_OUT_BLE_* // even when BLE is connected. if (!AudioSystem.isLeAudioDeviceType(device)) { + Log.w(TAG, "setLeAudioVolumeOnModeUpdate got unexpected device=" + device + + ", forcing to device=" + AudioSystem.DEVICE_OUT_BLE_HEADSET); device = AudioSystem.DEVICE_OUT_BLE_HEADSET; } - final int streamType = getBluetoothContextualVolumeStream(mode); - final int index = mStreamStates[streamType].getIndex(device); - final int maxIndex = mStreamStates[streamType].getMaxIndex(); - if (DEBUG_VOL) { - Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex index=" - + index + " maxIndex=" + maxIndex + " streamType=" + streamType); + Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device=" + + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex + + " streamType=" + streamType); } mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType); mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate"); @@ -5403,10 +5403,18 @@ public class AudioService extends IAudioService.Stub mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid, requestedMode, pid, mode)); - int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); - int device = getDeviceForStream(streamType); - int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device); - setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, + final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE); + final int device = getDeviceForStream(streamType); + final int streamAlias = mStreamVolumeAlias[streamType]; + + if (DEBUG_MODE) { + Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType + + ", streamAlias=" + streamAlias); + } + + final int index = mStreamStates[streamAlias].getIndex(device); + final int maxIndex = mStreamStates[streamAlias].getMaxIndex(); + setStreamVolumeInt(streamAlias, index, device, true, requesterPackage, true /*hasModifyAudioSettings*/); updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage); @@ -5414,7 +5422,7 @@ public class AudioService extends IAudioService.Stub // change of mode may require volume to be re-applied on some devices updateAbsVolumeMultiModeDevices(previousMode, mode); - setLeAudioVolumeOnModeUpdate(mode, device); + setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex); // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO // connections not started by the application changing the mode when pid changes diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index c15e419c073c..ab2c002c2b24 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -25,6 +25,8 @@ import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN; +import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_AUTO; +import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO; import static android.os.PowerWhitelistManager.REASON_VPN; import static android.os.UserHandle.PER_USER_RANGE; @@ -251,6 +253,14 @@ public class Vpn { */ private static final int STARTING_TOKEN = -1; + // TODO : read this from carrier config instead of a constant + @VisibleForTesting + public static final int AUTOMATIC_KEEPALIVE_DELAY_SECONDS = 30; + + // Default keepalive timeout for carrier config is 5 minutes. Mimic this. + @VisibleForTesting + static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60; + // TODO: create separate trackers for each unique VPN to support // automated reconnection @@ -3071,6 +3081,7 @@ public class Vpn { prepareStatusIntent(); } agentConnect(this::onValidationStatus); + mSession.setUnderpinnedNetwork(mNetworkAgent.getNetwork()); return; // Link properties are already sent. } else { // Underlying networks also set in agentConnect() @@ -3179,6 +3190,7 @@ public class Vpn { if (!removedAddrs.isEmpty()) { startNewNetworkAgent( mNetworkAgent, "MTU too low for IPv6; restarting network agent"); + mSession.setUnderpinnedNetwork(mNetworkAgent.getNetwork()); for (LinkAddress removed : removedAddrs) { mTunnelIface.removeAddress( @@ -3251,14 +3263,22 @@ public class Vpn { private IkeSessionParams getIkeSessionParams(@NonNull Network underlyingNetwork) { final IkeTunnelConnectionParams ikeTunConnParams = mProfile.getIkeTunnelConnectionParams(); + final IkeSessionParams.Builder builder; if (ikeTunConnParams != null) { - final IkeSessionParams.Builder builder = - new IkeSessionParams.Builder(ikeTunConnParams.getIkeSessionParams()) - .setNetwork(underlyingNetwork); - return builder.build(); + builder = new IkeSessionParams.Builder(ikeTunConnParams.getIkeSessionParams()) + .setNetwork(underlyingNetwork); } else { - return VpnIkev2Utils.buildIkeSessionParams(mContext, mProfile, underlyingNetwork); + builder = VpnIkev2Utils.makeIkeSessionParamsBuilder(mContext, mProfile, + underlyingNetwork); } + if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { + builder.setNattKeepAliveDelaySeconds(guessNattKeepaliveTimerForNetwork()); + } + if (mProfile.isAutomaticIpVersionSelectionEnabled()) { + builder.setIpVersion(guessEspIpVersionForNetwork()); + builder.setEncapType(guessEspEncapTypeForNetwork()); + } + return builder.build(); } @NonNull @@ -3322,6 +3342,23 @@ public class Vpn { startIkeSession(underlyingNetwork); } + private int guessEspIpVersionForNetwork() { + // TODO : guess the IP version based on carrier if auto IP version selection is enabled + return ESP_IP_VERSION_AUTO; + } + + private int guessEspEncapTypeForNetwork() { + // TODO : guess the ESP encap type based on carrier if auto IP version selection is + // enabled + return ESP_ENCAP_TYPE_AUTO; + } + + private int guessNattKeepaliveTimerForNetwork() { + // TODO : guess the keepalive delay based on carrier if auto keepalive timer is + // enabled + return AUTOMATIC_KEEPALIVE_DELAY_SECONDS; + } + boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) { if (mSession == null || !mMobikeEnabled) return false; @@ -3331,7 +3368,20 @@ public class Vpn { + mCurrentToken + " to network " + underlyingNetwork); - mSession.setNetwork(underlyingNetwork); + final int ipVersion = mProfile.isAutomaticIpVersionSelectionEnabled() + ? guessEspIpVersionForNetwork() : ESP_IP_VERSION_AUTO; + final int encapType = mProfile.isAutomaticIpVersionSelectionEnabled() + ? guessEspEncapTypeForNetwork() : ESP_ENCAP_TYPE_AUTO; + final int keepaliveDelaySeconds; + if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { + keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork(); + } else if (mProfile.getIkeTunnelConnectionParams() != null) { + keepaliveDelaySeconds = mProfile.getIkeTunnelConnectionParams() + .getIkeSessionParams().getNattKeepAliveDelaySeconds(); + } else { + keepaliveDelaySeconds = DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; + } + mSession.setNetwork(underlyingNetwork, ipVersion, encapType, keepaliveDelaySeconds); return true; } @@ -4661,8 +4711,14 @@ public class Vpn { } /** Update the underlying network of the IKE Session */ - public void setNetwork(@NonNull Network network) { - mImpl.setNetwork(network); + public void setNetwork(@NonNull Network network, int ipVersion, int encapType, + int keepaliveDelaySeconds) { + mImpl.setNetwork(network, ipVersion, encapType, keepaliveDelaySeconds); + } + + /** Set the underpinned network */ + public void setUnderpinnedNetwork(@NonNull Network underpinnedNetwork) { + mImpl.setUnderpinnedNetwork(underpinnedNetwork); } /** Forcibly terminate the IKE Session */ diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java index 857c86de57ca..a48c9fcd4181 100644 --- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java @@ -99,7 +99,7 @@ import java.util.concurrent.Executor; public class VpnIkev2Utils { private static final String TAG = VpnIkev2Utils.class.getSimpleName(); - static IkeSessionParams buildIkeSessionParams( + static IkeSessionParams.Builder makeIkeSessionParamsBuilder( @NonNull Context context, @NonNull Ikev2VpnProfile profile, @NonNull Network network) { final IkeIdentification localId = parseIkeIdentification(profile.getUserIdentity()); final IkeIdentification remoteId = parseIkeIdentification(profile.getServerAddr()); @@ -117,7 +117,7 @@ public class VpnIkev2Utils { ikeOptionsBuilder.addSaProposal(ikeProposal); } - return ikeOptionsBuilder.build(); + return ikeOptionsBuilder; } static ChildSessionParams buildChildSessionParams(List<String> allowedAlgorithms) { diff --git a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java index c4113198ae1d..1153cc37e3da 100644 --- a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java +++ b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java @@ -18,6 +18,7 @@ package com.android.server.health; import android.annotation.NonNull; import android.annotation.Nullable; +import android.hardware.health.BatteryHealthData; import android.hardware.health.HealthInfo; import android.hardware.health.IHealth; import android.os.BatteryManager; @@ -113,6 +114,7 @@ class HealthServiceWrapperAidl extends HealthServiceWrapper { private int getPropertyInternal(int id, BatteryProperty prop) throws RemoteException { IHealth service = mLastService.get(); if (service == null) throw new RemoteException("no health service"); + BatteryHealthData healthData; try { switch (id) { case BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER: @@ -133,6 +135,21 @@ class HealthServiceWrapperAidl extends HealthServiceWrapper { case BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER: prop.setLong(service.getEnergyCounterNwh()); break; + case BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE: + healthData = service.getBatteryHealthData(); + prop.setLong(healthData.batteryManufacturingDateSeconds); + break; + case BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE: + healthData = service.getBatteryHealthData(); + prop.setLong(healthData.batteryFirstUsageSeconds); + break; + case BatteryManager.BATTERY_PROPERTY_CHARGING_POLICY: + prop.setLong(service.getChargingPolicy()); + break; + case BatteryManager.BATTERY_PROPERTY_STATE_OF_HEALTH: + healthData = service.getBatteryHealthData(); + prop.setLong(healthData.batteryStateOfHealth); + break; } } catch (UnsupportedOperationException e) { // Leave prop untouched. diff --git a/services/robotests/src/com/android/server/media/OWNERS b/services/robotests/src/com/android/server/media/OWNERS new file mode 100644 index 000000000000..c74c9ac98b13 --- /dev/null +++ b/services/robotests/src/com/android/server/media/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 137631 +include platform/frameworks/av:/media/janitors/media_solutions_OWNERS + diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java index db99acfd9a35..3533c0907fac 100644 --- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java +++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java @@ -31,6 +31,7 @@ import com.android.ims.internal.IImsCallSession; import java.util.ArrayList; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Executor; /** * Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing @@ -44,8 +45,8 @@ import java.util.Set; // ImsCallSessionListenerConverter is also changed. @SystemApi public class ImsCallSessionListener { - private final IImsCallSessionListener mListener; + private Executor mExecutor = null; /** @hide */ public ImsCallSessionListener(IImsCallSessionListener l) { @@ -243,6 +244,9 @@ public class ImsCallSessionListener { public void callSessionMergeStarted(ImsCallSessionImplBase newSession, ImsCallProfile profile) { try { + if (newSession != null && mExecutor != null) { + newSession.setDefaultExecutor(mExecutor); + } mListener.callSessionMergeStarted(newSession != null ? newSession.getServiceImpl() : null, profile); } catch (RemoteException e) { @@ -274,6 +278,9 @@ public class ImsCallSessionListener { */ public void callSessionMergeComplete(ImsCallSessionImplBase newSession) { try { + if (newSession != null && mExecutor != null) { + newSession.setDefaultExecutor(mExecutor); + } mListener.callSessionMergeComplete(newSession != null ? newSession.getServiceImpl() : null); } catch (RemoteException e) { @@ -361,6 +368,9 @@ public class ImsCallSessionListener { public void callSessionConferenceExtended(ImsCallSessionImplBase newSession, ImsCallProfile profile) { try { + if (newSession != null && mExecutor != null) { + newSession.setDefaultExecutor(mExecutor); + } mListener.callSessionConferenceExtended( newSession != null ? newSession.getServiceImpl() : null, profile); } catch (RemoteException e) { @@ -406,6 +416,9 @@ public class ImsCallSessionListener { public void callSessionConferenceExtendReceived(ImsCallSessionImplBase newSession, ImsCallProfile profile) { try { + if (newSession != null && mExecutor != null) { + newSession.setDefaultExecutor(mExecutor); + } mListener.callSessionConferenceExtendReceived(newSession != null ? newSession.getServiceImpl() : null, profile); } catch (RemoteException e) { @@ -808,5 +821,19 @@ public class ImsCallSessionListener { e.rethrowFromSystemServer(); } } + + /** + * Set default Executor from ImsService. + * @param executor The default executor to use when executing the methods by the vendor + * implementation of {@link ImsCallSessionImplBase} for conference call. + * This executor is dedicated to set vendor CallSessionImpl + * only when conference call is established. + * @hide + */ + public final void setDefaultExecutor(@NonNull Executor executor) { + if (mExecutor == null) { + mExecutor = executor; + } + } } diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index fb0e659ec77b..ebe11e938c39 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -644,6 +644,7 @@ public class MmTelFeature extends ImsFeature { throw new IllegalStateException("Session is not available."); } try { + c.setDefaultExecutor(MmTelFeature.this.mExecutor); listener.onIncomingCall(c.getServiceImpl(), extras); } catch (RemoteException e) { throw new RuntimeException(e); diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java index e8100957517f..25bf7d6af9ca 100644 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java @@ -173,8 +173,9 @@ public class ImsCallSessionImplBase implements AutoCloseable { @Override public void setListener(IImsCallSessionListener listener) { - executeMethodAsync(() -> ImsCallSessionImplBase.this.setListener( - new ImsCallSessionListener(listener)), "setListener"); + ImsCallSessionListener iCSL = new ImsCallSessionListener(listener); + iCSL.setDefaultExecutor(mExecutor); + executeMethodAsync(() -> ImsCallSessionImplBase.this.setListener(iCSL), "setListener"); } @Override diff --git a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java index 90ddb6ffb34a..d2a6bf288be4 100644 --- a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java +++ b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java @@ -31,6 +31,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -299,6 +300,8 @@ public final class BackgroundDexOptServiceIntegrationTests { // Test that background dexopt under low storage conditions downgrades unused packages. @Test + @Ignore("b/251438180: This test has been failing for a long time; temporarily disable it while" + + " we investigate this issue.") public void testBackgroundDexOptDowngradeSuccessful() throws IOException { // Should be more than DOWNGRADE_AFTER_DAYS. long deltaDays = DOWNGRADE_AFTER_DAYS + 1; |