blob: 23655a08397d9fee456c1ba81e8096ee76deb7b5 [file] [log] [blame]
Ryan Mitchell9b939422020-02-04 10:18:53 -08001/*
2 * Copyright (C) 2020 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
17package com.android.internal.content;
18
19import static org.mockito.ArgumentMatchers.any;
20import static org.mockito.Mockito.doAnswer;
21import static org.mockito.Mockito.doReturn;
22import static org.mockito.Mockito.when;
23
24import android.content.pm.parsing.AndroidPackage;
25import android.os.Build;
26import android.util.ArrayMap;
27
28import com.android.internal.content.om.OverlayConfig.AndroidPackageProvider;
29import com.android.internal.content.om.OverlayScanner;
30import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
31
32import org.junit.Assert;
33import org.junit.rules.TestRule;
34import org.junit.runner.Description;
35import org.junit.runners.model.Statement;
36import org.mockito.Mockito;
37import org.mockito.invocation.InvocationOnMock;
38
39import java.io.File;
40import java.io.IOException;
41import java.util.Map;
42import java.util.function.Consumer;
43import java.util.function.Supplier;
44
45/**
46 * A {@link TestRule} that runs a test case twice. First, the test case runs with a non-null
47 * {@link OverlayScanner} as if the zygote process is scanning the overlay packages
48 * and parsing configuration files. The test case then runs with a non-null
49 * {@link AndroidPackageProvider} as if the system server is parsing configuration files.
50 *
51 * This simulates what will happen on device. If an exception would be thrown in the zygote, then
52 * the exception should be thrown in the first run of the test case.
53 */
54public class OverlayConfigIterationRule implements TestRule {
55
56 enum Iteration {
57 ZYGOTE,
58 SYSTEM_SERVER,
59 }
60
61 private final ArrayMap<File, ParsedOverlayInfo> mOverlayStubResults = new ArrayMap<>();
62 private Supplier<OverlayScanner> mOverlayScanner;
63 private AndroidPackageProvider mAndroidPackageProvider;
64 private Iteration mIteration;
65
66 /**
67 * Mocks the parsing of the file to make it appear to the scanner that the file is a valid
68 * overlay APK.
69 **/
70 void addOverlay(File path, String packageName, String targetPackage, int targetSdkVersion,
71 boolean isStatic, int priority) {
72 try {
73 final File canonicalPath = new File(path.getCanonicalPath());
74 mOverlayStubResults.put(canonicalPath, new ParsedOverlayInfo(
75 packageName, targetPackage, targetSdkVersion, isStatic, priority,
76 canonicalPath));
77 } catch (IOException e) {
78 Assert.fail("Failed to add overlay " + e);
79 }
80 }
81
82 void addOverlay(File path, String packageName) {
83 addOverlay(path, packageName, "target");
84 }
85
86 void addOverlay(File path, String packageName, String targetPackage) {
87 addOverlay(path, packageName, targetPackage, Build.VERSION_CODES.CUR_DEVELOPMENT);
88 }
89
90 void addOverlay(File path, String packageName, String targetPackage, int targetSdkVersion) {
91 addOverlay(path, packageName, targetPackage, targetSdkVersion, false, 0);
92 }
93
94 /** Retrieves the {@link OverlayScanner} for the current run of the test. */
95 Supplier<OverlayScanner> getScannerFactory() {
96 return mOverlayScanner;
97 }
98
99 /** Retrieves the {@link AndroidPackageProvider} for the current run of the test. */
100 AndroidPackageProvider getPackageProvider() {
101 return mAndroidPackageProvider;
102 }
103
104 /** Retrieves the current iteration of the test. */
105 Iteration getIteration() {
106 return mIteration;
107 }
108
109
110 @Override
111 public Statement apply(Statement base, Description description) {
112 return new Statement() {
113 @Override
114 public void evaluate() throws Throwable {
115 // Run the test once as if the zygote process is scanning the overlay packages
116 // and parsing configuration files.
117 mOverlayScanner = () -> {
118 OverlayScanner scanner = Mockito.spy(new OverlayScanner());
119 for (Map.Entry<File, ParsedOverlayInfo> overlay :
120 mOverlayStubResults.entrySet()) {
121 doReturn(overlay.getValue()).when(scanner)
122 .parseOverlayManifest(overlay.getKey());
123 }
124 return scanner;
125 };
126 mAndroidPackageProvider = null;
127 mIteration = Iteration.ZYGOTE;
128 base.evaluate();
129
130 // Run the test once more (if the first test did not throw an exception) as if
131 // the system server is parsing the configuration files and using PackageManager to
132 // retrieving information of overlays.
133 mOverlayScanner = null;
134 mAndroidPackageProvider = Mockito.mock(AndroidPackageProvider.class);
135 mIteration = Iteration.SYSTEM_SERVER;
136 doAnswer((InvocationOnMock invocation) -> {
137 final Object[] args = invocation.getArguments();
138 final Consumer<AndroidPackage> f = (Consumer<AndroidPackage>) args[0];
139 for (Map.Entry<File, ParsedOverlayInfo> overlay :
140 mOverlayStubResults.entrySet()) {
141 final AndroidPackage a = Mockito.mock(AndroidPackage.class);
142 final ParsedOverlayInfo info = overlay.getValue();
143 when(a.getPackageName()).thenReturn(info.packageName);
144 when(a.getOverlayTarget()).thenReturn(info.targetPackageName);
145 when(a.getTargetSdkVersion()).thenReturn(info.targetSdkVersion);
146 when(a.isOverlayIsStatic()).thenReturn(info.isStatic);
147 when(a.getOverlayPriority()).thenReturn(info.priority);
148 when(a.getBaseCodePath()).thenReturn(info.path.getPath());
149 when(a.isSystem()).thenReturn(
150 !info.path.getPath().contains("data/overlay"));
151 f.accept(a);
152 }
153 return null;
154 }).when(mAndroidPackageProvider).forEachPackage(any());
155
156 base.evaluate();
157 }
158 };
159 }
160}
161
162