blob: 0e89f56d237624e4702fc820fb461745ad810eea [file] [log] [blame]
Philip P. Moltmannd85d9412018-07-25 11:23:02 -07001/*
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
18package com.android.packageinstaller;
19
Philip P. Moltmannf325e282018-08-01 09:57:01 -070020import android.annotation.NonNull;
21import android.annotation.Nullable;
Philip P. Moltmannd85d9412018-07-25 11:23:02 -070022import android.app.Activity;
23import android.content.Context;
24import android.content.pm.ApplicationInfo;
25import android.content.pm.PackageManager;
26import android.content.pm.PackageParser;
27import android.content.pm.PackageParser.PackageParserException;
28import android.content.res.AssetManager;
29import android.content.res.Resources;
30import android.graphics.drawable.Drawable;
31import android.os.UserHandle;
Philip P. Moltmannd85d9412018-07-25 11:23:02 -070032import android.util.Log;
33import android.view.View;
34import android.widget.ImageView;
35import android.widget.TextView;
36
37import java.io.File;
38
39/**
40 * This is a utility class for defining some utility methods and constants
41 * used in the package installer application.
42 */
43public class PackageUtil {
44 private static final String LOG_TAG = PackageUtil.class.getSimpleName();
45
46 public static final String PREFIX="com.android.packageinstaller.";
47 public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
48 public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
49 public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
50 //intent attribute strings related to uninstall
51 public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
52
53 /**
54 * Utility method to get package information for a given {@link File}
55 */
56 public static PackageParser.Package getPackageInfo(Context context, File sourceFile) {
57 final PackageParser parser = new PackageParser();
58 parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager()));
59 try {
60 return parser.parsePackage(sourceFile, 0);
61 } catch (PackageParserException e) {
62 return null;
63 }
64 }
65
66 public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
67 ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
68 ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
69 return snippetView;
70 }
71
72 /**
73 * Utility method to display a snippet of an installed application.
74 * The content view should have been set on context before invoking this method.
75 * appSnippet view should include R.id.app_icon and R.id.app_name
76 * defined on it.
77 *
78 * @param pContext context of package that can load the resources
79 * @param componentInfo ComponentInfo object whose resources are to be loaded
80 * @param snippetView the snippet view
81 */
82 public static View initSnippetForInstalledApp(Context pContext,
83 ApplicationInfo appInfo, View snippetView) {
84 return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
85 }
86
87 /**
88 * Utility method to display a snippet of an installed application.
89 * The content view should have been set on context before invoking this method.
90 * appSnippet view should include R.id.app_icon and R.id.app_name
91 * defined on it.
92 *
93 * @param pContext context of package that can load the resources
94 * @param componentInfo ComponentInfo object whose resources are to be loaded
95 * @param snippetView the snippet view
96 * @param UserHandle user that the app si installed for.
97 */
98 public static View initSnippetForInstalledApp(Context pContext,
99 ApplicationInfo appInfo, View snippetView, UserHandle user) {
100 final PackageManager pm = pContext.getPackageManager();
101 Drawable icon = appInfo.loadIcon(pm);
102 if (user != null) {
103 icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
104 }
105 return initSnippet(
106 snippetView,
107 appInfo.loadLabel(pm),
108 icon);
109 }
110
Philip P. Moltmannd85d9412018-07-25 11:23:02 -0700111 static public class AppSnippet {
112 @NonNull public CharSequence label;
113 @Nullable public Drawable icon;
114 public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
115 this.label = label;
116 this.icon = icon;
117 }
118 }
119
120 /**
121 * Utility method to load application label
122 *
123 * @param pContext context of package that can load the resources
124 * @param appInfo ApplicationInfo object of package whose resources are to be loaded
125 * @param sourceFile File the package is in
126 */
127 public static AppSnippet getAppSnippet(
128 Activity pContext, ApplicationInfo appInfo, File sourceFile) {
129 final String archiveFilePath = sourceFile.getAbsolutePath();
130 Resources pRes = pContext.getResources();
131 AssetManager assmgr = new AssetManager();
132 assmgr.addAssetPath(archiveFilePath);
133 Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
134 CharSequence label = null;
135 // Try to load the label from the package's resources. If an app has not explicitly
136 // specified any label, just use the package name.
137 if (appInfo.labelRes != 0) {
138 try {
139 label = res.getText(appInfo.labelRes);
140 } catch (Resources.NotFoundException e) {
141 }
142 }
143 if (label == null) {
144 label = (appInfo.nonLocalizedLabel != null) ?
145 appInfo.nonLocalizedLabel : appInfo.packageName;
146 }
147 Drawable icon = null;
148 // Try to load the icon from the package's resources. If an app has not explicitly
149 // specified any resource, just use the default icon for now.
150 try {
151 if (appInfo.icon != 0) {
152 try {
153 icon = res.getDrawable(appInfo.icon);
154 } catch (Resources.NotFoundException e) {
155 }
156 }
157 if (icon == null) {
158 icon = pContext.getPackageManager().getDefaultActivityIcon();
159 }
160 } catch (OutOfMemoryError e) {
161 Log.i(LOG_TAG, "Could not load app icon", e);
162 }
163 return new PackageUtil.AppSnippet(label, icon);
164 }
165
166 /**
167 * Get the maximum target sdk for a UID.
168 *
169 * @param context The context to use
170 * @param uid The UID requesting the install/uninstall
171 *
172 * @return The maximum target SDK or -1 if the uid does not match any packages.
173 */
174 static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) {
175 PackageManager pm = context.getPackageManager();
176 final String[] packages = pm.getPackagesForUid(uid);
177 int targetSdkVersion = -1;
178 if (packages != null) {
179 for (String packageName : packages) {
180 try {
181 ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
182 targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion);
183 } catch (PackageManager.NameNotFoundException e) {
184 // Ignore and try the next package
185 }
186 }
187 }
188 return targetSdkVersion;
189 }
190}