1 /*
2  * Copyright (C) 2019 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.launcher3.shadows;
18 
19 import static org.robolectric.util.ReflectionHelpers.ClassParameter;
20 import static org.robolectric.util.ReflectionHelpers.callConstructor;
21 
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.ActivityInfo;
26 import android.content.pm.ApplicationInfo;
27 import android.content.pm.LauncherActivityInfo;
28 import android.content.pm.LauncherApps;
29 import android.content.pm.PackageInstaller;
30 import android.content.pm.PackageManager;
31 import android.content.pm.ResolveInfo;
32 import android.content.pm.ShortcutInfo;
33 import android.os.UserHandle;
34 import android.util.ArraySet;
35 
36 import com.android.launcher3.util.ComponentKey;
37 import com.android.launcher3.util.PackageUserKey;
38 
39 import org.robolectric.RuntimeEnvironment;
40 import org.robolectric.annotation.Implementation;
41 import org.robolectric.annotation.Implements;
42 import org.robolectric.shadows.ShadowLauncherApps;
43 
44 import java.util.Collections;
45 import java.util.List;
46 import java.util.concurrent.Executor;
47 import java.util.stream.Collectors;
48 
49 /**
50  * Extension of {@link ShadowLauncherApps} with missing shadow methods
51  */
52 @Implements(value = LauncherApps.class)
53 public class LShadowLauncherApps extends ShadowLauncherApps {
54 
55     public final ArraySet<PackageUserKey> disabledApps = new ArraySet<>();
56     public final ArraySet<ComponentKey> disabledActivities = new ArraySet<>();
57 
58     @Implementation
59     @Override
getShortcuts(LauncherApps.ShortcutQuery query, UserHandle user)60     protected List<ShortcutInfo> getShortcuts(LauncherApps.ShortcutQuery query, UserHandle user) {
61         try {
62             return super.getShortcuts(query, user);
63         } catch (UnsupportedOperationException e) {
64             return Collections.emptyList();
65         }
66     }
67 
68     @Implementation
isPackageEnabled(String packageName, UserHandle user)69     protected boolean isPackageEnabled(String packageName, UserHandle user) {
70         return !disabledApps.contains(new PackageUserKey(packageName, user));
71     }
72 
73     @Implementation
isActivityEnabled(ComponentName component, UserHandle user)74     protected boolean isActivityEnabled(ComponentName component, UserHandle user) {
75         return !disabledActivities.contains(new ComponentKey(component, user));
76     }
77 
78     @Implementation
resolveActivity(Intent intent, UserHandle user)79     protected LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
80         ResolveInfo ri = RuntimeEnvironment.application.getPackageManager()
81                 .resolveActivity(intent, 0);
82         return ri == null ? null : getLauncherActivityInfo(ri.activityInfo, user);
83     }
84 
getLauncherActivityInfo( ActivityInfo activityInfo, UserHandle user)85     public LauncherActivityInfo getLauncherActivityInfo(
86             ActivityInfo activityInfo, UserHandle user) {
87         return callConstructor(LauncherActivityInfo.class,
88                 ClassParameter.from(Context.class, RuntimeEnvironment.application),
89                 ClassParameter.from(ActivityInfo.class, activityInfo),
90                 ClassParameter.from(UserHandle.class, user));
91     }
92 
93     @Implementation
getApplicationInfo(String packageName, int flags, UserHandle user)94     public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
95             throws PackageManager.NameNotFoundException {
96         return RuntimeEnvironment.application.getPackageManager()
97                 .getApplicationInfo(packageName, flags);
98     }
99 
100     @Implementation
getActivityList(String packageName, UserHandle user)101     public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
102         Intent intent = new Intent(Intent.ACTION_MAIN)
103                 .addCategory(Intent.CATEGORY_LAUNCHER)
104                 .setPackage(packageName);
105         return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
106                 .stream()
107                 .map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
108                 .collect(Collectors.toList());
109     }
110 
111     @Implementation
hasShortcutHostPermission()112     public boolean hasShortcutHostPermission() {
113         return true;
114     }
115 
116     @Implementation
getAllPackageInstallerSessions()117     public List<PackageInstaller.SessionInfo> getAllPackageInstallerSessions() {
118         return RuntimeEnvironment.application.getPackageManager().getPackageInstaller()
119                 .getAllSessions();
120     }
121 
122     @Implementation
registerPackageInstallerSessionCallback( Executor executor, PackageInstaller.SessionCallback callback)123     public void registerPackageInstallerSessionCallback(
124             Executor executor, PackageInstaller.SessionCallback callback) {
125     }
126 
127     @Override
getShortcutConfigActivityList(String packageName, UserHandle user)128     protected List<LauncherActivityInfo> getShortcutConfigActivityList(String packageName,
129             UserHandle user) {
130         Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName);
131         return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
132                 .stream()
133                 .map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
134                 .collect(Collectors.toList());
135     }
136 }
137