diff options
21 files changed, 574 insertions, 143 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 896060ba7d65..4f96abe2323e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21542,6 +21542,7 @@ package android.media { public class MediaActionSound { ctor public MediaActionSound(); method public void load(int); + method public static boolean mustPlayShutterSound(); method public void play(int); method public void release(); field public static final int FOCUS_COMPLETE = 1; // 0x1 diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 81b4ee80a1d2..a646a681afc1 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -113,6 +113,8 @@ package android.media { public class AudioManager { method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getHwOffloadFormatsSupportedForA2dp(); + method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getHwOffloadFormatsSupportedForLeAudio(); method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void handleBluetoothActiveDeviceChanged(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothDevice, @NonNull android.media.BtProfileConnectionInfo); method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setA2dpSuspended(boolean); method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setBluetoothHeadsetProperties(@NonNull String, boolean, boolean); @@ -202,6 +204,10 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR; } + public final class IpSecManager { + field public static final int DIRECTION_FWD = 2; // 0x2 + } + public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable { method public int getResourceId(); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 1552dbd00c92..9659df6bf04a 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -5408,7 +5408,9 @@ public class Intent implements Parcelable, Cloneable { * * <p>Targets provided in this way will be presented inline with all other targets provided * by services from other apps. They will be prioritized before other service targets, but - * after those targets provided by sources that the user has manually pinned to the front.</p> + * after those targets provided by sources that the user has manually pinned to the front. + * You can provide up to two targets on this extra (the limit of two targets + * starts in Android 10).</p> * * @see #ACTION_CHOOSER */ @@ -5519,9 +5521,11 @@ public class Intent implements Parcelable, Cloneable { /** * A Parcelable[] of {@link Intent} or * {@link android.content.pm.LabeledIntent} objects as set with - * {@link #putExtra(String, Parcelable[])} of additional activities to place - * a the front of the list of choices, when shown to the user with a - * {@link #ACTION_CHOOSER}. + * {@link #putExtra(String, Parcelable[])} to place + * at the front of the list of choices, when shown to the user with an + * {@link #ACTION_CHOOSER}. You can choose up to two additional activities + * to show before the app suggestions (the limit of two additional activities starts in + * Android 10). */ public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS"; diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 70fe5d677b4f..123c55c27d1c 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -18,8 +18,11 @@ package android.net; import static android.net.NetworkStats.METERED_ALL; import static android.net.NetworkStats.METERED_YES; +import static android.net.NetworkTemplate.MATCH_BLUETOOTH; import static android.net.NetworkTemplate.MATCH_CARRIER; +import static android.net.NetworkTemplate.MATCH_ETHERNET; import static android.net.NetworkTemplate.MATCH_MOBILE; +import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT; import android.annotation.NonNull; @@ -324,7 +327,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { @NonNull private byte[] getNetworkTemplateBytesForBackup() throws IOException { - if (!template.isPersistable()) { + if (!isTemplatePersistable(this.template)) { Log.wtf(TAG, "Trying to backup non-persistable template: " + this); } @@ -378,4 +381,28 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { "Restored network template contains unknown match rule " + matchRule, e); } } + + /** + * Check if the template can be persisted into disk. + */ + public static boolean isTemplatePersistable(@NonNull NetworkTemplate template) { + switch (template.getMatchRule()) { + case MATCH_BLUETOOTH: + case MATCH_ETHERNET: + return true; + case MATCH_CARRIER: + case MATCH_MOBILE: + return !template.getSubscriberIds().isEmpty(); + case MATCH_WIFI: + if (Objects.equals(template.getWifiNetworkKey(), null) + && template.getSubscriberIds().isEmpty()) { + return false; + } + return true; + default: + // Don't allow persistable for unknown types or legacy types such as + // MATCH_MOBILE_WILDCARD, MATCH_PROXY, etc. + return false; + } + } } diff --git a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt index d936cad15689..121caef87f6f 100644 --- a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt +++ b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt @@ -16,6 +16,10 @@ package android.net +import android.net.NetworkTemplate.MATCH_BLUETOOTH +import android.net.NetworkTemplate.MATCH_ETHERNET +import android.net.NetworkTemplate.MATCH_MOBILE +import android.net.NetworkTemplate.MATCH_WIFI import android.text.format.Time.TIMEZONE_UTC import androidx.test.runner.AndroidJUnit4 import org.junit.Test @@ -24,6 +28,8 @@ import java.io.ByteArrayInputStream import java.io.DataInputStream import java.time.ZoneId import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue private const val TEST_IMSI1 = "TESTIMSI1" private const val TEST_SSID1 = "TESTISSID1" @@ -53,4 +59,26 @@ class NetworkPolicyTest { val restored = NetworkPolicy.getNetworkPolicyFromBackup(stream) assertEquals(policy, restored) } + + @Test + fun testIsTemplatePersistable() { + listOf(MATCH_MOBILE, MATCH_WIFI).forEach { + // Verify wildcard templates cannot be persistable. + assertFalse(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it).build())) + + // Verify mobile/wifi templates can be persistable if the Subscriber Id is supplied. + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it) + .setSubscriberIds(setOf(TEST_IMSI1)).build())) + } + + // Verify bluetooth and ethernet templates can be persistable without any other + // field is supplied. + listOf(MATCH_BLUETOOTH, MATCH_ETHERNET).forEach { + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(it).build())) + } + + // Verify wifi template can be persistable if the Wifi Network Key is supplied. + assertTrue(NetworkPolicy.isTemplatePersistable(NetworkTemplate.Builder(MATCH_WIFI) + .setWifiNetworkKey(TEST_SSID1).build())) + } }
\ No newline at end of file diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 60f4a5a226db..982cf07da358 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -6791,56 +6791,63 @@ public class AudioManager { /** * Returns a list of audio formats that corresponds to encoding formats - * supported on offload path for A2DP and LE audio playback. + * supported on offload path for A2DP playback. * - * @param deviceType Indicates the target device type {@link AudioSystem.DeviceType} * @return a list of {@link BluetoothCodecConfig} objects containing encoding formats - * supported for offload A2DP playback or a list of {@link BluetoothLeAudioCodecConfig} - * objects containing encoding formats supported for offload LE Audio playback + * supported for offload A2DP playback * @hide */ - public List<?> getHwOffloadFormatsSupportedForBluetoothMedia( - @AudioSystem.DeviceType int deviceType) { - ArrayList<Integer> formatsList = new ArrayList<Integer>(); - ArrayList<BluetoothCodecConfig> a2dpCodecConfigList = new ArrayList<BluetoothCodecConfig>(); - ArrayList<BluetoothLeAudioCodecConfig> leAudioCodecConfigList = - new ArrayList<BluetoothLeAudioCodecConfig>(); + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public @NonNull List<BluetoothCodecConfig> getHwOffloadFormatsSupportedForA2dp() { + ArrayList<Integer> formatsList = new ArrayList<>(); + ArrayList<BluetoothCodecConfig> codecConfigList = new ArrayList<>(); - if (deviceType != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP - && deviceType != AudioSystem.DEVICE_OUT_BLE_HEADSET) { - throw new IllegalArgumentException( - "Illegal devicetype for the getHwOffloadFormatsSupportedForBluetoothMedia"); + int status = AudioSystem.getHwOffloadFormatsSupportedForBluetoothMedia( + AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, formatsList); + if (status != AudioManager.SUCCESS) { + Log.e(TAG, "getHwOffloadEncodingFormatsSupportedForA2DP failed:" + status); + return codecConfigList; + } + + for (Integer format : formatsList) { + int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format); + if (btSourceCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) { + codecConfigList.add(new BluetoothCodecConfig(btSourceCodec)); + } } + return codecConfigList; + } + + /** + * Returns a list of audio formats that corresponds to encoding formats + * supported on offload path for Le audio playback. + * + * @return a list of {@link BluetoothLeAudioCodecConfig} objects containing encoding formats + * supported for offload Le Audio playback + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @NonNull + public List<BluetoothLeAudioCodecConfig> getHwOffloadFormatsSupportedForLeAudio() { + ArrayList<Integer> formatsList = new ArrayList<>(); + ArrayList<BluetoothLeAudioCodecConfig> leAudioCodecConfigList = new ArrayList<>(); - int status = AudioSystem.getHwOffloadFormatsSupportedForBluetoothMedia(deviceType, - formatsList); + int status = AudioSystem.getHwOffloadFormatsSupportedForBluetoothMedia( + AudioSystem.DEVICE_OUT_BLE_HEADSET, formatsList); if (status != AudioManager.SUCCESS) { - Log.e(TAG, "getHwOffloadFormatsSupportedForBluetoothMedia for deviceType " - + deviceType + " failed:" + status); - return a2dpCodecConfigList; + Log.e(TAG, "getHwOffloadEncodingFormatsSupportedForLeAudio failed:" + status); + return leAudioCodecConfigList; } - if (deviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) { - for (Integer format : formatsList) { - int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format); - if (btSourceCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) { - a2dpCodecConfigList.add(new BluetoothCodecConfig(btSourceCodec)); - } + for (Integer format : formatsList) { + int btLeAudioCodec = AudioSystem.audioFormatToBluetoothLeAudioSourceCodec(format); + if (btLeAudioCodec != BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID) { + leAudioCodecConfigList.add(new BluetoothLeAudioCodecConfig.Builder() + .setCodecType(btLeAudioCodec) + .build()); } - return a2dpCodecConfigList; - } else if (deviceType == AudioSystem.DEVICE_OUT_BLE_HEADSET) { - for (Integer format : formatsList) { - int btLeAudioCodec = AudioSystem.audioFormatToBluetoothLeAudioSourceCodec(format); - if (btLeAudioCodec != BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID) { - leAudioCodecConfigList.add(new BluetoothLeAudioCodecConfig.Builder() - .setCodecType(btLeAudioCodec) - .build()); - } - } - return leAudioCodecConfigList; } - Log.e(TAG, "Input deviceType " + deviceType + " doesn't support."); - return a2dpCodecConfigList; + return leAudioCodecConfigList; } // Since we need to calculate the changes since THE LAST NOTIFICATION, and not since the diff --git a/media/java/android/media/MediaActionSound.java b/media/java/android/media/MediaActionSound.java index dcd4dce5f3eb..ec56d614f2b5 100644 --- a/media/java/android/media/MediaActionSound.java +++ b/media/java/android/media/MediaActionSound.java @@ -16,8 +16,11 @@ package android.media; -import android.media.AudioManager; +import android.content.Context; import android.media.SoundPool; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Log; /** @@ -104,6 +107,26 @@ public class MediaActionSound { private static final int STATE_LOADING_PLAY_REQUESTED = 2; private static final int STATE_LOADED = 3; + /** + * <p>Returns true if the application must play the shutter sound in accordance + * to certain regional restrictions. </p> + * + * <p>If this method returns true, applications are strongly recommended to use + * MediaActionSound.play(SHUTTER_CLICK) or START_VIDEO_RECORDING whenever it captures + * images or video to storage or sends them over the network.</p> + */ + public static boolean mustPlayShutterSound() { + boolean result = false; + IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); + IAudioService audioService = IAudioService.Stub.asInterface(b); + try { + result = audioService.isCameraSoundForced(); + } catch (RemoteException e) { + Log.e(TAG, "audio service is unavailable for queries, defaulting to false"); + } + return result; + } + private class SoundState { public final int name; public int id; diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java index 837629911ccd..0b266b226c78 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java @@ -86,6 +86,7 @@ public final class IpSecManager { * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final int DIRECTION_FWD = 2; /** diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java index cb5a025278b1..d85291318fa4 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java @@ -47,6 +47,7 @@ import android.os.Parcelable; import android.telephony.Annotation.NetworkType; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.util.ArraySet; import com.android.internal.util.ArrayUtils; import com.android.net.module.util.NetworkIdentityUtils; @@ -58,6 +59,9 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; /** * Predicate used to match {@link NetworkIdentity}, usually when collecting @@ -119,20 +123,30 @@ public final class NetworkTemplate implements Parcelable { public @interface SubscriberIdMatchRule{} /** * Value of the match rule of the subscriberId to match networks with specific subscriberId. + * + * @hide */ public static final int SUBSCRIBER_ID_MATCH_RULE_EXACT = 0; /** * Value of the match rule of the subscriberId to match networks with any subscriberId which * includes null and non-null. + * + * @hide */ public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1; + // TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL. + /** @hide */ + public static final String WIFI_NETWORKID_ALL = null; + /** - * Wi-Fi Network ID is never supposed to be null (if it is, it is a bug that + * Wi-Fi Network Key is never supposed to be null (if it is, it is a bug that * should be fixed), so it's not possible to want to match null vs - * non-null. Therefore it's fine to use null as a sentinel for Network ID. + * non-null. Therefore it's fine to use null as a sentinel for Wifi Network Key. + * + * @hide */ - public static final String WIFI_NETWORKID_ALL = null; + public static final String WIFI_NETWORK_KEY_ALL = WIFI_NETWORKID_ALL; /** * Include all network types when filtering. This is meant to merge in with the @@ -278,7 +292,10 @@ public final class NetworkTemplate implements Parcelable { * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given SSID, * and IMSI. * - * Call with {@link #WIFI_NETWORKID_ALL} for {@code networkId} to get result regardless of SSID. + * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code networkId} to get result regardless + * of SSID. + * + * @hide */ public static NetworkTemplate buildTemplateWifi(@Nullable String networkId, @Nullable String subscriberId) { @@ -345,6 +362,7 @@ public final class NetworkTemplate implements Parcelable { */ private final String[] mMatchSubscriberIds; + // TODO: Change variable name to match the Api surface. private final String mNetworkId; // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*. @@ -361,14 +379,14 @@ public final class NetworkTemplate implements Parcelable { // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}. private final int mOemManaged; - private void checkValidSubscriberIdMatchRule() { - switch (mMatchRule) { + private static void checkValidSubscriberIdMatchRule(int matchRule, int subscriberIdMatchRule) { + switch (matchRule) { case MATCH_MOBILE: case MATCH_CARRIER: // MOBILE and CARRIER templates must always specify a subscriber ID. - if (mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) { - throw new IllegalArgumentException("Invalid SubscriberIdMatchRule" - + "on match rule: " + getMatchRuleName(mMatchRule)); + if (subscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) { + throw new IllegalArgumentException("Invalid SubscriberIdMatchRule " + + "on match rule: " + getMatchRuleName(matchRule)); } return; default: @@ -421,7 +439,7 @@ public final class NetworkTemplate implements Parcelable { mSubType = subType; mOemManaged = oemManaged; mSubscriberIdMatchRule = subscriberIdMatchRule; - checkValidSubscriberIdMatchRule(); + checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule); if (!isKnownMatchRule(matchRule)) { throw new IllegalArgumentException("Unknown network template rule " + matchRule + " will not match any identity."); @@ -519,7 +537,7 @@ public final class NetworkTemplate implements Parcelable { return false; } - private String subscriberIdMatchRuleToString(int rule) { + private static String subscriberIdMatchRuleToString(int rule) { switch (rule) { case SUBSCRIBER_ID_MATCH_RULE_EXACT: return "EXACT_MATCH"; @@ -542,52 +560,58 @@ public final class NetworkTemplate implements Parcelable { } /** - * Check if the template can be persisted into disk. - * - * @hide + * Get match rule of the template. See {@code MATCH_*}. */ - // TODO: Move to the NetworkPolicy. - public boolean isPersistable() { + @UnsupportedAppUsage + public int getMatchRule() { + // Wildcard rules are not exposed. For external callers, convert wildcard rules to + // exposed rules before returning. switch (mMatchRule) { case MATCH_MOBILE_WILDCARD: + return MATCH_MOBILE; case MATCH_WIFI_WILDCARD: - return false; - case MATCH_CARRIER: - return mSubscriberId != null; - case MATCH_WIFI: - if (Objects.equals(mNetworkId, WIFI_NETWORKID_ALL) - && mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) { - return false; - } - return true; + return MATCH_WIFI; default: - return true; + return mMatchRule; } } /** - * Get match rule of the template. See {@code MATCH_*}. + * Get subscriber Id of the template. */ + @Nullable @UnsupportedAppUsage - public int getMatchRule() { - return mMatchRule; + public String getSubscriberId() { + return mSubscriberId; } /** - * Get subscriber Id of the template. + * Get set of subscriber Ids of the template. + */ + @NonNull + public Set<String> getSubscriberIds() { + return new ArraySet<>(Arrays.asList(mMatchSubscriberIds)); + } + + /** + * Get Wifi Network Key of the template. See {@link WifiInfo#getCurrentNetworkKey()}. */ @Nullable - @UnsupportedAppUsage - public String getSubscriberId() { - return mSubscriberId; + public String getWifiNetworkKey() { + return mNetworkId; } + /** @hide */ + // TODO: Remove this and replace all callers with {@link #getWifiNetworkKey()}. + @Nullable public String getNetworkId() { return mNetworkId; } /** * Get Subscriber Id Match Rule of the template. + * + * @hide */ public int getSubscriberIdMatchRule() { return mSubscriberIdMatchRule; @@ -602,6 +626,38 @@ public final class NetworkTemplate implements Parcelable { } /** + * Get roaming filter of the template. + */ + @NetworkStats.Roaming + public int getRoaming() { + return mRoaming; + } + + /** + * Get the default network status filter of the template. + */ + @NetworkStats.DefaultNetwork + public int getDefaultNetworkStatus() { + return mDefaultNetwork; + } + + /** + * Get the Radio Access Technology(RAT) type filter of the template. + */ + public int getRatType() { + return mSubType; + } + + /** + * Get the OEM managed filter of the template. See {@code OEM_MANAGED_*} or + * {@code android.net.NetworkIdentity#OEM_*}. + */ + @OemManaged + public int getOemManaged() { + return mOemManaged; + } + + /** * Test if given {@link NetworkIdentity} matches this template. * * @hide @@ -680,10 +736,10 @@ public final class NetworkTemplate implements Parcelable { /** * Check if network with matching SSID. Returns true when the SSID matches, or when - * {@code mNetworkId} is {@code WIFI_NETWORKID_ALL}. + * {@code mNetworkId} is {@code WIFI_NETWORK_KEY_ALL}. */ private boolean matchesWifiNetworkId(@Nullable String networkId) { - return Objects.equals(mNetworkId, WIFI_NETWORKID_ALL) + return Objects.equals(mNetworkId, WIFI_NETWORK_KEY_ALL) || Objects.equals(sanitizeSsid(mNetworkId), sanitizeSsid(networkId)); } @@ -948,4 +1004,184 @@ public final class NetworkTemplate implements Parcelable { return new NetworkTemplate[size]; } }; + + /** + * Builder class for NetworkTemplate. + */ + public static final class Builder { + private final int mMatchRule; + // Use a SortedSet to provide a deterministic order when fetching the first one. + @NonNull + private final SortedSet<String> mMatchSubscriberIds = new TreeSet<>(); + @Nullable + private String mWifiNetworkKey; + + // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*. + private int mMetered; + private int mRoaming; + private int mDefaultNetwork; + private int mRatType; + + // Bitfield containing OEM network properties {@code NetworkIdentity#OEM_*}. + private int mOemManaged; + + /** + * Creates a new Builder with given match rule to construct NetworkTemplate objects. + * + * @param matchRule the match rule of the template, see {@code MATCH_*}. + */ + public Builder(@TemplateMatchRule final int matchRule) { + assertRequestableMatchRule(matchRule); + // Initialize members with default values. + mMatchRule = matchRule; + mWifiNetworkKey = WIFI_NETWORK_KEY_ALL; + mMetered = METERED_ALL; + mRoaming = ROAMING_ALL; + mDefaultNetwork = DEFAULT_NETWORK_ALL; + mRatType = NETWORK_TYPE_ALL; + mOemManaged = OEM_MANAGED_ALL; + } + + /** + * Set the Subscriber Ids. Calling this function with an empty set represents + * the intention of matching any Subscriber Ids. + * + * @param subscriberIds the list of Subscriber Ids. + * @return this builder. + */ + @NonNull + public Builder setSubscriberIds(@NonNull Set<String> subscriberIds) { + Objects.requireNonNull(subscriberIds); + mMatchSubscriberIds.clear(); + mMatchSubscriberIds.addAll(subscriberIds); + return this; + } + + /** + * Set the Wifi Network Key. + * + * @param wifiNetworkKey the Wifi Network Key, see {@link WifiInfo#getCurrentNetworkKey()}. + * Or null to match all networks. + * @return this builder. + */ + @NonNull + public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) { + mWifiNetworkKey = wifiNetworkKey; + return this; + } + + /** + * Set the meteredness filter. + * + * @param metered the meteredness filter. + * @return this builder. + */ + @NonNull + public Builder setMeteredness(@NetworkStats.Meteredness int metered) { + mMetered = metered; + return this; + } + + /** + * Set the roaming filter. + * + * @param roaming the roaming filter. + * @return this builder. + */ + @NonNull + public Builder setRoaming(@NetworkStats.Roaming int roaming) { + mRoaming = roaming; + return this; + } + + /** + * Set the default network status filter. + * + * @param defaultNetwork the default network status filter. + * @return this builder. + */ + @NonNull + public Builder setDefaultNetworkStatus(@NetworkStats.DefaultNetwork int defaultNetwork) { + mDefaultNetwork = defaultNetwork; + return this; + } + + /** + * Set the Radio Access Technology(RAT) type filter. + * + * @param ratType the Radio Access Technology(RAT) type filter. Use + * {@link #NETWORK_TYPE_ALL} to include all network types when filtering. + * See {@code TelephonyManager.NETWORK_TYPE_*}. + * @return this builder. + */ + @NonNull + public Builder setRatType(@NetworkType int ratType) { + // Input will be validated with the match rule when building the template. + mRatType = ratType; + return this; + } + + /** + * Set the OEM managed filter. + * + * @param oemManaged the match rule to match different type of OEM managed network or + * unmanaged networks. See {@code OEM_MANAGED_*}. + * @return this builder. + */ + @NonNull + public Builder setOemManaged(@OemManaged int oemManaged) { + mOemManaged = oemManaged; + return this; + } + + /** + * Check whether the match rule is requestable. + * + * @param matchRule the target match rule to be checked. + */ + private static void assertRequestableMatchRule(final int matchRule) { + if (!isKnownMatchRule(matchRule) + || matchRule == MATCH_PROXY + || matchRule == MATCH_MOBILE_WILDCARD + || matchRule == MATCH_WIFI_WILDCARD) { + throw new IllegalArgumentException("Invalid match rule: " + + getMatchRuleName(matchRule)); + } + } + + private void assertRequestableParameters() { + // TODO: Check all the input are legitimate. + } + + /** + * For backward compatibility, deduce match rule to a wildcard match rule + * if the Subscriber Ids are empty. + */ + private int getWildcardDeducedMatchRule() { + if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) { + return MATCH_MOBILE_WILDCARD; + } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty() + && mWifiNetworkKey == WIFI_NETWORK_KEY_ALL) { + return MATCH_WIFI_WILDCARD; + } + return mMatchRule; + } + + /** + * Builds the instance of the NetworkTemplate. + * + * @return the built instance of NetworkTemplate. + */ + @NonNull + public NetworkTemplate build() { + assertRequestableParameters(); + final int subscriberIdMatchRule = mMatchSubscriberIds.isEmpty() + ? SUBSCRIBER_ID_MATCH_RULE_ALL : SUBSCRIBER_ID_MATCH_RULE_EXACT; + return new NetworkTemplate(getWildcardDeducedMatchRule(), + mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(), + mMatchSubscriberIds.toArray(new String[0]), + mWifiNetworkKey, mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged, + subscriberIdMatchRule); + } + } } diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml index 918635d666fa..c88e95f07f12 100644 --- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml +++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml @@ -323,6 +323,46 @@ </FrameLayout> </LinearLayout> + <LinearLayout + android:id="@+id/wifi_scan_notify_layout" + style="@style/InternetDialog.Network" + android:orientation="vertical" + android:layout_height="wrap_content" + android:paddingBottom="4dp" + android:clickable="false" + android:focusable="false"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="56dp" + android:gravity="start|top" + android:orientation="horizontal" + android:paddingEnd="12dp" + android:paddingTop="16dp" + android:paddingBottom="4dp"> + <ImageView + android:src="@drawable/ic_info_outline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:tint="?android:attr/textColorTertiary"/> + </LinearLayout> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + <TextView + android:id="@+id/wifi_scan_notify_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="16dp" + android:paddingBottom="8dp" + android:textColor="?android:attr/textColorSecondary" + android:clickable="true"/> + </LinearLayout> + </LinearLayout> + <FrameLayout android:id="@+id/done_layout" android:layout_width="67dp" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7aacb702b75a..4ad4fa9d0854 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -3033,4 +3033,6 @@ <string name="see_all_networks">See all</string> <!-- Summary for warning to disconnect ethernet first then switch to other networks. [CHAR LIMIT=60] --> <string name="to_switch_networks_disconnect_ethernet">To switch networks, disconnect ethernet</string> + <!-- Message to describe "Wi-Fi scan always available feature" when Wi-Fi is off and Wi-Fi scanning is on. [CHAR LIMIT=NONE] --> + <string name="wifi_scan_notify_message">To improve device experience, apps and services can still scan for Wi\u2011Fi networks at any time, even when Wi\u2011Fi is off. You can change this in Wi\u2011Fi scanning settings. <annotation id="link">Change</annotation></string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpan.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpan.java index d8e80fe99331..0d7551ff66e9 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpan.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpan.java @@ -30,7 +30,7 @@ import java.util.Optional; /** * A span that turns the text wrapped by annotation tag into the clickable link text. */ -class AnnotationLinkSpan extends ClickableSpan { +public class AnnotationLinkSpan extends ClickableSpan { private final Optional<View.OnClickListener> mClickListener; private AnnotationLinkSpan(View.OnClickListener listener) { @@ -50,7 +50,7 @@ class AnnotationLinkSpan extends ClickableSpan { * @param linkInfos used to attach the click action into the corresponding span * @return the text attached with the span */ - static CharSequence linkify(CharSequence text, LinkInfo... linkInfos) { + public static CharSequence linkify(CharSequence text, LinkInfo... linkInfos) { final SpannableString msg = new SpannableString(text); final Annotation[] spans = msg.getSpans(/* queryStart= */ 0, msg.length(), Annotation.class); @@ -78,12 +78,12 @@ class AnnotationLinkSpan extends ClickableSpan { /** * Data class to store the annotation and the click action. */ - static class LinkInfo { - static final String DEFAULT_ANNOTATION = "link"; + public static class LinkInfo { + public static final String DEFAULT_ANNOTATION = "link"; private final Optional<String> mAnnotation; private final Optional<View.OnClickListener> mListener; - LinkInfo(@NonNull String annotation, View.OnClickListener listener) { + public LinkInfo(@NonNull String annotation, View.OnClickListener listener) { mAnnotation = Optional.of(annotation); mListener = Optional.ofNullable(listener); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java index dc54e1b52f2e..dae357e9e36b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java @@ -36,6 +36,7 @@ import android.telephony.TelephonyDisplayInfo; import android.telephony.TelephonyManager; import android.text.Html; import android.text.TextUtils; +import android.text.method.LinkMovementMethod; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -63,6 +64,7 @@ import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.Prefs; import com.android.systemui.R; +import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.phone.SystemUIDialog; @@ -110,6 +112,8 @@ public class InternetDialog extends SystemUIDialog implements private LinearLayout mTurnWifiOnLayout; private LinearLayout mEthernetLayout; private TextView mWifiToggleTitleText; + private LinearLayout mWifiScanNotifyLayout; + private TextView mWifiScanNotifyText; private LinearLayout mSeeAllLayout; private RecyclerView mWifiRecyclerView; private ImageView mConnectedWifiIcon; @@ -220,6 +224,8 @@ public class InternetDialog extends SystemUIDialog implements mMobileNetworkLayout = mDialogView.requireViewById(R.id.mobile_network_layout); mTurnWifiOnLayout = mDialogView.requireViewById(R.id.turn_on_wifi_layout); mWifiToggleTitleText = mDialogView.requireViewById(R.id.wifi_toggle_title); + mWifiScanNotifyLayout = mDialogView.requireViewById(R.id.wifi_scan_notify_layout); + mWifiScanNotifyText = mDialogView.requireViewById(R.id.wifi_scan_notify_text); mConnectedWifListLayout = mDialogView.requireViewById(R.id.wifi_connected_layout); mConnectedWifiIcon = mDialogView.requireViewById(R.id.wifi_connected_icon); mConnectedWifiTitleText = mDialogView.requireViewById(R.id.wifi_connected_title); @@ -313,8 +319,10 @@ public class InternetDialog extends SystemUIDialog implements showProgressBar(); final boolean isDeviceLocked = mInternetDialogController.isDeviceLocked(); final boolean isWifiEnabled = mWifiManager.isWifiEnabled(); + final boolean isWifiScanEnabled = mWifiManager.isScanAlwaysAvailable(); updateWifiToggle(isWifiEnabled, isDeviceLocked); updateConnectedWifi(isWifiEnabled, isDeviceLocked); + updateWifiScanNotify(isWifiEnabled, isWifiScanEnabled, isDeviceLocked); final int visibility = (isDeviceLocked || !isWifiEnabled || mWifiEntriesCount <= 0) ? View.GONE : View.VISIBLE; @@ -411,6 +419,24 @@ public class InternetDialog extends SystemUIDialog implements mContext.getColor(R.color.connected_network_primary_color)); } + @MainThread + private void updateWifiScanNotify(boolean isWifiEnabled, boolean isWifiScanEnabled, + boolean isDeviceLocked) { + if (isWifiEnabled || !isWifiScanEnabled || isDeviceLocked) { + mWifiScanNotifyLayout.setVisibility(View.GONE); + return; + } + if (TextUtils.isEmpty(mWifiScanNotifyText.getText())) { + final AnnotationLinkSpan.LinkInfo linkInfo = new AnnotationLinkSpan.LinkInfo( + AnnotationLinkSpan.LinkInfo.DEFAULT_ANNOTATION, + v -> mInternetDialogController.launchWifiScanningSetting()); + mWifiScanNotifyText.setText(AnnotationLinkSpan.linkify( + getContext().getText(R.string.wifi_scan_notify_message), linkInfo)); + mWifiScanNotifyText.setMovementMethod(LinkMovementMethod.getInstance()); + } + mWifiScanNotifyLayout.setVisibility(View.VISIBLE); + } + void onClickConnectedWifi() { if (mConnectedWifiEntry == null) { return; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index aaba5efc92f6..276c0be53063 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -103,6 +103,8 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, private static final String TAG = "InternetDialogController"; private static final String ACTION_NETWORK_PROVIDER_SETTINGS = "android.settings.NETWORK_PROVIDER_SETTINGS"; + private static final String ACTION_WIFI_SCANNING_SETTINGS = + "android.settings.WIFI_SCANNING_SETTINGS"; private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key"; public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT); public static final int NO_CELL_DATA_TYPE_ICON = 0; @@ -603,6 +605,13 @@ public class InternetDialogController implements WifiEntry.DisconnectCallback, } } + void launchWifiScanningSetting() { + mCallback.dismissDialog(); + final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mActivityStarter.postStartActivityDismissingKeyguard(intent, 0); + } + void connectCarrierNetwork() { final MergedCarrierEntry mergedCarrierEntry = mAccessPointController.getMergedCarrierEntry(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java index c42b64a09985..7cea430e146f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java @@ -19,6 +19,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.widget.LinearLayout; +import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import androidx.test.filters.SmallTest; @@ -73,6 +74,7 @@ public class InternetDialogTest extends SysuiTestCase { private LinearLayout mConnectedWifi; private RecyclerView mWifiList; private LinearLayout mSeeAll; + private LinearLayout mWifiScanNotify; @Before public void setUp() { @@ -104,6 +106,7 @@ public class InternetDialogTest extends SysuiTestCase { mConnectedWifi = mDialogView.requireViewById(R.id.wifi_connected_layout); mWifiList = mDialogView.requireViewById(R.id.wifi_list_layout); mSeeAll = mDialogView.requireViewById(R.id.see_all_layout); + mWifiScanNotify = mDialogView.requireViewById(R.id.wifi_scan_notify_layout); } @After @@ -264,6 +267,50 @@ public class InternetDialogTest extends SysuiTestCase { } @Test + public void updateDialog_wifiOn_hideWifiScanNotify() { + // The preconditions WiFi ON and Internet WiFi are already in setUp() + + mInternetDialog.updateDialog(); + + assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() { + when(mWifiManager.isWifiEnabled()).thenReturn(false); + when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false); + + mInternetDialog.updateDialog(); + + assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() { + when(mWifiManager.isWifiEnabled()).thenReturn(false); + when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true); + when(mInternetDialogController.isDeviceLocked()).thenReturn(true); + + mInternetDialog.updateDialog(); + + assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE); + } + + @Test + public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() { + when(mWifiManager.isWifiEnabled()).thenReturn(false); + when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true); + when(mInternetDialogController.isDeviceLocked()).thenReturn(false); + + mInternetDialog.updateDialog(); + + assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.VISIBLE); + TextView wifiScanNotifyText = mDialogView.requireViewById(R.id.wifi_scan_notify_text); + assertThat(wifiScanNotifyText.getText().length()).isNotEqualTo(0); + assertThat(wifiScanNotifyText.getMovementMethod()).isNotNull(); + } + + @Test public void onClickSeeMoreButton_clickSeeAll_verifyLaunchNetworkSetting() { mSeeAll.performClick(); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 5de5fd3cc79c..dee69e02b371 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -2456,7 +2456,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { networkId, templateMeteredness, NetworkStats.ROAMING_ALL, NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL, NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule); - if (template.isPersistable()) { + if (NetworkPolicy.isTemplatePersistable(template)) { mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule, warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze, metered, inferred)); @@ -2663,7 +2663,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { for (int i = 0; i < mNetworkPolicy.size(); i++) { final NetworkPolicy policy = mNetworkPolicy.valueAt(i); final NetworkTemplate template = policy.template; - if (!template.isPersistable()) continue; + if (!NetworkPolicy.isTemplatePersistable(template)) continue; out.startTag(null, TAG_NETWORK_POLICY); writeIntAttribute(out, ATTR_NETWORK_TEMPLATE, template.getMatchRule()); diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index 4a913e4edd71..cecbeed67f68 100644 --- a/services/core/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java @@ -124,16 +124,10 @@ public final class SELinuxMMAC { } // Vendor mac permissions. - // The filename has been renamed from nonplat_mac_permissions to - // vendor_mac_permissions. Either of them should exist. final File vendorMacPermission = new File( Environment.getVendorDirectory(), "/etc/selinux/vendor_mac_permissions.xml"); if (vendorMacPermission.exists()) { sMacPermissions.add(vendorMacPermission); - } else { - // For backward compatibility. - sMacPermissions.add(new File(Environment.getVendorDirectory(), - "/etc/selinux/nonplat_mac_permissions.xml")); } // ODM mac permissions (optional). diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index bd688a618c63..52da4b80a75d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2125,6 +2125,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final Task rootTask; if (singleActivity) { rootTask = task; + + // Apply the last recents animation leash transform to the task entering PIP + rootTask.maybeApplyLastRecentsAnimationTransaction(); } else { // In the case of multiple activities, we will create a new task for it and then // move the PIP activity into the task. Note that we explicitly defer the task diff --git a/services/proguard.flags b/services/proguard.flags index 30dd6cf545b9..5d01d3e7f85c 100644 --- a/services/proguard.flags +++ b/services/proguard.flags @@ -1,11 +1,21 @@ # TODO(b/196084106): Refine and optimize this configuration. Note that this # configuration is only used when `SOONG_CONFIG_ANDROID_SYSTEM_OPTIMIZE_JAVA=true`. -keep,allowoptimization,allowaccessmodification class ** { - *; + !synthetic *; } # Various classes subclassed in ethernet-service (avoid marking final). -keep public class android.net.** { *; } # Referenced via CarServiceHelperService in car-frameworks-service (avoid removing). --keep public class com.android.server.utils.Slogf { *; }
\ No newline at end of file +-keep public class com.android.server.utils.Slogf { *; } + +# Allows making private and protected methods/fields public as part of +# optimization. This enables inlining of trivial getter/setter methods. +-allowaccessmodification + +# Disallow accessmodification for soundtrigger classes. Logging via reflective +# public member traversal can cause infinite loops. See b/210901706. +-keep,allowoptimization class com.android.server.soundtrigger_middleware.** { + !synthetic *; +} diff --git a/telephony/common/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java index e2d62f868d52..6d9b3210ea70 100644 --- a/telephony/common/com/google/android/mms/util/SqliteWrapper.java +++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java @@ -17,7 +17,6 @@ package com.google.android.mms.util; -import android.app.ActivityManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.content.ContentValues; @@ -25,49 +24,15 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.net.Uri; -import android.os.Build; import android.util.Log; -import android.widget.Toast; public final class SqliteWrapper { private static final String TAG = "SqliteWrapper"; - private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE - = "unable to open database file"; private SqliteWrapper() { // Forbidden being instantiated. } - // FIXME: It looks like outInfo.lowMemory does not work well as we expected. - // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false. - private static boolean isLowMemory(Context context) { - if (null == context) { - return false; - } - - ActivityManager am = (ActivityManager) - context.getSystemService(Context.ACTIVITY_SERVICE); - ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); - am.getMemoryInfo(outInfo); - - return outInfo.lowMemory; - } - - // FIXME: need to optimize this method. - private static boolean isLowMemory(SQLiteException e) { - return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE); - } - - @UnsupportedAppUsage - public static void checkSQLiteException(Context context, SQLiteException e) { - if (isLowMemory(e)) { - Toast.makeText(context, com.android.internal.R.string.low_memory, - Toast.LENGTH_SHORT).show(); - } else { - throw e; - } - } - @UnsupportedAppUsage public static Cursor query(Context context, ContentResolver resolver, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { @@ -75,21 +40,10 @@ public final class SqliteWrapper { return resolver.query(uri, projection, selection, selectionArgs, sortOrder); } catch (SQLiteException e) { Log.e(TAG, "Catch a SQLiteException when query: ", e); - checkSQLiteException(context, e); return null; } } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static boolean requery(Context context, Cursor cursor) { - try { - return cursor.requery(); - } catch (SQLiteException e) { - Log.e(TAG, "Catch a SQLiteException when requery: ", e); - checkSQLiteException(context, e); - return false; - } - } @UnsupportedAppUsage public static int update(Context context, ContentResolver resolver, Uri uri, ContentValues values, String where, String[] selectionArgs) { @@ -97,7 +51,6 @@ public final class SqliteWrapper { return resolver.update(uri, values, where, selectionArgs); } catch (SQLiteException e) { Log.e(TAG, "Catch a SQLiteException when update: ", e); - checkSQLiteException(context, e); return -1; } } @@ -109,7 +62,6 @@ public final class SqliteWrapper { return resolver.delete(uri, where, selectionArgs); } catch (SQLiteException e) { Log.e(TAG, "Catch a SQLiteException when delete: ", e); - checkSQLiteException(context, e); return -1; } } @@ -121,7 +73,6 @@ public final class SqliteWrapper { return resolver.insert(uri, values); } catch (SQLiteException e) { Log.e(TAG, "Catch a SQLiteException when insert: ", e); - checkSQLiteException(context, e); return null; } } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 95b9fda34211..5851ee182368 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -964,6 +964,21 @@ public class CarrierConfigManager { = "carrier_use_ims_first_for_emergency_bool"; /** + * When {@code true}, the determination of whether to place a call as an emergency call will be + * based on the known {@link android.telephony.emergency.EmergencyNumber}s for the SIM on which + * the call is being placed. In a dual SIM scenario, if Sim A has the emergency numbers + * 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789, + * it will not be treated as an emergency call in this case. + * When {@code false}, the determination is based on the emergency numbers from all device SIMs, + * regardless of which SIM the call is being placed on. If Sim A has the emergency numbers + * 123, 456 and Sim B has the emergency numbers 789, and the user places a call on SIM A to 789, + * the call will be dialed as an emergency number, but with an unspecified routing. + * @hide + */ + public static final String KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL = + "use_only_dialed_sim_ecc_list_bool"; + + /** * When IMS instant lettering is available for a carrier (see * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines the list of characters * which may not be contained in messages. Should be specified as a regular expression suitable @@ -5339,6 +5354,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_IMS_GBA_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true); + sDefaults.putBoolean(KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, false); sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING, ""); sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING, ""); sDefaults.putString(KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING, ""); |