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