191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project/*
291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Copyright 2007, The Android Open Source Project
491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** you may not use this file except in compliance with the License.
791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** You may obtain a copy of the License at
891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project**
1191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** See the License for the specific language governing permissions and
1591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project** limitations under the License.
1691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project*/
1779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
1891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectpackage com.android.packageinstaller;
1991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
2091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.app.Activity;
21abf56631187491de2e5b558910f0a20d8fc0ee78Tony Mantlerimport android.content.Context;
2291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.ApplicationInfo;
2391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageManager;
2491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.content.pm.PackageParser;
253c2848cebf9d67e4cdf7bb0101e4a3f7553cc124Jeff Sharkeyimport android.content.pm.PackageParser.PackageParserException;
26ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapuimport android.content.res.AssetManager;
27ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapuimport android.content.res.Resources;
2891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.graphics.drawable.Drawable;
293da1b8718d919b389e5fa03c0ee4dfb388593806Tony Mantlerimport android.os.UserHandle;
3074fa089b8c39d84b737607a3e3d2cde4d3b42d24Philip P. Moltmannimport android.support.annotation.NonNull;
3174fa089b8c39d84b737607a3e3d2cde4d3b42d24Philip P. Moltmannimport android.support.annotation.Nullable;
32a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmannimport android.util.Log;
3391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.view.View;
3491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.widget.ImageView;
3591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectimport android.widget.TextView;
3691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project
37362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroyimport java.io.File;
38362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy
3991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project/**
4091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * This is a utility class for defining some utility methods and constants
4191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project * used in the package installer application.
4291ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project */
4391ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Projectpublic class PackageUtil {
44a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann    private static final String LOG_TAG = PackageUtil.class.getSimpleName();
45a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann
4691ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String PREFIX="com.android.packageinstaller.";
4791ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
4891ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
4991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
5091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    //intent attribute strings related to uninstall
5191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
5279da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
5379da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
5479da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey     * Utility method to get package information for a given {@link File}
5591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
56d744ee4cb512d8acd51fdca8ba9b2fb7e99e70f7Dianne Hackborn    public static PackageParser.Package getPackageInfo(Context context, File sourceFile) {
57e35948b4bc015c063d4437c35cef2949e4cb75f8Jeff Sharkey        final PackageParser parser = new PackageParser();
58d744ee4cb512d8acd51fdca8ba9b2fb7e99e70f7Dianne Hackborn        parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager()));
593c2848cebf9d67e4cdf7bb0101e4a3f7553cc124Jeff Sharkey        try {
60f9bf4f795615bac03d1b35a0138318473b1ef6bfSvet Ganov            return parser.parsePackage(sourceFile, 0);
613c2848cebf9d67e4cdf7bb0101e4a3f7553cc124Jeff Sharkey        } catch (PackageParserException e) {
62813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich            return null;
63813a4bd48de33efe5c882ad3b9258e88d6d10fd7Nick Kralevich        }
6491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
65ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu
66362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy    public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
67362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
68362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
69362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        return snippetView;
70362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy    }
71362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy
7279da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
73362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * Utility method to display a snippet of an installed application.
74ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * The content view should have been set on context before invoking this method.
75ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * appSnippet view should include R.id.app_icon and R.id.app_name
76ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * defined on it.
77ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     *
78ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param pContext context of package that can load the resources
79362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * @param componentInfo ComponentInfo object whose resources are to be loaded
80362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy     * @param snippetView the snippet view
8191ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
82abf56631187491de2e5b558910f0a20d8fc0ee78Tony Mantler    public static View initSnippetForInstalledApp(Context pContext,
83362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy            ApplicationInfo appInfo, View snippetView) {
84596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy        return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
85596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy    }
86596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy
87596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy    /**
88596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * Utility method to display a snippet of an installed application.
89596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * The content view should have been set on context before invoking this method.
90596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * appSnippet view should include R.id.app_icon and R.id.app_name
91596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * defined on it.
92596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     *
93596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * @param pContext context of package that can load the resources
94596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * @param componentInfo ComponentInfo object whose resources are to be loaded
95596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * @param snippetView the snippet view
96596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     * @param UserHandle user that the app si installed for.
97596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy     */
98abf56631187491de2e5b558910f0a20d8fc0ee78Tony Mantler    public static View initSnippetForInstalledApp(Context pContext,
99596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy            ApplicationInfo appInfo, View snippetView, UserHandle user) {
100362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        final PackageManager pm = pContext.getPackageManager();
101596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy        Drawable icon = appInfo.loadIcon(pm);
102596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy        if (user != null) {
103dee544d68c92a3e1f66a981b8e232941c9b582a4Amith Yamasani            icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
104596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy        }
105362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy        return initSnippet(
106362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy                snippetView,
107362660b35aec989137b205ce8cb8eb945c19c1a3Patrick Dubroy                appInfo.loadLabel(pm),
108596ce64f71011e7600ee2be66d977dafb86b9da3Kenny Guy                icon);
10991ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
110ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu
11179da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
112ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * Utility method to display application snippet of a new package.
113ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * The content view should have been set on context before invoking this method.
114ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * appSnippet view should include R.id.app_icon and R.id.app_name
115ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * defined on it.
116ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     *
117ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param pContext context of package that can load the resources
118a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann     * @param as The resources to be loaded
119ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu     * @param snippetId view id of app snippet view
12091ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project     */
121a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann    @NonNull public static View initSnippetForNewApp(@NonNull Activity pContext,
122a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            @NonNull AppSnippet as, int snippetId) {
123ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        View appSnippet = pContext.findViewById(snippetId);
124a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        if (as.icon != null) {
125a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            ((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon);
126a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        }
1279ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        ((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label);
1289ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        return appSnippet;
1299ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    }
1309ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu
1319ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    static public class AppSnippet {
132a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        @NonNull public CharSequence label;
133a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        @Nullable public Drawable icon;
134a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
1359ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            this.label = label;
1369ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu            this.icon = icon;
1379ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        }
1389ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu    }
13979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey
14079da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    /**
1419ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * Utility method to load application label
1429ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     *
1439ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * @param pContext context of package that can load the resources
1449ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     * @param appInfo ApplicationInfo object of package whose resources are to be loaded
145a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann     * @param sourceFile File the package is in
1469ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu     */
14779da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey    public static AppSnippet getAppSnippet(
14879da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey            Activity pContext, ApplicationInfo appInfo, File sourceFile) {
14979da2eaa800f889be5e5f5bd91121c2ecb55ce14Jeff Sharkey        final String archiveFilePath = sourceFile.getAbsolutePath();
150ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        Resources pRes = pContext.getResources();
151ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        AssetManager assmgr = new AssetManager();
152ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        assmgr.addAssetPath(archiveFilePath);
153ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
154ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        CharSequence label = null;
155ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // Try to load the label from the package's resources. If an app has not explicitly
156ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // specified any label, just use the package name.
157f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        if (appInfo.labelRes != 0) {
158f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            try {
159f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu                label = res.getText(appInfo.labelRes);
160f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            } catch (Resources.NotFoundException e) {
161f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            }
162f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu        }
163ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu        if (label == null) {
164ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu            label = (appInfo.nonLocalizedLabel != null) ?
165ccb4dda8b1525c90323fa9dd7b96b9eeb78b7082Suchi Amalapurapu                    appInfo.nonLocalizedLabel : appInfo.packageName;
166ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        }
167ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        Drawable icon = null;
168ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // Try to load the icon from the package's resources. If an app has not explicitly
169ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        // specified any resource, just use the default icon for now.
170a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        try {
171a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            if (appInfo.icon != 0) {
172a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann                try {
173a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann                    icon = res.getDrawable(appInfo.icon);
174a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann                } catch (Resources.NotFoundException e) {
175a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann                }
176f075068817434dbb5e861d00f5ed23d6405ab4d9Suchi Amalapurapu            }
177a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            if (icon == null) {
178a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann                icon = pContext.getPackageManager().getDefaultActivityIcon();
179a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            }
180a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann        } catch (OutOfMemoryError e) {
181a2780da1ecd4473fe59775d867653a61cc3d61efPhilip P. Moltmann            Log.i(LOG_TAG, "Could not load app icon", e);
182ff8693ab50a9ed78ee816361c628969752127e9dSuchi Amalapurapu        }
1839ab50f3655afed4f9266402a03d3235d94220397Suchi Amalapurapu        return new PackageUtil.AppSnippet(label, icon);
18491ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project    }
18591ec61c3dca241befdf4a3803c45b051a3e3124fThe Android Open Source Project}
186