• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2007, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 package com.android.packageinstaller;
19 
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.app.Activity;
23 import android.content.Context;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageInfo;
26 import android.content.pm.PackageManager;
27 import android.content.res.AssetManager;
28 import android.content.res.Resources;
29 import android.graphics.drawable.Drawable;
30 import android.os.UserHandle;
31 import android.util.Log;
32 import android.view.View;
33 import android.widget.ImageView;
34 import android.widget.TextView;
35 
36 import java.io.File;
37 
38 /**
39  * This is a utility class for defining some utility methods and constants
40  * used in the package installer application.
41  */
42 public class PackageUtil {
43     private static final String LOG_TAG = PackageUtil.class.getSimpleName();
44 
45     public static final String PREFIX="com.android.packageinstaller.";
46     public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
47     public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
48     public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
49     //intent attribute strings related to uninstall
50     public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
51 
52     /**
53      * Utility method to get package information for a given {@link File}
54      */
55     @Nullable
getPackageInfo(Context context, File sourceFile, int flags)56     public static PackageInfo getPackageInfo(Context context, File sourceFile, int flags) {
57         try {
58             return context.getPackageManager().getPackageArchiveInfo(sourceFile.getAbsolutePath(),
59                     flags);
60         } catch (Exception ignored) {
61             return null;
62         }
63     }
64 
initSnippet(View snippetView, CharSequence label, Drawable icon)65     public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
66         ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
67         ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
68         return snippetView;
69     }
70 
71     /**
72      * Utility method to display a snippet of an installed application.
73      * The content view should have been set on context before invoking this method.
74      * appSnippet view should include R.id.app_icon and R.id.app_name
75      * defined on it.
76      *
77      * @param pContext context of package that can load the resources
78      * @param componentInfo ComponentInfo object whose resources are to be loaded
79      * @param snippetView the snippet view
80      */
initSnippetForInstalledApp(Context pContext, ApplicationInfo appInfo, View snippetView)81     public static View initSnippetForInstalledApp(Context pContext,
82             ApplicationInfo appInfo, View snippetView) {
83         return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
84     }
85 
86     /**
87      * Utility method to display a snippet of an installed application.
88      * The content view should have been set on context before invoking this method.
89      * appSnippet view should include R.id.app_icon and R.id.app_name
90      * defined on it.
91      *
92      * @param pContext context of package that can load the resources
93      * @param componentInfo ComponentInfo object whose resources are to be loaded
94      * @param snippetView the snippet view
95      * @param UserHandle user that the app si installed for.
96      */
initSnippetForInstalledApp(Context pContext, ApplicationInfo appInfo, View snippetView, UserHandle user)97     public static View initSnippetForInstalledApp(Context pContext,
98             ApplicationInfo appInfo, View snippetView, UserHandle user) {
99         final PackageManager pm = pContext.getPackageManager();
100         Drawable icon = appInfo.loadIcon(pm);
101         if (user != null) {
102             icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
103         }
104         return initSnippet(
105                 snippetView,
106                 appInfo.loadLabel(pm),
107                 icon);
108     }
109 
110     static final class AppSnippet {
111         @NonNull public CharSequence label;
112         @Nullable public Drawable icon;
AppSnippet(@onNull CharSequence label, @Nullable Drawable icon)113         public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
114             this.label = label;
115             this.icon = icon;
116         }
117 
118         @Override
toString()119         public String toString() {
120             return "AppSnippet[" + label + (icon != null ? "(has" : "(no ") + " icon)]";
121         }
122     }
123 
124     /**
125      * Utility method to load application label
126      *
127      * @param pContext context of package that can load the resources
128      * @param appInfo ApplicationInfo object of package whose resources are to be loaded
129      * @param sourceFile File the package is in
130      */
getAppSnippet( Activity pContext, ApplicationInfo appInfo, File sourceFile)131     public static AppSnippet getAppSnippet(
132             Activity pContext, ApplicationInfo appInfo, File sourceFile) {
133         final String archiveFilePath = sourceFile.getAbsolutePath();
134         Resources pRes = pContext.getResources();
135         AssetManager assmgr = new AssetManager();
136         assmgr.addAssetPath(archiveFilePath);
137         Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
138         CharSequence label = null;
139         // Try to load the label from the package's resources. If an app has not explicitly
140         // specified any label, just use the package name.
141         if (appInfo.labelRes != 0) {
142             try {
143                 label = res.getText(appInfo.labelRes);
144             } catch (Resources.NotFoundException e) {
145             }
146         }
147         if (label == null) {
148             label = (appInfo.nonLocalizedLabel != null) ?
149                     appInfo.nonLocalizedLabel : appInfo.packageName;
150         }
151         Drawable icon = null;
152         // Try to load the icon from the package's resources. If an app has not explicitly
153         // specified any resource, just use the default icon for now.
154         try {
155             if (appInfo.icon != 0) {
156                 try {
157                     icon = res.getDrawable(appInfo.icon);
158                 } catch (Resources.NotFoundException e) {
159                 }
160             }
161             if (icon == null) {
162                 icon = pContext.getPackageManager().getDefaultActivityIcon();
163             }
164         } catch (OutOfMemoryError e) {
165             Log.i(LOG_TAG, "Could not load app icon", e);
166         }
167         return new PackageUtil.AppSnippet(label, icon);
168     }
169 
170     /**
171      * Get the maximum target sdk for a UID.
172      *
173      * @param context The context to use
174      * @param uid The UID requesting the install/uninstall
175      *
176      * @return The maximum target SDK or -1 if the uid does not match any packages.
177      */
getMaxTargetSdkVersionForUid(@onNull Context context, int uid)178     static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) {
179         PackageManager pm = context.getPackageManager();
180         final String[] packages = pm.getPackagesForUid(uid);
181         int targetSdkVersion = -1;
182         if (packages != null) {
183             for (String packageName : packages) {
184                 try {
185                     ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
186                     targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion);
187                 } catch (PackageManager.NameNotFoundException e) {
188                     // Ignore and try the next package
189                 }
190             }
191         }
192         return targetSdkVersion;
193     }
194 }
195