• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 package com.android.launcher3.util;
17 
18 import static androidx.test.InstrumentationRegistry.getContext;
19 import static androidx.test.InstrumentationRegistry.getInstrumentation;
20 import static androidx.test.InstrumentationRegistry.getTargetContext;
21 
22 import android.content.pm.LauncherApps;
23 import android.content.res.Resources;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.os.UserHandle;
27 
28 import androidx.test.uiautomator.UiDevice;
29 
30 import com.android.launcher3.config.FeatureFlags;
31 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
32 import com.android.launcher3.config.FeatureFlags.IntFlag;
33 
34 import org.junit.Assert;
35 
36 import java.io.FileOutputStream;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.function.Predicate;
41 import java.util.function.ToIntFunction;
42 
43 public class TestUtil {
44     public static final String DUMMY_PACKAGE = "com.example.android.aardwolf";
45 
installDummyApp()46     public static void installDummyApp() throws IOException {
47         // Copy apk from resources to a local file and install from there.
48         final Resources resources = getContext().getResources();
49         final InputStream in = resources.openRawResource(
50                 resources.getIdentifier("aardwolf_dummy_app",
51                         "raw", getContext().getPackageName()));
52         final String apkFilename = getInstrumentation().getTargetContext().
53                 getFilesDir().getPath() + "/dummy_app.apk";
54 
55         try (PackageInstallCheck pic = new PackageInstallCheck()) {
56             final FileOutputStream out = new FileOutputStream(apkFilename);
57             byte[] buff = new byte[1024];
58             int read;
59 
60             while ((read = in.read(buff)) > 0) {
61                 out.write(buff, 0, read);
62             }
63             in.close();
64             out.close();
65 
66             final String result = UiDevice.getInstance(getInstrumentation())
67                     .executeShellCommand("pm install " + apkFilename);
68             Assert.assertTrue(
69                     "Failed to install wellbeing test apk; make sure the device is rooted",
70                     "Success".equals(result.replaceAll("\\s+", "")));
71             pic.mAddWait.await();
72         } catch (InterruptedException e) {
73             throw new IOException(e);
74         }
75     }
76 
77     /**
78      * Utility class to override a boolean flag during test. Note that the returned SafeCloseable
79      * must be closed to restore the original state
80      */
overrideFlag(BooleanFlag flag, boolean value)81     public static SafeCloseable overrideFlag(BooleanFlag flag, boolean value) {
82         Predicate<BooleanFlag> originalProxy = FeatureFlags.sBooleanReader;
83         Predicate<BooleanFlag> testProxy = f -> f == flag ? value : originalProxy.test(f);
84         FeatureFlags.sBooleanReader = testProxy;
85         return () -> {
86             if (FeatureFlags.sBooleanReader == testProxy) {
87                 FeatureFlags.sBooleanReader = originalProxy;
88             }
89         };
90     }
91 
92     /**
93      * Utility class to override a int flag during test. Note that the returned SafeCloseable
94      * must be closed to restore the original state
95      */
96     public static SafeCloseable overrideFlag(IntFlag flag, int value) {
97         ToIntFunction<IntFlag> originalProxy = FeatureFlags.sIntReader;
98         ToIntFunction<IntFlag> testProxy = f -> f == flag ? value : originalProxy.applyAsInt(f);
99         FeatureFlags.sIntReader = testProxy;
100         return () -> {
101             if (FeatureFlags.sIntReader == testProxy) {
102                 FeatureFlags.sIntReader = originalProxy;
103             }
104         };
105     }
106 
107     public static void uninstallDummyApp() throws IOException {
108         UiDevice.getInstance(getInstrumentation()).executeShellCommand(
109                 "pm uninstall " + DUMMY_PACKAGE);
110     }
111 
112     private static class PackageInstallCheck extends LauncherApps.Callback
113             implements AutoCloseable {
114 
115         final CountDownLatch mAddWait = new CountDownLatch(1);
116         final LauncherApps mLauncherApps;
117 
118         PackageInstallCheck() {
119             mLauncherApps = getTargetContext().getSystemService(LauncherApps.class);
120             mLauncherApps.registerCallback(this, new Handler(Looper.getMainLooper()));
121         }
122 
123         private void verifyPackage(String packageName) {
124             if (DUMMY_PACKAGE.equals(packageName)) {
125                 mAddWait.countDown();
126             }
127         }
128 
129         @Override
130         public void onPackageAdded(String packageName, UserHandle user) {
131             verifyPackage(packageName);
132         }
133 
134         @Override
135         public void onPackageChanged(String packageName, UserHandle user) {
136             verifyPackage(packageName);
137         }
138 
139         @Override
140         public void onPackageRemoved(String packageName, UserHandle user) { }
141 
142         @Override
143         public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
144             for (String packageName : packageNames) {
145                 verifyPackage(packageName);
146             }
147         }
148 
149         @Override
150         public void onPackagesUnavailable(String[] packageNames, UserHandle user,
151                 boolean replacing) { }
152 
153         @Override
154         public void close() {
155             mLauncherApps.unregisterCallback(this);
156         }
157     }
158 }
159