Merge "Revert "resolve merge conflicts of 0cc0d229d0f590fe84c1b7aa8cc8fbf188d8a787 to pi-dev-plus-aosp"" into pi-dev-plus-aosp
diff --git a/api/current.txt b/api/current.txt
index bcd8ebb..eb32f06 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -37270,6 +37270,7 @@
field public static final java.lang.String AUTH_TYPE = "authtype";
field public static final deprecated java.lang.String BEARER = "bearer";
field public static final java.lang.String CARRIER_ENABLED = "carrier_enabled";
+ field public static final java.lang.String CARRIER_ID = "carrier_id";
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String CURRENT = "current";
field public static final java.lang.String DEFAULT_SORT_ORDER = "name ASC";
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index cde0269..70beac8e6 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -494,42 +494,6 @@
Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
-Landroid/icu/impl/CurrencyData;-><init>()V
-Landroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
-Landroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-Landroid/icu/impl/IllegalIcuArgumentException;-><init>(Ljava/lang/String;)V
-Landroid/icu/text/ArabicShaping;-><init>(I)V
-Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z
-Landroid/icu/text/ArabicShaping;->isSeenTailFamilyChar(C)I
-Landroid/icu/text/ArabicShaping;->isTailChar(C)Z
-Landroid/icu/text/ArabicShaping;->isYehHamzaChar(C)Z
-Landroid/icu/text/ArabicShaping;->shape(Ljava/lang/String;)Ljava/lang/String;
-Landroid/icu/text/DateFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/DateIntervalFormat;-><init>()V
-Landroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
-Landroid/icu/text/DecimalFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/RuleBasedCollator;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/SpoofChecker$ScriptSet;-><init>()V
-Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V
-Landroid/icu/text/SpoofChecker$ScriptSet;->isFull()Z
-Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V
-Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V
-Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;I)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->transliterate(Landroid/icu/text/Replaceable;Landroid/icu/text/Transliterator$Position;Ljava/lang/String;)V
-Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
-Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/util/PersianCalendar;-><init>(Ljava/util/Locale;)V
-Landroid/icu/util/UResourceBundle;->getBundleInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/util/UResourceBundle;
-Landroid/icu/util/UResourceBundle;->getKey()Ljava/lang/String;
-Landroid/icu/util/UResourceBundle;->getString()Ljava/lang/String;
-Landroid/icu/util/UResourceBundle;->getType()I
-Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
-Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
-Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
-Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
Landroid/location/ICountryListener$Stub;-><init>()V
Landroid/location/IGeocodeProvider$Stub;-><init>()V
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
index 0643414..229bee5 100644
--- a/core/java/android/app/DexLoadReporter.java
+++ b/core/java/android/app/DexLoadReporter.java
@@ -87,7 +87,7 @@
}
@Override
- public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) {
+ public void report(List<ClassLoader> classLoadersChain, List<String> classPaths) {
if (classLoadersChain.size() != classPaths.size()) {
Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch");
return;
@@ -113,12 +113,12 @@
registerSecondaryDexForProfiling(dexPathsForRegistration);
}
- private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain,
+ private void notifyPackageManager(List<ClassLoader> classLoadersChain,
List<String> classPaths) {
// Get the class loader names for the binder call.
List<String> classLoadersNames = new ArrayList<>(classPaths.size());
- for (BaseDexClassLoader bdc : classLoadersChain) {
- classLoadersNames.add(bdc.getClass().getName());
+ for (ClassLoader classLoader : classLoadersChain) {
+ classLoadersNames.add(classLoader.getClass().getName());
}
String packageName = ActivityThread.currentPackageName();
try {
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index bc5b32c..da7d664 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -475,7 +475,7 @@
* @param classPaths the class paths corresponding to the class loaders names from
* {@param classLoadersNames}. The the first element corresponds to the first class loader
* and so on. A classpath is represented as a list of dex files separated by
- * {@code File.pathSeparator}.
+ * {@code File.pathSeparator}, or null if the class loader's classpath is not known.
* The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the loader process
*/
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index ccbc8ed..b036289 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2066,8 +2066,13 @@
}
FeatureInfo[] features = pm.getSystemAvailableFeatures();
- Arrays.sort(features, (o1, o2) ->
- (o1.name == o2.name ? 0 : (o1.name == null ? -1 : o1.name.compareTo(o2.name))));
+ Arrays.sort(features, (o1, o2) -> {
+ if (o1.name == o2.name) return 0;
+ if (o1.name == null) return -1;
+ if (o2.name == null) return 1;
+ return o1.name.compareTo(o2.name);
+ });
+
for (int i = 0; i < features.length; i++) {
if (features[i].name != null) {
if (protoOutputStream != null) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index deaa334..94c94a5 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -165,7 +165,7 @@
}
@VisibleForTesting
- int getDeviceFirstSdkInt() {
+ protected int getDeviceFirstSdkInt() {
return Build.VERSION.FIRST_SDK_INT;
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 753c283..580e4f4 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -35,6 +35,7 @@
import android.util.jar.StrictJarFile;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
@@ -153,7 +154,7 @@
* @param classPaths the class paths corresponding to the class loaders names from
* {@param classLoadersNames}. The the first element corresponds to the first class loader
* and so on. A classpath is represented as a list of dex files separated by
- * {@code File.pathSeparator}.
+ * {@code File.pathSeparator}, or null if the class loader's classpath is not known.
* The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the app loading the dex files
* @param loaderUserId the user id which runs the code loading the dex files
@@ -169,7 +170,8 @@
}
}
- private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
+ @VisibleForTesting
+ /*package*/ void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
List<String> classLoaderNames, List<String> classPaths, String loaderIsa,
int loaderUserId) {
if (classLoaderNames.size() != classPaths.size()) {
@@ -186,8 +188,14 @@
return;
}
+ // The first classpath should never be null because the first classloader
+ // should always be an instance of BaseDexClassLoader.
+ String firstClassPath = classPaths.get(0);
+ if (firstClassPath == null) {
+ return;
+ }
// The classpath is represented as a list of dex files separated by File.pathSeparator.
- String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator);
+ String[] dexPathsToRegister = firstClassPath.split(File.pathSeparator);
// Encode the class loader contexts for the dexPathsToRegister.
String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index e1310a2..d2600b5 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -318,7 +318,8 @@
// is fine (they come over binder). Even if something changes we expect the sizes to be
// very small and it shouldn't matter much.
for (int i = 1; i < classLoadersNames.size(); i++) {
- if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) {
+ if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))
+ || classPaths.get(i) == null) {
return null;
}
String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator));
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 030f9cc..b30c043 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -69,6 +69,7 @@
private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
DelegateLastClassLoader.class.getName();
+ private static final String UNSUPPORTED_CLASS_LOADER_NAME = "unsupported.class_loader";
@Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Mock Installer mInstaller;
@@ -106,7 +107,7 @@
mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1);
mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0,
- "unsupported.class_loader");
+ UNSUPPORTED_CLASS_LOADER_NAME);
mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0,
DELEGATE_LAST_CLASS_LOADER_NAME);
@@ -406,6 +407,24 @@
}
@Test
+ public void testNotifySupportedAndUnsupportedClassLoader() {
+ String classPath = String.join(File.pathSeparator, mBarUser0.getSecondaryDexPaths());
+ List<String> classLoaders =
+ Arrays.asList(PATH_CLASS_LOADER_NAME, UNSUPPORTED_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(classPath, classPath);
+ notifyDexLoad(mBarUser0, classLoaders, classPaths, mUser0);
+
+ assertNoUseInfo(mBarUser0);
+ }
+
+ @Test
+ public void testNotifyNullClassPath() {
+ notifyDexLoad(mBarUser0, null, mUser0);
+
+ assertNoUseInfo(mBarUser0);
+ }
+
+ @Test
public void testNotifyVariableClassLoader() {
// Record bar secondaries with the default PathClassLoader.
List<String> secondaries = mBarUser0.getSecondaryDexPaths();
@@ -500,14 +519,17 @@
// By default, assume a single class loader in the chain.
// This makes writing tests much easier.
List<String> classLoaders = Arrays.asList(testData.mClassLoader);
- List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths));
+ List<String> classPaths = (dexPaths == null)
+ ? Arrays.asList((String) null)
+ : Arrays.asList(String.join(File.pathSeparator, dexPaths));
notifyDexLoad(testData, classLoaders, classPaths, loaderUserId);
}
- private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths,
- int loaderUserId) {
- mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths,
- testData.mLoaderIsa, loaderUserId);
+ private void notifyDexLoad(TestData testData, List<String> classLoaders,
+ List<String> classPaths, int loaderUserId) {
+ // We call the internal function so any exceptions thrown cause test failures.
+ mDexManager.notifyDexLoadInternal(testData.mPackageInfo.applicationInfo, classLoaders,
+ classPaths, testData.mLoaderIsa, loaderUserId);
}
private PackageUseInfo getPackageUseInfo(TestData testData) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 150f7f0..6e0f56c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -353,6 +353,18 @@
}
@Test
+ public void testProcessContextForDexLoadNoClassPath() {
+ List<String> classLoaders = Arrays.asList(
+ DELEGATE_LAST_CLASS_LOADER_NAME,
+ PATH_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(
+ String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+ null);
+ String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+ assertNull(context);
+ }
+
+ @Test
public void testProcessContextForDexLoadIllegalCallEmptyList() {
boolean gotException = false;
try {
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 171e111..af77b5c 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3048,6 +3048,13 @@
@SystemApi
public static final int NO_SET_SET = 0;
+ /**
+ * A unique carrier id associated with this APN
+ * {@see TelephonyManager#getSimCarrierId()}
+ * <p>Type: STRING</p>
+ */
+ public static final String CARRIER_ID = "carrier_id";
+
}
/**
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index f12756a..af7123b 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -30,7 +30,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -63,24 +65,13 @@
@Mock private PackageManager mPackageManager;
private PermissionMonitor mPermissionMonitor;
- private int mMockFirstSdkInt;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(MOCK_PACKAGE_NAMES);
- // Try to use spy() here for stubbing getDeviceFirstSdkInt value but the spies are loaded
- // by a custom class loader that's different from the loader used for loading the real
- // thing. That means those two classes are not in the same package, so a package private
- // method is not accessible. Hence, using override method to control FIRST_SDK_INT value
- // instead of spy function for testing.
- mPermissionMonitor = new PermissionMonitor(mContext, null) {
- @Override
- int getDeviceFirstSdkInt() {
- return mMockFirstSdkInt;
- }
- };
+ mPermissionMonitor = spy(new PermissionMonitor(mContext, null));
}
private boolean hasBgPermission(String partition, int targetSdkVersion, int uid,
@@ -166,13 +157,13 @@
@Test
public void testHasUseBackgroundNetworksPermissionSystemUid() throws Exception {
- mMockFirstSdkInt = VERSION_P;
+ doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CHANGE_WIFI_STATE));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID,
CONNECTIVITY_USE_RESTRICTED_NETWORKS));
- mMockFirstSdkInt = VERSION_Q;
+ doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CHANGE_WIFI_STATE));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID,