• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.model.data;
18 
19 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
20 
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.LauncherActivityInfo;
26 import android.os.Build;
27 import android.os.Process;
28 import android.os.UserHandle;
29 import android.os.UserManager;
30 
31 import androidx.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 import androidx.annotation.VisibleForTesting;
34 
35 import com.android.launcher3.LauncherSettings;
36 import com.android.launcher3.Utilities;
37 import com.android.launcher3.pm.PackageInstallInfo;
38 import com.android.launcher3.util.PackageManagerHelper;
39 
40 import java.util.Comparator;
41 
42 /**
43  * Represents an app in AllAppsView.
44  */
45 public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
46 
47     public static final AppInfo[] EMPTY_ARRAY = new AppInfo[0];
48     public static final Comparator<AppInfo> COMPONENT_KEY_COMPARATOR = (a, b) -> {
49         int uc = a.user.hashCode() - b.user.hashCode();
50         return uc != 0 ? uc : a.componentName.compareTo(b.componentName);
51     };
52 
53     /**
54      * The intent used to start the application.
55      */
56     public Intent intent;
57 
58     @NonNull
59     public ComponentName componentName;
60 
61     // Section name used for indexing.
62     public String sectionName = "";
63 
AppInfo()64     public AppInfo() {
65         itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
66     }
67 
68     @Override
69     @Nullable
getIntent()70     public Intent getIntent() {
71         return intent;
72     }
73 
74     /**
75      * Must not hold the Context.
76      */
AppInfo(Context context, LauncherActivityInfo info, UserHandle user)77     public AppInfo(Context context, LauncherActivityInfo info, UserHandle user) {
78         this(info, user, context.getSystemService(UserManager.class).isQuietModeEnabled(user));
79     }
80 
AppInfo(LauncherActivityInfo info, UserHandle user, boolean quietModeEnabled)81     public AppInfo(LauncherActivityInfo info, UserHandle user, boolean quietModeEnabled) {
82         this.componentName = info.getComponentName();
83         this.container = CONTAINER_ALL_APPS;
84         this.user = user;
85         intent = makeLaunchIntent(info);
86 
87         if (quietModeEnabled) {
88             runtimeStatusFlags |= FLAG_DISABLED_QUIET_USER;
89         }
90         updateRuntimeFlagsForActivityTarget(this, info);
91     }
92 
AppInfo(AppInfo info)93     public AppInfo(AppInfo info) {
94         super(info);
95         componentName = info.componentName;
96         title = Utilities.trim(info.title);
97         intent = new Intent(info.intent);
98     }
99 
100     @VisibleForTesting
AppInfo(ComponentName componentName, CharSequence title, UserHandle user, Intent intent)101     public AppInfo(ComponentName componentName, CharSequence title,
102             UserHandle user, Intent intent) {
103         this.componentName = componentName;
104         this.title = title;
105         this.user = user;
106         this.intent = intent;
107     }
108 
AppInfo(@onNull PackageInstallInfo installInfo)109     public AppInfo(@NonNull PackageInstallInfo installInfo) {
110         componentName = installInfo.componentName;
111         intent = new Intent(Intent.ACTION_MAIN)
112             .addCategory(Intent.CATEGORY_LAUNCHER)
113             .setComponent(componentName)
114             .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
115                 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
116         setProgressLevel(installInfo);
117         user = installInfo.user;
118     }
119 
120     @Override
dumpProperties()121     protected String dumpProperties() {
122         return super.dumpProperties() + " componentName=" + componentName;
123     }
124 
125     @Override
makeWorkspaceItem(Context context)126     public WorkspaceItemInfo makeWorkspaceItem(Context context) {
127         WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(this);
128 
129         if ((runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
130             // We need to update the component name when the apk is installed
131             workspaceItemInfo.status |= WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
132             // Since the user is manually placing it on homescreen, it should not be auto-removed
133             // later
134             workspaceItemInfo.status |= WorkspaceItemInfo.FLAG_RESTORE_STARTED;
135             workspaceItemInfo.status |= FLAG_INSTALL_SESSION_ACTIVE;
136         }
137         if ((runtimeStatusFlags & FLAG_INCREMENTAL_DOWNLOAD_ACTIVE) != 0) {
138             workspaceItemInfo.runtimeStatusFlags |= FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
139         }
140 
141         return workspaceItemInfo;
142     }
143 
makeLaunchIntent(LauncherActivityInfo info)144     public static Intent makeLaunchIntent(LauncherActivityInfo info) {
145         return makeLaunchIntent(info.getComponentName());
146     }
147 
makeLaunchIntent(ComponentName cn)148     public static Intent makeLaunchIntent(ComponentName cn) {
149         return new Intent(Intent.ACTION_MAIN)
150                 .addCategory(Intent.CATEGORY_LAUNCHER)
151                 .setComponent(cn)
152                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
153                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
154     }
155 
156     @NonNull
157     @Override
getTargetComponent()158     public ComponentName getTargetComponent() {
159         return componentName;
160     }
161 
updateRuntimeFlagsForActivityTarget( ItemInfoWithIcon info, LauncherActivityInfo lai)162     public static void updateRuntimeFlagsForActivityTarget(
163             ItemInfoWithIcon info, LauncherActivityInfo lai) {
164         ApplicationInfo appInfo = lai.getApplicationInfo();
165         if (PackageManagerHelper.isAppSuspended(appInfo)) {
166             info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
167         }
168         info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
169                 ? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
170 
171         if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O
172                 && Process.myUserHandle().equals(lai.getUser())) {
173             // The icon for a non-primary user is badged, hence it's not exactly an adaptive icon.
174             info.runtimeStatusFlags |= FLAG_ADAPTIVE_ICON;
175         }
176 
177         // Sets the progress level, installation and incremental download flags.
178         info.setProgressLevel(
179                 PackageManagerHelper.getLoadingProgress(lai),
180                 PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
181     }
182 
183     @Override
clone()184     public AppInfo clone() {
185         return new AppInfo(this);
186     }
187 }
188