1/*
2 * Copyright (C) 2014 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
17package android.content.pm;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.pm.PackageManager.NameNotFoundException;
22import android.content.res.Resources;
23import android.graphics.drawable.BitmapDrawable;
24import android.graphics.drawable.Drawable;
25import android.os.UserHandle;
26import android.os.UserManager;
27import android.util.DisplayMetrics;
28import android.util.Log;
29
30/**
31 * A representation of an activity that can belong to this user or a managed
32 * profile associated with this user. It can be used to query the label, icon
33 * and badged icon for the activity.
34 */
35public class LauncherActivityInfo {
36    private static final String TAG = "LauncherActivityInfo";
37
38    private final PackageManager mPm;
39
40    private ActivityInfo mActivityInfo;
41    private ComponentName mComponentName;
42    private ResolveInfo mResolveInfo;
43    private UserHandle mUser;
44    private long mFirstInstallTime;
45
46    /**
47     * Create a launchable activity object for a given ResolveInfo and user.
48     *
49     * @param context The context for fetching resources.
50     * @param info ResolveInfo from which to create the LauncherActivityInfo.
51     * @param user The UserHandle of the profile to which this activity belongs.
52     */
53    LauncherActivityInfo(Context context, ResolveInfo info, UserHandle user,
54            long firstInstallTime) {
55        this(context);
56        mResolveInfo = info;
57        mActivityInfo = info.activityInfo;
58        mComponentName = LauncherApps.getComponentName(info);
59        mUser = user;
60        mFirstInstallTime = firstInstallTime;
61    }
62
63    LauncherActivityInfo(Context context) {
64        mPm = context.getPackageManager();
65    }
66
67    /**
68     * Returns the component name of this activity.
69     *
70     * @return ComponentName of the activity
71     */
72    public ComponentName getComponentName() {
73        return mComponentName;
74    }
75
76    /**
77     * Returns the user handle of the user profile that this activity belongs to. In order to
78     * persist the identity of the profile, do not store the UserHandle. Instead retrieve its
79     * serial number from UserManager. You can convert the serial number back to a UserHandle
80     * for later use.
81     *
82     * @see UserManager#getSerialNumberForUser(UserHandle)
83     * @see UserManager#getUserForSerialNumber(long)
84     *
85     * @return The UserHandle of the profile.
86     */
87    public UserHandle getUser() {
88        return mUser;
89    }
90
91    /**
92     * Retrieves the label for the activity.
93     *
94     * @return The label for the activity.
95     */
96    public CharSequence getLabel() {
97        return mResolveInfo.loadLabel(mPm);
98    }
99
100    /**
101     * Returns the icon for this activity, without any badging for the profile.
102     * @param density The preferred density of the icon, zero for default density. Use
103     * density DPI values from {@link DisplayMetrics}.
104     * @see #getBadgedIcon(int)
105     * @see DisplayMetrics
106     * @return The drawable associated with the activity.
107     */
108    public Drawable getIcon(int density) {
109        final int iconRes = mResolveInfo.getIconResource();
110        Drawable icon = getDrawableForDensity(iconRes, density);
111        // Get the default density icon
112        if (icon == null) {
113            icon = mResolveInfo.loadIcon(mPm);
114        }
115        return icon;
116    }
117
118    /**
119     * Returns the icon for this activity, without any badging for the profile.
120     * This function can get the icon no matter the icon needs to be badged or not.
121     * @param density The preferred density of the icon, zero for default density. Use
122     * density DPI values from {@link DisplayMetrics}.
123     * @see #getBadgedIcon(int)
124     * @see DisplayMetrics
125     * @return The drawable associated with the activity.
126     */
127    private Drawable getOriginalIcon(int density) {
128        final int iconRes = mResolveInfo.getIconResourceInternal();
129        Drawable icon = getDrawableForDensity(iconRes, density);
130        // Get the default density icon
131        if (icon == null) {
132            icon = mResolveInfo.loadIcon(mPm);
133        }
134        return icon;
135    }
136
137    /**
138     * Returns the drawable for this activity, without any badging for the profile.
139     * @param resource id of the drawable.
140     * @param density The preferred density of the icon, zero for default density. Use
141     * density DPI values from {@link DisplayMetrics}.
142     * @see DisplayMetrics
143     * @return The drawable associated with the resource id.
144     */
145    private Drawable getDrawableForDensity(int iconRes, int density) {
146        // Get the preferred density icon from the app's resources
147        if (density != 0 && iconRes != 0) {
148            try {
149                final Resources resources
150                        = mPm.getResourcesForApplication(mActivityInfo.applicationInfo);
151                return resources.getDrawableForDensity(iconRes, density);
152            } catch (NameNotFoundException | Resources.NotFoundException exc) {
153            }
154        }
155        return null;
156    }
157
158    /**
159     * Returns the application flags from the ApplicationInfo of the activity.
160     *
161     * @return Application flags
162     * @hide remove before shipping
163     */
164    public int getApplicationFlags() {
165        return mActivityInfo.applicationInfo.flags;
166    }
167
168    /**
169     * Returns the application info for the appliction this activity belongs to.
170     * @return
171     */
172    public ApplicationInfo getApplicationInfo() {
173        return mActivityInfo.applicationInfo;
174    }
175
176    /**
177     * Returns the time at which the package was first installed.
178     *
179     * @return The time of installation of the package, in milliseconds.
180     */
181    public long getFirstInstallTime() {
182        return mFirstInstallTime;
183    }
184
185    /**
186     * Returns the name for the acitivty from  android:name in the manifest.
187     * @return the name from android:name for the acitivity.
188     */
189    public String getName() {
190        return mActivityInfo.name;
191    }
192
193    /**
194     * Returns the activity icon with badging appropriate for the profile.
195     * @param density Optional density for the icon, or 0 to use the default density. Use
196     * {@link DisplayMetrics} for DPI values.
197     * @see DisplayMetrics
198     * @return A badged icon for the activity.
199     */
200    public Drawable getBadgedIcon(int density) {
201        Drawable originalIcon = getOriginalIcon(density);
202
203        if (originalIcon instanceof BitmapDrawable) {
204            return mPm.getUserBadgedIcon(originalIcon, mUser);
205        } else {
206            Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
207        }
208        return originalIcon;
209    }
210}
211