• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.tests.loadingprogress.device;
18 
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertTrue;
21 
22 import android.annotation.NonNull;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.LauncherActivityInfo;
27 import android.content.pm.LauncherApps;
28 import android.content.pm.PackageManager;
29 import android.os.ConditionVariable;
30 import android.os.Handler;
31 import android.os.HandlerThread;
32 import android.os.Process;
33 import android.os.UserHandle;
34 
35 import androidx.test.filters.LargeTest;
36 import androidx.test.platform.app.InstrumentationRegistry;
37 import androidx.test.runner.AndroidJUnit4;
38 
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.io.File;
45 import java.nio.file.Files;
46 import java.nio.file.Paths;
47 import java.util.List;
48 import java.util.function.Predicate;
49 
50 /**
51  * Device-side test, launched by the host-side test only and should not be called directly.
52  */
53 @RunWith(AndroidJUnit4.class)
54 @LargeTest
55 public class LoadingProgressTest {
56     private static final String TEST_PACKAGE_NAME = "com.android.tests.loadingprogress.app";
57     private static final String REGISTER_APP_NAME = "com.android.tests.loadingprogress.registerapp";
58 
59     protected Context mContext;
60     private PackageManager mPackageManager;
61     private UserHandle mUser;
62     private LauncherApps mLauncherApps;
63     private static final int WAIT_TIMEOUT_MILLIS = 2000; /* 2 second */
64     private ConditionVariable mCalled  = new ConditionVariable();
65     private final HandlerThread mCallbackThread = new HandlerThread("callback");
66     private LauncherAppsCallback mCallback;
67 
68     @Before
setUp()69     public void setUp() {
70         mContext = InstrumentationRegistry.getInstrumentation().getContext();
71         mPackageManager = mContext.getPackageManager();
72         assertNotNull(mPackageManager);
73         mUser = Process.myUserHandle();
74         mLauncherApps = mContext.getSystemService(LauncherApps.class);
75         mCallbackThread.start();
76     }
77 
78     @After
tearDown()79     public void tearDown() {
80         mCallbackThread.quit();
81         if (mCallback != null) {
82             mLauncherApps.unregisterCallback(mCallback);
83         }
84     }
85 
86     @Test
registerFirstLauncherAppsCallback()87     public void registerFirstLauncherAppsCallback() {
88         final Intent intent = mPackageManager.getLaunchIntentForPackage(REGISTER_APP_NAME);
89         assertNotNull(intent);
90         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
91         mContext.startActivity(intent);
92     }
93 
94     @Test
testGetPartialLoadingProgress()95     public void testGetPartialLoadingProgress() throws Exception {
96         // Package is installed but only partially streamed
97         checkLoadingProgress(loadingProgress -> loadingProgress < 1.0f && loadingProgress > 0);
98     }
99 
100     @Test
testReadAllBytes()101     public void testReadAllBytes() throws Exception {
102         ApplicationInfo appInfo = mLauncherApps.getApplicationInfo(
103                 TEST_PACKAGE_NAME, /* flags= */ 0, mUser);
104         final String codePath = appInfo.sourceDir;
105         final String apkDir = codePath.substring(0, codePath.lastIndexOf('/'));
106         for (String apkName : new File(apkDir).list()) {
107             final String apkPath = apkDir + "/" + apkName;
108             assertTrue(new File(apkPath).exists());
109             byte[] apkContentBytes = Files.readAllBytes(Paths.get(apkPath));
110             assertNotNull(apkContentBytes);
111             assertTrue(apkContentBytes.length > 0);
112         }
113     }
114 
115     @Test
testGetFullLoadingProgress()116     public void testGetFullLoadingProgress() throws Exception {
117         // Package should be fully streamed now
118         checkLoadingProgress(loadingProgress -> (1 - loadingProgress) < 0.001f);
119     }
120 
checkLoadingProgress(Predicate<Float> progressCondition)121     private void checkLoadingProgress(Predicate<Float> progressCondition) {
122         List<LauncherActivityInfo> activities =
123                 mLauncherApps.getActivityList(TEST_PACKAGE_NAME, mUser);
124         boolean foundTestApp = false;
125         for (LauncherActivityInfo activity : activities) {
126             if (activity.getComponentName().getPackageName().equals(
127                     TEST_PACKAGE_NAME)) {
128                 foundTestApp = true;
129                 final float progress = activity.getLoadingProgress();
130                 assertTrue("progress <" + progress + "> does not meet requirement",
131                         progressCondition.test(progress));
132             }
133             assertTrue(activity.getUser().equals(mUser));
134         }
135         assertTrue(foundTestApp);
136     }
137 
138     @Test
testOnPackageLoadingProgressChangedCalledWithPartialLoaded()139     public void testOnPackageLoadingProgressChangedCalledWithPartialLoaded() throws Exception {
140         mCalled.close();
141         mCallback = new LauncherAppsCallback(
142                 loadingProgress -> loadingProgress < 1.0f && loadingProgress > 0);
143         mLauncherApps.registerCallback(mCallback, new Handler(mCallbackThread.getLooper()));
144         assertTrue(mCalled.block(WAIT_TIMEOUT_MILLIS));
145     }
146 
147     @Test
testOnPackageLoadingProgressChangedCalledWithFullyLoaded()148     public void testOnPackageLoadingProgressChangedCalledWithFullyLoaded() throws Exception {
149         mCalled.close();
150         mCallback = new LauncherAppsCallback(loadingProgress -> 1 - loadingProgress < 0.001);
151         mLauncherApps.registerCallback(mCallback, new Handler(mCallbackThread.getLooper()));
152         testReadAllBytes();
153         assertTrue(mCalled.block(WAIT_TIMEOUT_MILLIS));
154     }
155 
156     class LauncherAppsCallback extends LauncherApps.Callback {
157         private final Predicate<Float> mCondition;
LauncherAppsCallback(Predicate<Float> progressCondition)158         LauncherAppsCallback(Predicate<Float> progressCondition) {
159             mCondition = progressCondition;
160         }
161         @Override
onPackageRemoved(String packageName, UserHandle user)162         public void onPackageRemoved(String packageName, UserHandle user) {
163         }
164 
165         @Override
onPackageAdded(String packageName, UserHandle user)166         public void onPackageAdded(String packageName, UserHandle user) {
167         }
168 
169         @Override
onPackageChanged(String packageName, UserHandle user)170         public void onPackageChanged(String packageName, UserHandle user) {
171         }
172 
173         @Override
onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing)174         public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
175         }
176 
177         @Override
onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing)178         public void onPackagesUnavailable(String[] packageNames, UserHandle user,
179                 boolean replacing) {
180         }
181 
182         @Override
onPackageLoadingProgressChanged(@onNull String packageName, @NonNull UserHandle user, float progress)183         public void onPackageLoadingProgressChanged(@NonNull String packageName,
184                 @NonNull UserHandle user, float progress) {
185             if (mCondition.test(progress)) {
186                 // Only release when progress meets the expected condition
187                 mCalled.open();
188             }
189         }
190     }
191 }
192