• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.art;
18 
19 import static com.android.server.art.GetDexoptNeededResult.ArtifactsLocation;
20 
21 import static org.mockito.Mockito.any;
22 import static org.mockito.Mockito.anyBoolean;
23 import static org.mockito.Mockito.argThat;
24 import static org.mockito.Mockito.eq;
25 import static org.mockito.Mockito.lenient;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.same;
28 
29 import android.os.CancellationSignal;
30 import android.os.SystemProperties;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.os.storage.StorageManager;
34 
35 import com.android.modules.utils.pm.PackageStateModulesUtils;
36 import com.android.server.art.testing.StaticMockitoRule;
37 import com.android.server.pm.pkg.AndroidPackage;
38 import com.android.server.pm.pkg.AndroidPackageSplit;
39 import com.android.server.pm.pkg.PackageState;
40 import com.android.server.pm.pkg.PackageUserState;
41 
42 import dalvik.system.PathClassLoader;
43 
44 import org.junit.Before;
45 import org.junit.Rule;
46 import org.mockito.Mock;
47 
48 import java.util.ArrayList;
49 import java.util.List;
50 
51 public class PrimaryDexopterTestBase {
52     protected static final String PKG_NAME = "com.example.foo";
53     protected static final int UID = 12345;
54     protected static final int SHARED_GID = UserHandle.getSharedAppGid(UID);
55     protected static final long ART_VERSION = 331413030l;
56     protected static final String APP_VERSION_NAME = "12.34.56";
57     protected static final long APP_VERSION_CODE = 1536036288l;
58 
59     @Rule
60     public StaticMockitoRule mockitoRule = new StaticMockitoRule(
61             SystemProperties.class, Constants.class, PackageStateModulesUtils.class);
62 
63     @Mock protected PrimaryDexopter.Injector mInjector;
64     @Mock protected IArtd mArtd;
65     @Mock protected UserManager mUserManager;
66     @Mock protected DexUseManagerLocal mDexUseManager;
67     @Mock protected StorageManager mStorageManager;
68     protected PackageState mPkgState;
69     protected AndroidPackage mPkg;
70     protected PackageUserState mPkgUserStateNotInstalled;
71     protected PackageUserState mPkgUserStateInstalled;
72     protected CancellationSignal mCancellationSignal;
73 
74     @Before
setUp()75     public void setUp() throws Exception {
76         lenient().when(mInjector.getArtd()).thenReturn(mArtd);
77         lenient().when(mInjector.isSystemUiPackage(any())).thenReturn(false);
78         lenient().when(mInjector.isLauncherPackage(any())).thenReturn(false);
79         lenient().when(mInjector.getUserManager()).thenReturn(mUserManager);
80         lenient().when(mInjector.getDexUseManager()).thenReturn(mDexUseManager);
81         lenient().when(mInjector.getStorageManager()).thenReturn(mStorageManager);
82         lenient().when(mInjector.getArtVersion()).thenReturn(ART_VERSION);
83 
84         lenient()
85                 .when(SystemProperties.get("dalvik.vm.systemuicompilerfilter"))
86                 .thenReturn("speed");
87         lenient()
88                 .when(SystemProperties.getBoolean(eq("dalvik.vm.always_debuggable"), anyBoolean()))
89                 .thenReturn(false);
90         lenient().when(SystemProperties.get("dalvik.vm.appimageformat")).thenReturn("lz4");
91         lenient().when(SystemProperties.get("pm.dexopt.shared")).thenReturn("speed");
92 
93         // No ISA translation.
94         lenient()
95                 .when(SystemProperties.get(argThat(arg -> arg.startsWith("ro.dalvik.vm.isa."))))
96                 .thenReturn("");
97 
98         lenient().when(Constants.getPreferredAbi()).thenReturn("arm64-v8a");
99         lenient().when(Constants.getNative64BitAbi()).thenReturn("arm64-v8a");
100         lenient().when(Constants.getNative32BitAbi()).thenReturn("armeabi-v7a");
101 
102         lenient()
103                 .when(mUserManager.getUserHandles(anyBoolean()))
104                 .thenReturn(List.of(UserHandle.of(0), UserHandle.of(1), UserHandle.of(2)));
105 
106         lenient().when(mDexUseManager.isPrimaryDexUsedByOtherApps(any(), any())).thenReturn(false);
107 
108         lenient().when(mStorageManager.getAllocatableBytes(any())).thenReturn(1l);
109 
110         mPkgUserStateNotInstalled = createPackageUserState(false /* installed */);
111         mPkgUserStateInstalled = createPackageUserState(true /* installed */);
112         mPkgState = createPackageState();
113         mPkg = mPkgState.getAndroidPackage();
114         mCancellationSignal = new CancellationSignal();
115     }
116 
createPackage()117     private AndroidPackage createPackage() {
118         // This package has the base APK and one split APK that has code.
119         AndroidPackage pkg = mock(AndroidPackage.class);
120         var baseSplit = mock(AndroidPackageSplit.class);
121         lenient().when(baseSplit.getPath()).thenReturn("/data/app/foo/base.apk");
122         lenient().when(baseSplit.isHasCode()).thenReturn(true);
123         lenient().when(baseSplit.getClassLoaderName()).thenReturn(PathClassLoader.class.getName());
124 
125         var split0 = mock(AndroidPackageSplit.class);
126         lenient().when(split0.getName()).thenReturn("split_0");
127         lenient().when(split0.getPath()).thenReturn("/data/app/foo/split_0.apk");
128         lenient().when(split0.isHasCode()).thenReturn(true);
129 
130         var split1 = mock(AndroidPackageSplit.class);
131         lenient().when(split1.getName()).thenReturn("split_1");
132         lenient().when(split1.getPath()).thenReturn("/data/app/foo/split_1.apk");
133         lenient().when(split1.isHasCode()).thenReturn(false);
134 
135         var splits = List.of(baseSplit, split0, split1);
136         lenient().when(pkg.getSplits()).thenReturn(splits);
137 
138         lenient().when(pkg.isVmSafeMode()).thenReturn(false);
139         lenient().when(pkg.isDebuggable()).thenReturn(false);
140         lenient().when(pkg.getTargetSdkVersion()).thenReturn(123);
141         lenient().when(pkg.isSignedWithPlatformKey()).thenReturn(false);
142         lenient().when(pkg.isNonSdkApiRequested()).thenReturn(false);
143         lenient().when(pkg.getVersionName()).thenReturn(APP_VERSION_NAME);
144         lenient().when(pkg.getLongVersionCode()).thenReturn(APP_VERSION_CODE);
145         return pkg;
146     }
147 
createPackageState()148     private PackageState createPackageState() {
149         PackageState pkgState = mock(PackageState.class);
150         lenient().when(pkgState.getPackageName()).thenReturn(PKG_NAME);
151         lenient().when(pkgState.getPrimaryCpuAbi()).thenReturn("arm64-v8a");
152         lenient().when(pkgState.getSecondaryCpuAbi()).thenReturn("armeabi-v7a");
153         lenient().when(pkgState.isSystem()).thenReturn(false);
154         lenient().when(pkgState.isUpdatedSystemApp()).thenReturn(false);
155         lenient().when(pkgState.getAppId()).thenReturn(UID);
156         lenient().when(pkgState.getSharedLibraryDependencies()).thenReturn(new ArrayList<>());
157         lenient().when(pkgState.getStateForUser(any())).thenReturn(mPkgUserStateNotInstalled);
158         AndroidPackage pkg = createPackage();
159         lenient().when(pkgState.getAndroidPackage()).thenReturn(pkg);
160         lenient()
161                 .when(PackageStateModulesUtils.isLoadableInOtherProcesses(
162                         same(pkgState), anyBoolean()))
163                 .thenReturn(false);
164         return pkgState;
165     }
166 
createPackageUserState(boolean isInstalled)167     private PackageUserState createPackageUserState(boolean isInstalled) {
168         PackageUserState pkgUserState = mock(PackageUserState.class);
169         lenient().when(pkgUserState.isInstalled()).thenReturn(isInstalled);
170         return pkgUserState;
171     }
172 
dexoptIsNotNeeded()173     protected GetDexoptNeededResult dexoptIsNotNeeded() {
174         var result = new GetDexoptNeededResult();
175         result.isDexoptNeeded = false;
176         return result;
177     }
178 
dexoptIsNeeded()179     protected GetDexoptNeededResult dexoptIsNeeded() {
180         return dexoptIsNeeded(ArtifactsLocation.NONE_OR_ERROR);
181     }
182 
dexoptIsNeeded(@rtifactsLocation byte location)183     protected GetDexoptNeededResult dexoptIsNeeded(@ArtifactsLocation byte location) {
184         var result = new GetDexoptNeededResult();
185         result.isDexoptNeeded = true;
186         result.artifactsLocation = location;
187         if (location != ArtifactsLocation.NONE_OR_ERROR) {
188             result.isVdexUsable = true;
189         }
190         return result;
191     }
192 
createArtdDexoptResult(boolean cancelled, long wallTimeMs, long cpuTimeMs, long sizeBytes, long sizeBeforeBytes)193     protected ArtdDexoptResult createArtdDexoptResult(boolean cancelled, long wallTimeMs,
194             long cpuTimeMs, long sizeBytes, long sizeBeforeBytes) {
195         var result = new ArtdDexoptResult();
196         result.cancelled = cancelled;
197         result.wallTimeMs = wallTimeMs;
198         result.cpuTimeMs = cpuTimeMs;
199         result.sizeBytes = sizeBytes;
200         result.sizeBeforeBytes = sizeBeforeBytes;
201         return result;
202     }
203 
createArtdDexoptResult(boolean cancelled)204     protected ArtdDexoptResult createArtdDexoptResult(boolean cancelled) {
205         return createArtdDexoptResult(cancelled, 0 /* wallTimeMs */, 0 /* cpuTimeMs */,
206                 0 /* sizeBytes */, 0 /* sizeBeforeBytes */);
207     }
208 }
209