summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt3
-rw-r--r--api/system-current.txt7
-rw-r--r--api/test-current.txt3
-rw-r--r--config/OWNERS5
-rw-r--r--core/java/android/app/ContextImpl.java9
-rw-r--r--core/java/android/content/Context.java28
-rw-r--r--core/java/android/content/ContextWrapper.java6
-rw-r--r--core/java/android/net/ConnectivityManager.java40
-rw-r--r--core/java/android/net/NetworkKey.java37
-rw-r--r--core/java/android/os/SystemProperties.java112
-rw-r--r--core/java/android/telephony/PhoneStateListener.java3
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java9
-rw-r--r--core/java/com/android/internal/app/LocaleHelper.java2
-rw-r--r--core/jni/android_os_SystemProperties.cpp215
-rw-r--r--core/tests/coretests/src/android/net/NetworkKeyTest.java24
-rw-r--r--core/tests/systemproperties/src/android/os/SystemPropertiesTest.java21
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java183
-rw-r--r--services/core/java/com/android/server/pm/OWNERS3
-rw-r--r--services/core/java/com/android/server/recoverysystem/RecoverySystemService.java (renamed from services/core/java/com/android/server/RecoverySystemService.java)4
-rw-r--r--services/java/com/android/server/SystemServer.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java5
-rw-r--r--telecomm/java/android/telecom/Conference.java1
-rw-r--r--telecomm/java/android/telecom/Connection.java1
-rw-r--r--telephony/java/android/telephony/Annotation.java40
-rw-r--r--telephony/java/android/telephony/PreciseCallState.java34
-rw-r--r--telephony/java/android/telephony/ServiceState.java27
-rw-r--r--telephony/java/android/telephony/SmsCbLocation.java7
-rw-r--r--telephony/java/android/telephony/SmsCbMessage.java17
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java27
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java5
-rw-r--r--test-mock/src/android/test/mock/MockContext.java6
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java5
-rw-r--r--wifi/java/android/net/wifi/WifiSsid.java2
33 files changed, 603 insertions, 289 deletions
diff --git a/api/current.txt b/api/current.txt
index 6f97fdd5ffd9..c657756ba3e9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9772,7 +9772,7 @@ package android.content {
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String);
method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
- method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
+ method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent);
method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
@@ -29892,6 +29892,7 @@ package android.net.wifi {
field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
+ field public static final String UNKNOWN_SSID = "<unknown ssid>";
field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1
field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
diff --git a/api/system-current.txt b/api/system-current.txt
index b92462d1ca60..685238a7ba02 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1366,8 +1366,9 @@ package android.content {
public abstract class Context {
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public boolean bindServiceAsUser(@RequiresPermission android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
+ method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
method public abstract android.content.Context createCredentialProtectedStorageContext();
- method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method @Nullable public abstract java.io.File getPreloadsFileCache();
method public abstract boolean isCredentialProtectedStorage();
method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
@@ -8141,6 +8142,7 @@ package android.telephony {
}
public final class SmsCbLocation implements android.os.Parcelable {
+ ctor public SmsCbLocation(@NonNull String, int, int);
method public int describeContents();
method public int getCid();
method public int getLac();
@@ -8152,7 +8154,7 @@ package android.telephony {
}
public final class SmsCbMessage implements android.os.Parcelable {
- ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int);
+ ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int);
method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
method public int describeContents();
method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
@@ -8179,6 +8181,7 @@ package android.telephony {
field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0
field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2
field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1
+ field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff
field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1
field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2
field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3
diff --git a/api/test-current.txt b/api/test-current.txt
index eaf1fd793750..92d89d40dff9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -640,7 +640,8 @@ package android.content {
}
public abstract class Context {
- method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int);
+ method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.view.Display getDisplay();
method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
diff --git a/config/OWNERS b/config/OWNERS
new file mode 100644
index 000000000000..53f80e698d83
--- /dev/null
+++ b/config/OWNERS
@@ -0,0 +1,5 @@
+# compat-team@ for changes to hiddenapi files
+per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com
+
+# Escalations:
+per-file hiddenapi-* = bdc@google.com, narayan@google.com \ No newline at end of file
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 9902f6aa0fe3..794ffcb83078 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2224,6 +2224,15 @@ class ContextImpl extends Context {
}
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ try {
+ return createPackageContextAsUser(getPackageName(), flags, user);
+ } catch (NameNotFoundException e) {
+ throw new IllegalStateException("Own package not found: package=" + getPackageName());
+ }
+ }
+
+ @Override
public Context createContextForSplit(String splitName) throws NameNotFoundException {
if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
// All Splits are always loaded.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a12e4da6e23e..4b22166a9688 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2424,10 +2424,10 @@ public abstract class Context {
*
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
*/
- public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent,
- @Nullable String receiverPermission, @Nullable String receiverAppOp,
- @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
- int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
+ public void sendOrderedBroadcast(@NonNull Intent intent, @Nullable String receiverPermission,
+ @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver,
+ @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+ @Nullable Bundle initialExtras) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
@@ -5256,8 +5256,9 @@ public abstract class Context {
*/
@SystemApi
@TestApi
+ @NonNull
public Context createPackageContextAsUser(
- String packageName, @CreatePackageOptions int flags, UserHandle user)
+ @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user)
throws PackageManager.NameNotFoundException {
if (Build.IS_ENG) {
throw new IllegalStateException("createPackageContextAsUser not overridden!");
@@ -5266,6 +5267,23 @@ public abstract class Context {
}
/**
+ * Similar to {@link #createPackageContext(String, int)}, but for the own package with a
+ * different {@link UserHandle}. For example, {@link #getContentResolver()}
+ * will open any {@link Uri} as the given user.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @NonNull
+ public Context createContextAsUser(@NonNull UserHandle user, @CreatePackageOptions int flags) {
+ if (Build.IS_ENG) {
+ throw new IllegalStateException("createContextAsUser not overridden!");
+ }
+ return this;
+ }
+
+ /**
* Creates a context given an {@link android.content.pm.ApplicationInfo}.
*
* @hide
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 2b1b8eb183ab..428aadb5c3f6 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -898,6 +898,12 @@ public class ContextWrapper extends Context {
/** @hide */
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ return mBase.createContextAsUser(user, flags);
+ }
+
+ /** @hide */
+ @Override
@UnsupportedAppUsage
public Context createApplicationContext(ApplicationInfo application,
int flags) throws PackageManager.NameNotFoundException {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 75af41cb2b54..56bacf29ac73 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -52,13 +52,12 @@ import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
@@ -711,6 +710,12 @@ public class ConnectivityManager {
@Deprecated
public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
+ // Deprecated constants for return values of startUsingNetworkFeature. They used to live
+ // in com.android.internal.telephony.PhoneConstants until they were made inaccessible.
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0;
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1;
+ private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3;
+
/** {@hide} */
public static final int MAX_RADIO_TYPE = TYPE_TEST;
@@ -1407,7 +1412,7 @@ public class ConnectivityManager {
if (netCap == null) {
Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
feature);
- return PhoneConstants.APN_REQUEST_FAILED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
}
NetworkRequest request = null;
@@ -1417,9 +1422,9 @@ public class ConnectivityManager {
Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
renewRequestLocked(l);
if (l.currentNetwork != null) {
- return PhoneConstants.APN_ALREADY_ACTIVE;
+ return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE;
} else {
- return PhoneConstants.APN_REQUEST_STARTED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
}
}
@@ -1427,10 +1432,10 @@ public class ConnectivityManager {
}
if (request != null) {
Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
- return PhoneConstants.APN_REQUEST_STARTED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED;
} else {
Log.d(TAG, " request Failed");
- return PhoneConstants.APN_REQUEST_FAILED;
+ return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED;
}
}
@@ -2149,19 +2154,14 @@ public class ConnectivityManager {
@Deprecated
@UnsupportedAppUsage
public boolean getMobileDataEnabled() {
- IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
- if (b != null) {
- try {
- ITelephony it = ITelephony.Stub.asInterface(b);
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
- Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
- boolean retVal = it.isUserDataEnabled(subId);
- Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
- + " retVal=" + retVal);
- return retVal;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+ if (tm != null) {
+ int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
+ boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled();
+ Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
+ + " retVal=" + retVal);
+ return retVal;
}
Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
return false;
diff --git a/core/java/android/net/NetworkKey.java b/core/java/android/net/NetworkKey.java
index a101da7b4b9c..04cb877305b9 100644
--- a/core/java/android/net/NetworkKey.java
+++ b/core/java/android/net/NetworkKey.java
@@ -21,7 +21,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -69,22 +69,25 @@ public class NetworkKey implements Parcelable {
*/
@Nullable
public static NetworkKey createFromScanResult(@Nullable ScanResult result) {
- if (result != null && result.wifiSsid != null) {
- final String ssid = result.wifiSsid.toString();
- final String bssid = result.BSSID;
- if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE)
- && !TextUtils.isEmpty(bssid)) {
- WifiKey wifiKey;
- try {
- wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Unable to create WifiKey.", e);
- return null;
- }
- return new NetworkKey(wifiKey);
- }
+ if (result == null) {
+ return null;
+ }
+ final String ssid = result.SSID;
+ if (TextUtils.isEmpty(ssid) || ssid.equals(WifiManager.UNKNOWN_SSID)) {
+ return null;
+ }
+ final String bssid = result.BSSID;
+ if (TextUtils.isEmpty(bssid)) {
+ return null;
+ }
+
+ try {
+ final WifiKey wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid);
+ return new NetworkKey(wifiKey);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unable to create WifiKey.", e);
+ return null;
}
- return null;
}
/**
@@ -100,7 +103,7 @@ public class NetworkKey implements Parcelable {
if (wifiInfo != null) {
final String ssid = wifiInfo.getSSID();
final String bssid = wifiInfo.getBSSID();
- if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE)
+ if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiManager.UNKNOWN_SSID)
&& !TextUtils.isEmpty(bssid)) {
WifiKey wifiKey;
try {
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 8b0ffe155fc3..f08e1ff16999 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -26,6 +26,9 @@ import android.util.MutableInt;
import com.android.internal.annotations.GuardedBy;
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
import libcore.util.HexEncoding;
import java.nio.charset.StandardCharsets;
@@ -93,18 +96,43 @@ public class SystemProperties {
}
}
+ // The one-argument version of native_get used to be a regular native function. Nowadays,
+ // we use the two-argument form of native_get all the time, but we can't just delete the
+ // one-argument overload: apps use it via reflection, as the UnsupportedAppUsage annotation
+ // indicates. Let's just live with having a Java function with a very unusual name.
@UnsupportedAppUsage
- private static native String native_get(String key);
+ private static String native_get(String key) {
+ return native_get(key, "");
+ }
+
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native String native_get(String key, String def);
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native int native_get_int(String key, int def);
+ @FastNative
@UnsupportedAppUsage
private static native long native_get_long(String key, long def);
+ @FastNative
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native boolean native_get_boolean(String key, boolean def);
+
+ @FastNative
+ private static native long native_find(String name);
+ @FastNative
+ private static native String native_get(long handle);
+ @CriticalNative
+ private static native int native_get_int(long handle, int def);
+ @CriticalNative
+ private static native long native_get_long(long handle, long def);
+ @CriticalNative
+ private static native boolean native_get_boolean(long handle, boolean def);
+
+ // _NOT_ FastNative: native_set performs IPC and can block
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native void native_set(String key, String def);
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static native void native_add_change_callback();
private static native void native_report_sysprop_change();
@@ -229,25 +257,27 @@ public class SystemProperties {
@SuppressWarnings("unused") // Called from native code.
private static void callChangeCallbacks() {
+ ArrayList<Runnable> callbacks = null;
synchronized (sChangeCallbacks) {
//Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
if (sChangeCallbacks.size() == 0) {
return;
}
- ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
- final long token = Binder.clearCallingIdentity();
- try {
- for (int i = 0; i < callbacks.size(); i++) {
- try {
- callbacks.get(i).run();
- } catch (Throwable t) {
- Log.wtf(TAG, "Exception in SystemProperties change callback", t);
- // Ignore and try to go on.
- }
+ callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+ }
+ final long token = Binder.clearCallingIdentity();
+ try {
+ for (int i = 0; i < callbacks.size(); i++) {
+ try {
+ callbacks.get(i).run();
+ } catch (Throwable t) {
+ // Ignore and try to go on. Don't use wtf here: that
+ // will cause the process to exit on some builds and break tests.
+ Log.e(TAG, "Exception in SystemProperties change callback", t);
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -284,4 +314,60 @@ public class SystemProperties {
@UnsupportedAppUsage
private SystemProperties() {
}
+
+ /**
+ * Look up a property location by name.
+ * @name name of the property
+ * @return property handle or {@code null} if property isn't set
+ * @hide
+ */
+ @Nullable public static Handle find(@NonNull String name) {
+ long nativeHandle = native_find(name);
+ if (nativeHandle == 0) {
+ return null;
+ }
+ return new Handle(nativeHandle);
+ }
+
+ /**
+ * Handle to a pre-located property. Looking up a property handle in advance allows
+ * for optimal repeated lookup of a single property.
+ * @hide
+ */
+ public static final class Handle {
+
+ private final long mNativeHandle;
+
+ /**
+ * @return Value of the property
+ */
+ @NonNull public String get() {
+ return native_get(mNativeHandle);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public int getInt(int def) {
+ return native_get_int(mNativeHandle, def);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public long getLong(long def) {
+ return native_get_long(mNativeHandle, def);
+ }
+ /**
+ * @param def default value
+ * @return value or {@code def} on parse error
+ */
+ public boolean getBoolean(boolean def) {
+ return native_get_boolean(mNativeHandle, def);
+ }
+
+ private Handle(long nativeHandle) {
+ mNativeHandle = nativeHandle;
+ }
+ }
}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 2af827e36696..a65c8fdf50c9 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -184,7 +184,8 @@ public class PhoneStateListener {
public static final int LISTEN_CELL_INFO = 0x00000400;
/**
- * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls.
+ * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
+ * background and foreground calls.
*
* @hide
*/
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 456789fb77bc..5c427309e823 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -29,13 +29,13 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.telephony.Annotation;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseCallStates;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
@@ -43,7 +43,6 @@ import android.telephony.CallQuality;
import android.telephony.CellInfo;
import android.telephony.DisconnectCause;
import android.telephony.PhoneCapability;
-import android.telephony.PreciseCallState.State;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -624,8 +623,10 @@ public class TelephonyRegistryManager {
*
* @hide
*/
- public void notifyPreciseCallState(int subId, int slotIndex, @State int ringCallPreciseState,
- @State int foregroundCallPreciseState, @State int backgroundCallPreciseState) {
+ public void notifyPreciseCallState(int subId, int slotIndex,
+ @PreciseCallStates int ringCallPreciseState,
+ @PreciseCallStates int foregroundCallPreciseState,
+ @PreciseCallStates int backgroundCallPreciseState) {
try {
sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
foregroundCallPreciseState, backgroundCallPreciseState);
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index aef4dbf41d35..e3d07aaa8fe8 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -208,7 +208,7 @@ public class LocaleHelper {
* @return the maximized Locale instance.
*/
public static Locale addLikelySubtags(Locale locale) {
- return libcore.icu.ICU.addLikelySubtags(locale);
+ return ULocale.addLikelySubtags(ULocale.forLocale(locale)).toLocale();
}
/**
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 87f498a710c1..7f8bec6ce507 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -17,9 +17,13 @@
#define LOG_TAG "SysPropJNI"
+#include <utility>
+#include <optional>
+
#include "android-base/logging.h"
+#include "android-base/parsebool.h"
+#include "android-base/parseint.h"
#include "android-base/properties.h"
-#include "cutils/properties.h"
#include "utils/misc.h"
#include <utils/Log.h>
#include "jni.h"
@@ -28,86 +32,171 @@
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedUtfChars.h>
-namespace android
-{
+#if defined(__BIONIC__)
+# include <sys/system_properties.h>
+#else
+struct prop_info;
+#endif
+namespace android {
namespace {
-template <typename T, typename Handler>
-T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) {
- std::string key;
- {
- // Scope the String access. If the handler can throw an exception,
- // releasing the string characters late would trigger an abort.
- ScopedUtfChars key_utf(env, keyJ);
- if (key_utf.c_str() == nullptr) {
- return defJ;
- }
- key = key_utf.c_str(); // This will make a copy, but we can't avoid
- // with the existing interface in
- // android::base.
- }
- return handler(key, defJ);
-}
+using android::base::ParseBoolResult;
-jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ,
- jstring defJ)
+template<typename Functor>
+void ReadProperty(const prop_info* prop, Functor&& functor)
{
- // Using ConvertKeyAndForward is sub-optimal for copying the key string,
- // but improves reuse and reasoning over code.
- auto handler = [&](const std::string& key, jstring defJ) {
- std::string prop_val = android::base::GetProperty(key, "");
- if (!prop_val.empty()) {
- return env->NewStringUTF(prop_val.c_str());
- };
- if (defJ != nullptr) {
- return defJ;
- }
- // This function is specified to never return null (or have an
- // exception pending).
- return env->NewStringUTF("");
+#if defined(__BIONIC__)
+ auto thunk = [](void* cookie,
+ const char* /*name*/,
+ const char* value,
+ uint32_t /*serial*/) {
+ std::forward<Functor>(*static_cast<Functor*>(cookie))(value);
};
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
+ __system_property_read_callback(prop, thunk, &functor);
+#else
+ LOG(FATAL) << "fast property access supported only on device";
+#endif
}
-jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ)
+template<typename Functor>
+void ReadProperty(JNIEnv* env, jstring keyJ, Functor&& functor)
{
- return SystemProperties_getSS(env, clazz, keyJ, nullptr);
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return;
+ }
+#if defined(__BIONIC__)
+ const prop_info* prop = __system_property_find(key.c_str());
+ if (!prop) {
+ return;
+ }
+ ReadProperty(prop, std::forward<Functor>(functor));
+#else
+ std::forward<Functor>(functor)(
+ android::base::GetProperty(key.c_str(), "").c_str());
+#endif
+}
+
+jstring SystemProperties_getSS(JNIEnv* env, jclass clazz, jstring keyJ,
+ jstring defJ)
+{
+ jstring ret = defJ;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ if (value[0]) {
+ ret = env->NewStringUTF(value);
+ }
+ });
+ if (ret == nullptr && !env->ExceptionCheck()) {
+ ret = env->NewStringUTF(""); // Legacy behavior
+ }
+ return ret;
}
template <typename T>
T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ,
T defJ)
{
- auto handler = [](const std::string& key, T defV) {
- return android::base::GetIntProperty<T>(key, defV);
- };
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
+ T ret = defJ;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ android::base::ParseInt<T>(value, &ret);
+ });
+ return ret;
+}
+
+static jboolean jbooleanFromParseBoolResult(ParseBoolResult parseResult, jboolean defJ) {
+ jboolean ret;
+ switch (parseResult) {
+ case ParseBoolResult::kError:
+ ret = defJ;
+ break;
+ case ParseBoolResult::kFalse:
+ ret = JNI_FALSE;
+ break;
+ case ParseBoolResult::kTrue:
+ ret = JNI_TRUE;
+ break;
+ }
+ return ret;
}
jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ,
jboolean defJ)
{
- auto handler = [](const std::string& key, jboolean defV) -> jboolean {
- bool result = android::base::GetBoolProperty(key, defV);
- return result ? JNI_TRUE : JNI_FALSE;
- };
- return ConvertKeyAndForward(env, keyJ, defJ, handler);
+ ParseBoolResult parseResult;
+ ReadProperty(env, keyJ, [&](const char* value) {
+ parseResult = android::base::ParseBool(value);
+ });
+ return jbooleanFromParseBoolResult(parseResult, defJ);
+}
+
+jlong SystemProperties_find(JNIEnv* env, jclass, jstring keyJ)
+{
+#if defined(__BIONIC__)
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return 0;
+ }
+ const prop_info* prop = __system_property_find(key.c_str());
+ return reinterpret_cast<jlong>(prop);
+#else
+ LOG(FATAL) << "fast property access supported only on device";
+ __builtin_unreachable(); // Silence warning
+#endif
+}
+
+jstring SystemProperties_getH(JNIEnv* env, jclass clazz, jlong propJ)
+{
+ jstring ret;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ ret = env->NewStringUTF(value);
+ });
+ return ret;
+}
+
+template <typename T>
+T SystemProperties_get_integralH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, T defJ)
+{
+ T ret = defJ;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ android::base::ParseInt<T>(value, &ret);
+ });
+ return ret;
+}
+
+jboolean SystemProperties_get_booleanH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, jboolean defJ)
+{
+ ParseBoolResult parseResult;
+ auto prop = reinterpret_cast<const prop_info*>(propJ);
+ ReadProperty(prop, [&](const char* value) {
+ parseResult = android::base::ParseBool(value);
+ });
+ return jbooleanFromParseBoolResult(parseResult, defJ);
}
void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ,
jstring valJ)
{
- auto handler = [&](const std::string& key, bool) {
- std::string val;
- if (valJ != nullptr) {
- ScopedUtfChars key_utf(env, valJ);
- val = key_utf.c_str();
+ ScopedUtfChars key(env, keyJ);
+ if (!key.c_str()) {
+ return;
+ }
+ std::optional<ScopedUtfChars> value;
+ if (valJ != nullptr) {
+ value.emplace(env, valJ);
+ if (!value->c_str()) {
+ return;
}
- return android::base::SetProperty(key, val);
- };
- if (!ConvertKeyAndForward(env, keyJ, true, handler)) {
- // Must have been a failure in SetProperty.
+ }
+ bool success;
+#if defined(__BIONIC__)
+ success = !__system_property_set(key.c_str(), value ? value->c_str() : "");
+#else
+ success = android::base::SetProperty(key.c_str(), value ? value->c_str() : "");
+#endif
+ if (!success) {
jniThrowException(env, "java/lang/RuntimeException",
"failed to set system property (check logcat for reason)");
}
@@ -157,8 +246,6 @@ void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
int register_android_os_SystemProperties(JNIEnv *env)
{
const JNINativeMethod method_table[] = {
- { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
- (void*) SystemProperties_getS },
{ "native_get",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
(void*) SystemProperties_getSS },
@@ -168,6 +255,18 @@ int register_android_os_SystemProperties(JNIEnv *env)
(void*) SystemProperties_get_integral<jlong> },
{ "native_get_boolean", "(Ljava/lang/String;Z)Z",
(void*) SystemProperties_get_boolean },
+ { "native_find",
+ "(Ljava/lang/String;)J",
+ (void*) SystemProperties_find },
+ { "native_get",
+ "(J)Ljava/lang/String;",
+ (void*) SystemProperties_getH },
+ { "native_get_int", "(JI)I",
+ (void*) SystemProperties_get_integralH<jint> },
+ { "native_get_long", "(JJ)J",
+ (void*) SystemProperties_get_integralH<jlong> },
+ { "native_get_boolean", "(JZ)Z",
+ (void*) SystemProperties_get_booleanH },
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
{ "native_add_change_callback", "()V",
@@ -179,4 +278,4 @@ int register_android_os_SystemProperties(JNIEnv *env)
method_table, NELEM(method_table));
}
-};
+} // namespace android
diff --git a/core/tests/coretests/src/android/net/NetworkKeyTest.java b/core/tests/coretests/src/android/net/NetworkKeyTest.java
index 0f1c71d7c601..c6c0b46d0505 100644
--- a/core/tests/coretests/src/android/net/NetworkKeyTest.java
+++ b/core/tests/coretests/src/android/net/NetworkKeyTest.java
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.when;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiSsid;
+import android.net.wifi.WifiManager;
import androidx.test.runner.AndroidJUnit4;
@@ -65,7 +65,7 @@ public class NetworkKeyTest {
@Test
public void createFromWifi_noneSsid() throws Exception {
- when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE);
+ when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID);
when(mWifiInfo.getBSSID()).thenReturn(VALID_BSSID);
assertNull(NetworkKey.createFromWifiInfo(mWifiInfo));
}
@@ -106,7 +106,7 @@ public class NetworkKeyTest {
}
@Test
- public void createFromScanResult_nullWifiSsid() {
+ public void createFromScanResult_nullSsid() {
ScanResult scanResult = new ScanResult();
scanResult.BSSID = VALID_BSSID;
@@ -114,18 +114,18 @@ public class NetworkKeyTest {
}
@Test
- public void createFromScanResult_emptyWifiSsid() {
+ public void createFromScanResult_emptySsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded("");
+ scanResult.SSID = "";
scanResult.BSSID = VALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@Test
- public void createFromScanResult_noneWifiSsid() {
+ public void createFromScanResult_noneSsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(WifiSsid.NONE);
+ scanResult.SSID = WifiManager.UNKNOWN_SSID;
scanResult.BSSID = VALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
@@ -134,7 +134,7 @@ public class NetworkKeyTest {
@Test
public void createFromScanResult_nullBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@@ -142,7 +142,7 @@ public class NetworkKeyTest {
@Test
public void createFromScanResult_emptyBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = "";
assertNull(NetworkKey.createFromScanResult(scanResult));
@@ -151,16 +151,16 @@ public class NetworkKeyTest {
@Test
public void createFromScanResult_invalidBssid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = INVALID_BSSID;
assertNull(NetworkKey.createFromScanResult(scanResult));
}
@Test
- public void createFromScanResult_validWifiSsid() {
+ public void createFromScanResult_validSsid() {
ScanResult scanResult = new ScanResult();
- scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID);
+ scanResult.SSID = VALID_UNQUOTED_SSID;
scanResult.BSSID = VALID_BSSID;
NetworkKey expected = new NetworkKey(new WifiKey(VALID_SSID, VALID_BSSID));
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 928351e7de8c..b48ac3347093 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -93,6 +93,27 @@ public class SystemPropertiesTest extends TestCase {
}
@SmallTest
+ private static void testHandle() throws Exception {
+ String value;
+ SystemProperties.Handle handle = SystemProperties.find("doesnotexist_2341431");
+ assertNull(handle);
+ SystemProperties.set(KEY, "abc");
+ handle = SystemProperties.find(KEY);
+ assertNotNull(handle);
+ value = handle.get();
+ assertEquals("abc", value);
+ SystemProperties.set(KEY, "blarg");
+ value = handle.get();
+ assertEquals("blarg", value);
+ SystemProperties.set(KEY, "1");
+ assertEquals(1, handle.getInt(-1));
+ assertEquals(1, handle.getLong(-1));
+ assertEquals(true, handle.getBoolean(false));
+ SystemProperties.set(KEY, "");
+ assertEquals(12345, handle.getInt(12345));
+ }
+
+ @SmallTest
public void testIntegralProperties() throws Exception {
testInt("", 123, 123);
testInt("", 0, 0);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 81eb4b355a21..a75d5d696bd0 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -146,6 +146,7 @@ import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
@@ -3050,7 +3051,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private void handleAsyncChannelHalfConnect(Message msg) {
- AsyncChannel ac = (AsyncChannel) msg.obj;
+ ensureRunningOnConnectivityServiceThread();
+ final AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkFactory connected");
@@ -3060,7 +3062,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// A network factory has connected. Send it all current NetworkRequests.
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
- NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+ ensureRunningOnConnectivityServiceThread();
+ NetworkAgentInfo nai = nri.mSatisfier;
final int score;
final int serial;
if (nai != null) {
@@ -3116,6 +3119,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// ConnectivityService, free its interfaces and clean up.
// Must be called on the Handler thread.
private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
+ ensureRunningOnConnectivityServiceThread();
if (DBG) {
log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
}
@@ -3162,14 +3166,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Remove all previously satisfied requests.
for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest request = nai.requestAt(i);
- NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
+ final NetworkRequestInfo nri = mNetworkRequests.get(request);
+ ensureRunningOnConnectivityServiceThread();
+ final NetworkAgentInfo currentNetwork = nri.mSatisfier;
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
- clearNetworkForRequest(request.requestId);
+ nri.mSatisfier = null;
sendUpdatedScoreToFactories(request, null);
}
}
nai.clearLingerState();
if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
+ mDefaultNetworkNai = null;
updateDataActivityTracking(null /* newNetwork */, nai);
notifyLockdownVpn(nai);
ensureNetworkTransitionWakelock(nai.name());
@@ -3253,6 +3260,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri);
if (nri.request.isListen()) {
@@ -3264,7 +3272,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
rematchAllNetworksAndRequests(null, 0);
- if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
+ ensureRunningOnConnectivityServiceThread();
+ if (nri.request.isRequest() && nri.mSatisfier == null) {
sendUpdatedScoreToFactories(nri.request, null);
}
}
@@ -3286,6 +3295,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
// then it should be lingered.
private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
+ ensureRunningOnConnectivityServiceThread();
final int numRequests;
switch (reason) {
case TEARDOWN:
@@ -3310,6 +3320,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// If this Network is already the highest scoring Network for a request, or if
// there is hope for it to become one if it validated, then it is needed.
+ ensureRunningOnConnectivityServiceThread();
if (nri.request.isRequest() && nai.satisfies(nri.request) &&
(nai.isSatisfyingRequest(nri.request.requestId) ||
// Note that this catches two important cases:
@@ -3319,8 +3330,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// 2. Unvalidated WiFi will not be reaped when validated cellular
// is currently satisfying the request. This is desirable when
// WiFi ends up validating and out scoring cellular.
- getNetworkForRequest(nri.request.requestId).getCurrentScore() <
- nai.getCurrentScoreAsValidated())) {
+ nri.mSatisfier.getCurrentScore()
+ < nai.getCurrentScoreAsValidated())) {
return false;
}
}
@@ -3344,10 +3355,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
if (mNetworkRequests.get(nri.request) == null) {
return;
}
- if (getNetworkForRequest(nri.request.requestId) != null) {
+ ensureRunningOnConnectivityServiceThread();
+ if (nri.mSatisfier != null) {
return;
}
if (VDBG || (DBG && nri.request.isRequest())) {
@@ -3374,6 +3387,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
+ ensureRunningOnConnectivityServiceThread();
+
nri.unlinkDeathRecipient();
mNetworkRequests.remove(nri.request);
@@ -3393,7 +3408,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (nri.request.isRequest()) {
boolean wasKept = false;
- NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
+ ensureRunningOnConnectivityServiceThread();
+ final NetworkAgentInfo nai = nri.mSatisfier;
if (nai != null) {
boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
nai.removeRequest(nri.request.requestId);
@@ -3410,7 +3426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
wasKept = true;
}
- clearNetworkForRequest(nri.request.requestId);
+ nri.mSatisfier = null;
if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
// Went from foreground to background.
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
@@ -5093,6 +5109,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private class NetworkRequestInfo implements IBinder.DeathRecipient {
final NetworkRequest request;
+ // The network currently satisfying this request, or null if none. Must only be touched
+ // on the handler thread. This only makes sense for network requests and not for listens,
+ // as defined by NetworkRequest#isRequest(). For listens, this is always null.
+ @Nullable
+ NetworkAgentInfo mSatisfier;
final PendingIntent mPendingIntent;
boolean mPendingIntentSent;
private final IBinder mBinder;
@@ -5479,16 +5500,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (DBG) log("unregisterNetworkFactory for " + nfi.name);
}
- /**
- * NetworkAgentInfo supporting a request by requestId.
- * These have already been vetted (their Capabilities satisfy the request)
- * and the are the highest scored network available.
- * the are keyed off the Requests requestId.
- */
- // NOTE: Accessed on multiple threads, must be synchronized on itself.
- @GuardedBy("mNetworkForRequestId")
- private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>();
-
// NOTE: Accessed on multiple threads, must be synchronized on itself.
@GuardedBy("mNetworkForNetId")
private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
@@ -5506,7 +5517,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
+ @NonNull
private final NetworkRequest mDefaultRequest;
+ // The NetworkAgentInfo currently satisfying the default request, if any.
+ @Nullable
+ private volatile NetworkAgentInfo mDefaultNetworkNai = null;
// Request used to optionally keep mobile data active even when higher
// priority networks like Wi-Fi are active.
@@ -5516,26 +5531,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// priority networks like ethernet are active.
private final NetworkRequest mDefaultWifiRequest;
- private NetworkAgentInfo getNetworkForRequest(int requestId) {
- synchronized (mNetworkForRequestId) {
- return mNetworkForRequestId.get(requestId);
- }
- }
-
- private void clearNetworkForRequest(int requestId) {
- synchronized (mNetworkForRequestId) {
- mNetworkForRequestId.remove(requestId);
- }
- }
-
- private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
- synchronized (mNetworkForRequestId) {
- mNetworkForRequestId.put(requestId, nai);
- }
- }
-
private NetworkAgentInfo getDefaultNetwork() {
- return getNetworkForRequest(mDefaultRequest.requestId);
+ return mDefaultNetworkNai;
}
@Nullable
@@ -6253,7 +6250,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- private void makeDefault(NetworkAgentInfo newNetwork) {
+ private void makeDefault(@NonNull final NetworkAgentInfo newNetwork) {
if (DBG) log("Switching to new default network: " + newNetwork);
try {
@@ -6262,6 +6259,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("Exception setting default network :" + e);
}
+ mDefaultNetworkNai = newNetwork;
notifyLockdownVpn(newNetwork);
handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes());
@@ -6325,6 +6323,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// validated) of becoming the highest scoring network.
private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) {
+ ensureRunningOnConnectivityServiceThread();
if (!newNetwork.everConnected) return;
boolean keep = newNetwork.isVPN();
boolean isNewDefault = false;
@@ -6335,10 +6334,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (VDBG || DDBG) log("rematching " + newNetwork.name());
- // Find and migrate to this Network any NetworkRequests for
- // which this network is now the best.
- ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>();
- ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+ final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
+
NetworkCapabilities nc = newNetwork.networkCapabilities;
if (VDBG) log(" network has: " + nc);
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
@@ -6348,16 +6345,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// requests or not, and doesn't affect the network's score.
if (nri.request.isListen()) continue;
- final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
+ ensureRunningOnConnectivityServiceThread();
+ final NetworkAgentInfo currentNetwork = nri.mSatisfier;
final boolean satisfies = newNetwork.satisfies(nri.request);
- if (newNetwork == currentNetwork && satisfies) {
- if (VDBG) {
- log("Network " + newNetwork.name() + " was already satisfying" +
- " request " + nri.request.requestId + ". No change.");
- }
- keep = true;
- continue;
- }
+ if (newNetwork == currentNetwork && satisfies) continue;
// check if it satisfies the NetworkCapabilities
if (VDBG) log(" checking if request is satisfied: " + nri.request);
@@ -6370,39 +6361,55 @@ public class ConnectivityService extends IConnectivityManager.Stub
", newScore = " + score);
}
if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
- if (VDBG) log("rematch for " + newNetwork.name());
- if (currentNetwork != null) {
- if (VDBG || DDBG){
- log(" accepting network in place of " + currentNetwork.name());
- }
- currentNetwork.removeRequest(nri.request.requestId);
- currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
- affectedNetworks.add(currentNetwork);
- } else {
- if (VDBG || DDBG) log(" accepting network in place of null");
- }
- newNetwork.unlingerRequest(nri.request);
- setNetworkForRequest(nri.request.requestId, newNetwork);
- if (!newNetwork.addRequest(nri.request)) {
- Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
+ reassignedRequests.put(nri, newNetwork);
+ }
+ } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
+ reassignedRequests.put(nri, null);
+ }
+ }
+
+ // Find and migrate to this Network any NetworkRequests for
+ // which this network is now the best.
+ final ArrayList<NetworkAgentInfo> removedRequests = new ArrayList<>();
+ final ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
+ for (final Map.Entry<NetworkRequestInfo, NetworkAgentInfo> entry :
+ reassignedRequests.entrySet()) {
+ final NetworkRequestInfo nri = entry.getKey();
+ final NetworkAgentInfo previousSatisfier = nri.mSatisfier;
+ final NetworkAgentInfo newSatisfier = entry.getValue();
+ if (newSatisfier != null) {
+ if (VDBG) log("rematch for " + newSatisfier.name());
+ if (previousSatisfier != null) {
+ if (VDBG || DDBG) {
+ log(" accepting network in place of " + previousSatisfier.name());
}
- addedRequests.add(nri);
- keep = true;
- // Tell NetworkFactories about the new score, so they can stop
- // trying to connect if they know they cannot match it.
- // TODO - this could get expensive if we have a lot of requests for this
- // network. Think about if there is a way to reduce this. Push
- // netid->request mapping to each factory?
- sendUpdatedScoreToFactories(nri.request, newNetwork);
- if (isDefaultRequest(nri)) {
- isNewDefault = true;
- oldDefaultNetwork = currentNetwork;
- if (currentNetwork != null) {
- mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork);
- }
+ previousSatisfier.removeRequest(nri.request.requestId);
+ previousSatisfier.lingerRequest(nri.request, now, mLingerDelayMs);
+ removedRequests.add(previousSatisfier);
+ } else {
+ if (VDBG || DDBG) log(" accepting network in place of null");
+ }
+ newSatisfier.unlingerRequest(nri.request);
+ nri.mSatisfier = newSatisfier;
+ if (!newSatisfier.addRequest(nri.request)) {
+ Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request);
+ }
+ addedRequests.add(nri);
+ keep = true;
+ // Tell NetworkFactories about the new score, so they can stop
+ // trying to connect if they know they cannot match it.
+ // TODO - this could get expensive if we have a lot of requests for this
+ // network. Think about if there is a way to reduce this. Push
+ // netid->request mapping to each factory?
+ sendUpdatedScoreToFactories(nri.request, newSatisfier);
+ if (isDefaultRequest(nri)) {
+ isNewDefault = true;
+ oldDefaultNetwork = previousSatisfier;
+ if (previousSatisfier != null) {
+ mLingerMonitor.noteLingerDefaultNetwork(previousSatisfier, newSatisfier);
}
}
- } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
+ } else {
// If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
// mark it as no longer satisfying "nri". Because networks are processed by
// rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will
@@ -6415,13 +6422,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
" request " + nri.request.requestId);
}
newNetwork.removeRequest(nri.request.requestId);
- if (currentNetwork == newNetwork) {
- clearNetworkForRequest(nri.request.requestId);
+ if (previousSatisfier == newNetwork) {
+ nri.mSatisfier = null;
+ if (isDefaultRequest(nri)) mDefaultNetworkNai = null;
sendUpdatedScoreToFactories(nri.request, null);
} else {
Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
newNetwork.name() +
- " without updating mNetworkForRequestId or factories!");
+ " without updating mSatisfier or factories!");
}
// TODO: Technically, sending CALLBACK_LOST here is
// incorrect if there is a replacement network currently
@@ -6433,6 +6441,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0);
}
}
+
if (isNewDefault) {
updateDataActivityTracking(newNetwork, oldDefaultNetwork);
// Notify system services that this network is up.
@@ -6472,7 +6481,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Linger any networks that are no longer needed. This should be done after sending the
// available callback for newNetwork.
- for (NetworkAgentInfo nai : affectedNetworks) {
+ for (NetworkAgentInfo nai : removedRequests) {
updateLingerState(nai, now);
}
// Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 62ea95b21865..f8c173f6a9c1 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -32,6 +32,9 @@ per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com
per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com
per-file UserManagerService.java = omakoto@google.com, yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com
+per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
+per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com
# security
per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com
diff --git a/services/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 997178e1582b..d78aaa5f9c9d 100644
--- a/services/core/java/com/android/server/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.recoverysystem;
import android.content.Context;
import android.net.LocalSocket;
@@ -27,6 +27,8 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Slog;
+import com.android.server.SystemService;
+
import libcore.io.IoUtils;
import java.io.DataInputStream;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 16c60ca3997a..c1b7a50a8623 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -135,6 +135,7 @@ import com.android.server.policy.role.LegacyRoleResolutionPolicy;
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
import com.android.server.power.ThermalManagerService;
+import com.android.server.recoverysystem.RecoverySystemService;
import com.android.server.restrictions.RestrictionsManagerService;
import com.android.server.role.RoleManagerService;
import com.android.server.rollback.RollbackManagerService;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e9e96c9c7efb..8fd8d0461e75 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -56,6 +56,7 @@ import android.net.WifiKey;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.Handler;
@@ -719,7 +720,7 @@ public class NetworkScoreServiceTest {
@Test
public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_noneSsid() throws Exception {
- when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE);
+ when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID);
NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter =
new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo);
@@ -793,7 +794,7 @@ public class NetworkScoreServiceTest {
List<ScanResult> invalidScanResults = Lists.newArrayList(
new ScanResult(),
createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid),
- createScanResult(WifiSsid.NONE, SCORED_NETWORK.networkKey.wifiKey.bssid),
+ createScanResult(WifiManager.UNKNOWN_SSID, SCORED_NETWORK.networkKey.wifiKey.bssid),
createScanResult(SSID, null),
createScanResult(SSID, INVALID_BSSID)
);
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index d669e905e4df..58abf0051539 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.telecom.Connection.VideoProvider;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index e2f5d0bba0b0..4c22ba9715b0 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -35,6 +35,7 @@ import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index a884a7039d5b..72f758eba39a 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -469,4 +469,44 @@ public class Annotation {
@Retention(RetentionPolicy.SOURCE)
public @interface DataFailureCause {
}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"PRECISE_CALL_STATE_"},
+ value = {
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_IDLE,
+ PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+ PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+ PreciseCallState.PRECISE_CALL_STATE_DIALING,
+ PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+ PreciseCallState. PRECISE_CALL_STATE_INCOMING,
+ PreciseCallState.PRECISE_CALL_STATE_WAITING,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
+ public @interface PreciseCallStates {}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = {
+ ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GPRS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EDGE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_UMTS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GSM,
+ ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_NR})
+ public @interface RilRadioTechnology {}
}
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index f929649453b9..9f75332c4a03 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -23,6 +23,7 @@ import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.PreciseCallStates;
import android.telephony.DisconnectCause;
import android.telephony.PreciseDisconnectCause;
@@ -48,22 +49,6 @@ import java.util.Objects;
@SystemApi
public final class PreciseCallState implements Parcelable {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"PRECISE_CALL_STATE_"},
- value = {
- PRECISE_CALL_STATE_NOT_VALID,
- PRECISE_CALL_STATE_IDLE,
- PRECISE_CALL_STATE_ACTIVE,
- PRECISE_CALL_STATE_HOLDING,
- PRECISE_CALL_STATE_DIALING,
- PRECISE_CALL_STATE_ALERTING,
- PRECISE_CALL_STATE_INCOMING,
- PRECISE_CALL_STATE_WAITING,
- PRECISE_CALL_STATE_DISCONNECTED,
- PRECISE_CALL_STATE_DISCONNECTING})
- public @interface State {}
-
/** Call state is not valid (Not received a call state). */
public static final int PRECISE_CALL_STATE_NOT_VALID = -1;
/** Call state: No activity. */
@@ -85,9 +70,9 @@ public final class PreciseCallState implements Parcelable {
/** Call state: Disconnecting. */
public static final int PRECISE_CALL_STATE_DISCONNECTING = 8;
- private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
private int mDisconnectCause = DisconnectCause.NOT_VALID;
private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
@@ -97,8 +82,9 @@ public final class PreciseCallState implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- public PreciseCallState(@State int ringingCall, @State int foregroundCall,
- @State int backgroundCall, int disconnectCause,
+ public PreciseCallState(@PreciseCallStates int ringingCall,
+ @PreciseCallStates int foregroundCall,
+ @PreciseCallStates int backgroundCall, int disconnectCause,
int preciseDisconnectCause) {
mRingingCallState = ringingCall;
mForegroundCallState = foregroundCall;
@@ -131,21 +117,21 @@ public final class PreciseCallState implements Parcelable {
/**
* Returns the precise ringing call state.
*/
- public @State int getRingingCallState() {
+ public @PreciseCallStates int getRingingCallState() {
return mRingingCallState;
}
/**
* Returns the precise foreground call state.
*/
- public @State int getForegroundCallState() {
+ public @PreciseCallStates int getForegroundCallState() {
return mForegroundCallState;
}
/**
* Returns the precise background call state.
*/
- public @State int getBackgroundCallState() {
+ public @PreciseCallStates int getBackgroundCallState() {
return mBackgroundCallState;
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 3fd8990ffc9a..1e601cf3de5f 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -30,6 +30,7 @@ import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.NetworkRegistrationInfo.Domain;
import android.telephony.NetworkRegistrationInfo.NRState;
import android.text.TextUtils;
@@ -155,32 +156,6 @@ public class ServiceState implements Parcelable {
*/
public static final int DUPLEX_MODE_TDD = 2;
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" },
- value = {
- RIL_RADIO_TECHNOLOGY_UNKNOWN,
- RIL_RADIO_TECHNOLOGY_GPRS,
- RIL_RADIO_TECHNOLOGY_EDGE,
- RIL_RADIO_TECHNOLOGY_UMTS,
- RIL_RADIO_TECHNOLOGY_IS95A,
- RIL_RADIO_TECHNOLOGY_IS95B,
- RIL_RADIO_TECHNOLOGY_1xRTT,
- RIL_RADIO_TECHNOLOGY_EVDO_0,
- RIL_RADIO_TECHNOLOGY_EVDO_A,
- RIL_RADIO_TECHNOLOGY_HSDPA,
- RIL_RADIO_TECHNOLOGY_HSUPA,
- RIL_RADIO_TECHNOLOGY_HSPA,
- RIL_RADIO_TECHNOLOGY_EVDO_B,
- RIL_RADIO_TECHNOLOGY_EHRPD,
- RIL_RADIO_TECHNOLOGY_LTE,
- RIL_RADIO_TECHNOLOGY_HSPAP,
- RIL_RADIO_TECHNOLOGY_GSM,
- RIL_RADIO_TECHNOLOGY_TD_SCDMA,
- RIL_RADIO_TECHNOLOGY_IWLAN,
- RIL_RADIO_TECHNOLOGY_LTE_CA,
- RIL_RADIO_TECHNOLOGY_NR})
- public @interface RilRadioTechnology {}
/**
* Available radio technologies for GSM, UMTS and CDMA.
* Duplicates the constants from hardware/radio/include/ril.h
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
index adf7154b4e07..663e8e25a115 100644
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ b/telephony/java/android/telephony/SmsCbLocation.java
@@ -65,9 +65,12 @@ public final class SmsCbLocation implements Parcelable {
/**
* Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
* the same object can be reused for multiple broadcasts.
- * @hide
+ *
+ * @param plmn the MCC/MNC of the network
+ * @param lac the GSM location area code, or UMTS service area code
+ * @param cid the GSM or UMTS cell ID
*/
- public SmsCbLocation(String plmn, int lac, int cid) {
+ public SmsCbLocation(@NonNull String plmn, int lac, int cid) {
mPlmn = plmn;
mLac = lac;
mCid = cid;
diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index 3e044e52d28b..737ead1f8131 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -138,8 +138,8 @@ public final class SmsCbMessage implements Parcelable {
public @interface MessagePriority {}
/**
- * ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
- * @hide
+ * Integer indicating that the maximum wait time is not set.
+ * Based on ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12.
*/
public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;
@@ -209,6 +209,7 @@ public final class SmsCbMessage implements Parcelable {
/**
* Create a new SmsCbMessage with the specified data.
+ * @hide
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
@NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
@@ -221,14 +222,14 @@ public final class SmsCbMessage implements Parcelable {
}
/**
- * Create a new {@link SmsCbMessage} with the warning area coordinates information.
- * @hide
+ * Create a new {@link SmsCbMessage} with the specified data, including warning area
+ * coordinates information.
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
- SmsCbLocation location, int serviceCategory, String language, String body,
- int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
- int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis,
- int slotIndex) {
+ @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language,
+ @Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo,
+ @Nullable SmsCbCmasInfo cmasWarningInfo, int maximumWaitTimeSec,
+ @Nullable List<Geometry> geometries, long receivedTimeMillis, int slotIndex) {
mMessageFormat = messageFormat;
mGeographicalScope = geographicalScope;
mSerialNumber = serialNumber;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 9d1b7a918327..3c890a18e344 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -61,6 +61,7 @@ import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsMmTelManager;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub;
@@ -76,6 +77,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -910,6 +912,11 @@ public class SubscriptionManager {
private final Context mContext;
private volatile INetworkPolicyManager mNetworkPolicy;
+ // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing
+ // the Context and subId.
+ private static final Map<Pair<Context, Integer>, Resources> sResourcesCache =
+ new ConcurrentHashMap<>();
+
/**
* A listener class for monitoring changes to {@link SubscriptionInfo} records.
* <p>
@@ -2304,8 +2311,20 @@ public class SubscriptionManager {
* @return Resources associated with Subscription.
* @hide
*/
+ @NonNull
public static Resources getResourcesForSubId(Context context, int subId,
boolean useRootLocale) {
+ // Check if resources for this context and subId already exist in the resource cache.
+ // Resources that use the root locale are not cached.
+ Pair<Context, Integer> cacheKey = null;
+ if (isValidSubscriptionId(subId) && !useRootLocale) {
+ cacheKey = Pair.create(context, subId);
+ if (sResourcesCache.containsKey(cacheKey)) {
+ // Cache hit. Use cached Resources.
+ return sResourcesCache.get(cacheKey);
+ }
+ }
+
final SubscriptionInfo subInfo =
SubscriptionManager.from(context).getActiveSubscriptionInfo(subId);
@@ -2325,7 +2344,13 @@ public class SubscriptionManager {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
DisplayMetrics newMetrics = new DisplayMetrics();
newMetrics.setTo(metrics);
- return new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+ Resources res = new Resources(context.getResources().getAssets(), newMetrics, newConfig);
+
+ if (cacheKey != null) {
+ // Save the newly created Resources in the resource cache.
+ sResourcesCache.put(cacheKey, res);
+ }
+ return res;
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8163a6642089..e99465d58764 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8832,7 +8832,10 @@ public class TelephonyManager {
@Deprecated
public boolean isTtyModeSupported() {
try {
- TelecomManager telecomManager = TelecomManager.from(mContext);
+ TelecomManager telecomManager = null;
+ if (mContext != null) {
+ telecomManager = mContext.getSystemService(TelecomManager.class);
+ }
if (telecomManager != null) {
return telecomManager.isTtySupported();
}
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 727684eca7ea..1de6260f3719 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -765,6 +765,12 @@ public class MockContext extends Context {
/** {@hide} */
@Override
+ public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@hide} */
+ @Override
public int getUserId() {
throw new UnsupportedOperationException();
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 2f963efd09d5..b53b2aaaf547 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1128,6 +1128,9 @@ public class WifiManager {
*/
private static final int MAX_ACTIVE_LOCKS = 50;
+ /** Indicates an invalid SSID. */
+ public static final String UNKNOWN_SSID = "<unknown ssid>";
+
/* Number of currently active WifiLocks and MulticastLocks */
@UnsupportedAppUsage
private int mActiveLockCount;
@@ -2326,7 +2329,7 @@ public class WifiManager {
* <p>
* In the connected state, access to the SSID and BSSID requires
* the same permissions as {@link #getScanResults}. If such access is not allowed,
- * {@link WifiInfo#getSSID} will return {@code "<unknown ssid>"} and
+ * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and
* {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}.
*
* @return the Wi-Fi information, contained in {@link WifiInfo}.
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index 70ca0882d7da..f187e1042c58 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -48,7 +48,7 @@ public class WifiSsid implements Parcelable {
private static final int HEX_RADIX = 16;
@UnsupportedAppUsage
- public static final String NONE = "<unknown ssid>";
+ public static final String NONE = WifiManager.UNKNOWN_SSID;
private WifiSsid() {
}