Migrate to PackageState#getSharedLibraryDependencies
API was renamed. Use reflection to avoid issues with the
master-art prebuilt. Will be removed in future change.
Ignore-AOSP-First: ART Services.
Bug: 265006762
Test: atest ArtServiceTests
Change-Id: Ife8dfe72307f8835a1d004984a1e631acabab15f
diff --git a/libartservice/service/java/com/android/server/art/DexoptHelper.java b/libartservice/service/java/com/android/server/art/DexoptHelper.java
index 1e04bd0..af0f20f 100644
--- a/libartservice/service/java/com/android/server/art/DexoptHelper.java
+++ b/libartservice/service/java/com/android/server/art/DexoptHelper.java
@@ -37,6 +37,7 @@
import com.android.server.art.model.DexoptParams;
import com.android.server.art.model.DexoptResult;
import com.android.server.art.model.OperationProgress;
+import com.android.server.art.wrapper.PackageStateWrapper;
import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
@@ -52,7 +53,6 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
-import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -268,7 +268,8 @@
Utils.getPackageOrThrow(pkgState);
pkgStates.put(packageName, pkgState);
if (includeDependencies && canDexoptPackage(pkgState)) {
- for (SharedLibrary library : pkgState.getUsesLibraries()) {
+ for (SharedLibrary library :
+ PackageStateWrapper.getSharedLibraryDependencies(pkgState)) {
maybeEnqueue.accept(library);
}
}
diff --git a/libartservice/service/java/com/android/server/art/PrimaryDexUtils.java b/libartservice/service/java/com/android/server/art/PrimaryDexUtils.java
index ada6488..3eb9414 100644
--- a/libartservice/service/java/com/android/server/art/PrimaryDexUtils.java
+++ b/libartservice/service/java/com/android/server/art/PrimaryDexUtils.java
@@ -24,6 +24,7 @@
import com.android.internal.annotations.Immutable;
import com.android.server.art.model.DetailedDexInfo;
+import com.android.server.art.wrapper.PackageStateWrapper;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageSplit;
import com.android.server.pm.pkg.PackageState;
@@ -110,7 +111,8 @@
baseApk.mRelativeDexPath = baseDexFile.getName();
// Shared libraries are the dependencies of the base APK.
- baseApk.mSharedLibrariesContext = encodeSharedLibraries(pkgState.getUsesLibraries());
+ baseApk.mSharedLibrariesContext =
+ encodeSharedLibraries(PackageStateWrapper.getSharedLibraryDependencies(pkgState));
boolean isIsolatedSplitLoading = isIsolatedSplitLoading(pkg);
diff --git a/libartservice/service/java/com/android/server/art/wrapper/PackageStateWrapper.java b/libartservice/service/java/com/android/server/art/wrapper/PackageStateWrapper.java
new file mode 100644
index 0000000..cd6f083
--- /dev/null
+++ b/libartservice/service/java/com/android/server/art/wrapper/PackageStateWrapper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.art.wrapper;
+
+import android.annotation.NonNull;
+
+import com.android.server.pm.pkg.PackageState;
+import com.android.server.pm.pkg.SharedLibrary;
+
+import java.util.List;
+
+/** @hide */
+public class PackageStateWrapper {
+ @SuppressWarnings("unchecked")
+ @NonNull
+ public static List<SharedLibrary> getSharedLibraryDependencies(
+ @NonNull PackageState packageState) {
+ try {
+ return (List<SharedLibrary>) packageState.getClass()
+ .getMethod("getSharedLibraryDependencies")
+ .invoke(packageState);
+ } catch (ReflectiveOperationException ignored) {
+ try {
+ return (List<SharedLibrary>) packageState.getClass()
+ .getMethod("getUsesLibraries")
+ .invoke(packageState);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/libartservice/service/javatests/com/android/server/art/DexoptHelperTest.java b/libartservice/service/javatests/com/android/server/art/DexoptHelperTest.java
index eab54d4..40c351d 100644
--- a/libartservice/service/javatests/com/android/server/art/DexoptHelperTest.java
+++ b/libartservice/service/javatests/com/android/server/art/DexoptHelperTest.java
@@ -26,7 +26,6 @@
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.lenient;
@@ -49,6 +48,8 @@
import com.android.server.art.model.DexoptParams;
import com.android.server.art.model.DexoptResult;
import com.android.server.art.model.OperationProgress;
+import com.android.server.art.testing.StaticMockitoRule;
+import com.android.server.art.wrapper.PackageStateWrapper;
import com.android.server.pm.PackageManagerLocal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageSplit;
@@ -57,6 +58,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
@@ -82,6 +84,8 @@
private static final String PKG_NAME_LIB4 = "com.example.lib4";
private static final String PKG_NAME_LIBBAZ = "com.example.libbaz";
+ @Rule public StaticMockitoRule mockitoRule = new StaticMockitoRule(PackageStateWrapper.class);
+
@Mock private DexoptHelper.Injector mInjector;
@Mock private PrimaryDexopter mPrimaryDexopter;
@Mock private SecondaryDexopter mSecondaryDexopter;
@@ -623,7 +627,7 @@
PackageState pkgState = mock(PackageState.class);
lenient().when(pkgState.getPackageName()).thenReturn(packageName);
lenient().when(pkgState.getAppId()).thenReturn(12345);
- lenient().when(pkgState.getUsesLibraries()).thenReturn(deps);
+ lenient().when(PackageStateWrapper.getSharedLibraryDependencies(pkgState)).thenReturn(deps);
AndroidPackage pkg = createPackage(multiSplit);
lenient().when(pkgState.getAndroidPackage()).thenReturn(pkg);
return pkgState;
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexUtilsTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexUtilsTest.java
index ab703fc..ef5727b 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexUtilsTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexUtilsTest.java
@@ -23,10 +23,11 @@
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import androidx.test.filters.SmallTest;
+import com.android.server.art.testing.StaticMockitoRule;
+import com.android.server.art.wrapper.PackageStateWrapper;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageSplit;
import com.android.server.pm.pkg.PackageState;
@@ -37,6 +38,7 @@
import dalvik.system.PathClassLoader;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
@@ -47,6 +49,8 @@
@SmallTest
@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class PrimaryDexUtilsTest {
+ @Rule public StaticMockitoRule mockitoRule = new StaticMockitoRule(PackageStateWrapper.class);
+
@Before
public void setUp() {}
@@ -162,7 +166,7 @@
lenient().when(split4.isHasCode()).thenReturn(true);
var splits = List.of(baseSplit, split0, split1, split2, split3, split4);
- when(pkg.getSplits()).thenReturn(splits);
+ lenient().when(pkg.getSplits()).thenReturn(splits);
if (isIsolatedSplitLoading) {
// split_0: PCL(PathClassLoader), depends on split_2.
@@ -170,18 +174,20 @@
// split_2: DLC(DelegateLastClassLoader), depends on base.
// split_3: PCL(DexClassLoader), no dependency.
// split_4: PCL(null), depends on split_3.
- when(split0.getClassLoaderName()).thenReturn(PathClassLoader.class.getName());
- when(split1.getClassLoaderName()).thenReturn(null);
- when(split2.getClassLoaderName()).thenReturn(DelegateLastClassLoader.class.getName());
- when(split3.getClassLoaderName()).thenReturn(DexClassLoader.class.getName());
- when(split4.getClassLoaderName()).thenReturn(null);
+ lenient().when(split0.getClassLoaderName()).thenReturn(PathClassLoader.class.getName());
+ lenient().when(split1.getClassLoaderName()).thenReturn(null);
+ lenient()
+ .when(split2.getClassLoaderName())
+ .thenReturn(DelegateLastClassLoader.class.getName());
+ lenient().when(split3.getClassLoaderName()).thenReturn(DexClassLoader.class.getName());
+ lenient().when(split4.getClassLoaderName()).thenReturn(null);
- when(split0.getDependencies()).thenReturn(List.of(split2));
- when(split2.getDependencies()).thenReturn(List.of(baseSplit));
- when(split4.getDependencies()).thenReturn(List.of(split3));
- when(pkg.isIsolatedSplitLoading()).thenReturn(true);
+ lenient().when(split0.getDependencies()).thenReturn(List.of(split2));
+ lenient().when(split2.getDependencies()).thenReturn(List.of(baseSplit));
+ lenient().when(split4.getDependencies()).thenReturn(List.of(split3));
+ lenient().when(pkg.isIsolatedSplitLoading()).thenReturn(true);
} else {
- when(pkg.isIsolatedSplitLoading()).thenReturn(false);
+ lenient().when(pkg.isIsolatedSplitLoading()).thenReturn(false);
}
return pkg;
@@ -190,33 +196,36 @@
private PackageState createPackageState() {
PackageState pkgState = mock(PackageState.class);
- when(pkgState.getPackageName()).thenReturn("com.example.foo");
+ lenient().when(pkgState.getPackageName()).thenReturn("com.example.foo");
// Base depends on library 2, 3, 4.
// Library 2, 4 depends on library 1.
List<SharedLibrary> usesLibraryInfos = new ArrayList<>();
SharedLibrary library1 = mock(SharedLibrary.class);
- when(library1.getAllCodePaths())
+ lenient()
+ .when(library1.getAllCodePaths())
.thenReturn(List.of("library_1_dex_1.jar", "library_1_dex_2.jar"));
- when(library1.getDependencies()).thenReturn(null);
+ lenient().when(library1.getDependencies()).thenReturn(null);
SharedLibrary library2 = mock(SharedLibrary.class);
- when(library2.getAllCodePaths()).thenReturn(List.of("library_2.jar"));
- when(library2.getDependencies()).thenReturn(List.of(library1));
+ lenient().when(library2.getAllCodePaths()).thenReturn(List.of("library_2.jar"));
+ lenient().when(library2.getDependencies()).thenReturn(List.of(library1));
usesLibraryInfos.add(library2);
SharedLibrary library3 = mock(SharedLibrary.class);
- when(library3.getAllCodePaths()).thenReturn(List.of("library_3.jar"));
- when(library3.getDependencies()).thenReturn(null);
+ lenient().when(library3.getAllCodePaths()).thenReturn(List.of("library_3.jar"));
+ lenient().when(library3.getDependencies()).thenReturn(null);
usesLibraryInfos.add(library3);
SharedLibrary library4 = mock(SharedLibrary.class);
- when(library4.getAllCodePaths()).thenReturn(List.of("library_4.jar"));
- when(library4.getDependencies()).thenReturn(List.of(library1));
+ lenient().when(library4.getAllCodePaths()).thenReturn(List.of("library_4.jar"));
+ lenient().when(library4.getDependencies()).thenReturn(List.of(library1));
usesLibraryInfos.add(library4);
- when(pkgState.getUsesLibraries()).thenReturn(usesLibraryInfos);
+ lenient()
+ .when(PackageStateWrapper.getSharedLibraryDependencies(pkgState))
+ .thenReturn(usesLibraryInfos);
return pkgState;
}
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTestBase.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTestBase.java
index fb31508..29a11d3 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTestBase.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTestBase.java
@@ -20,7 +20,6 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.lenient;
@@ -33,6 +32,7 @@
import android.os.storage.StorageManager;
import com.android.server.art.testing.StaticMockitoRule;
+import com.android.server.art.wrapper.PackageStateWrapper;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageSplit;
import com.android.server.pm.pkg.PackageState;
@@ -53,8 +53,8 @@
protected static final int SHARED_GID = UserHandle.getSharedAppGid(UID);
@Rule
- public StaticMockitoRule mockitoRule =
- new StaticMockitoRule(SystemProperties.class, Constants.class);
+ public StaticMockitoRule mockitoRule = new StaticMockitoRule(
+ SystemProperties.class, Constants.class, PackageStateWrapper.class);
@Mock protected PrimaryDexopter.Injector mInjector;
@Mock protected IArtd mArtd;
@@ -148,7 +148,9 @@
lenient().when(pkgState.isSystem()).thenReturn(false);
lenient().when(pkgState.isUpdatedSystemApp()).thenReturn(false);
lenient().when(pkgState.getAppId()).thenReturn(UID);
- lenient().when(pkgState.getUsesLibraries()).thenReturn(new ArrayList<>());
+ lenient()
+ .when(PackageStateWrapper.getSharedLibraryDependencies(pkgState))
+ .thenReturn(new ArrayList<>());
lenient().when(pkgState.getStateForUser(any())).thenReturn(mPkgUserStateNotInstalled);
AndroidPackage pkg = createPackage();
lenient().when(pkgState.getAndroidPackage()).thenReturn(pkg);