Uses ParsingPackageImpl to generate the PackageInfo for
PackageManager's getPackageArchiveInfo API.
This keeps the migration to v2 hidden and thus the API can
be shipped for this release and then deprecated entirely
if necessary.
Exempt-From-Owner-Approval: Has approval on previous patchsets,
will need non-logic updates to resolve merge conflict and CP
into rvc-dev properly
Bug: 135203078
Bug: 146575910
Bug: 153880854
Test: atest com.android.server.pm.parsing
Test: atest android.content.pm.PackageManagerTests
Merged-In: Ib21dbbdc556502144df8e3d7a26b7a9d33885cd9
Change-Id: Ib21dbbdc556502144df8e3d7a26b7a9d33885cd9
190 lines
7.3 KiB
Java
190 lines
7.3 KiB
Java
/*
|
|
**
|
|
** Copyright 2007, The Android Open Source Project
|
|
**
|
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
** you may not use this file except in compliance with the License.
|
|
** You may obtain a copy of the License at
|
|
**
|
|
** http://www.apache.org/licenses/LICENSE-2.0
|
|
**
|
|
** Unless required by applicable law or agreed to in writing, software
|
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
** See the License for the specific language governing permissions and
|
|
** limitations under the License.
|
|
*/
|
|
|
|
package com.android.packageinstaller;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.pm.ApplicationInfo;
|
|
import android.content.pm.PackageInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.res.AssetManager;
|
|
import android.content.res.Resources;
|
|
import android.graphics.drawable.Drawable;
|
|
import android.os.UserHandle;
|
|
import android.util.Log;
|
|
import android.view.View;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
|
|
import java.io.File;
|
|
|
|
/**
|
|
* This is a utility class for defining some utility methods and constants
|
|
* used in the package installer application.
|
|
*/
|
|
public class PackageUtil {
|
|
private static final String LOG_TAG = PackageUtil.class.getSimpleName();
|
|
|
|
public static final String PREFIX="com.android.packageinstaller.";
|
|
public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
|
|
public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
|
|
public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
|
|
//intent attribute strings related to uninstall
|
|
public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
|
|
|
|
/**
|
|
* Utility method to get package information for a given {@link File}
|
|
*/
|
|
@Nullable
|
|
public static PackageInfo getPackageInfo(Context context, File sourceFile, int flags) {
|
|
try {
|
|
return context.getPackageManager().getPackageArchiveInfo(sourceFile.getAbsolutePath(),
|
|
flags);
|
|
} catch (Exception ignored) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
|
|
((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
|
|
((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
|
|
return snippetView;
|
|
}
|
|
|
|
/**
|
|
* Utility method to display a snippet of an installed application.
|
|
* The content view should have been set on context before invoking this method.
|
|
* appSnippet view should include R.id.app_icon and R.id.app_name
|
|
* defined on it.
|
|
*
|
|
* @param pContext context of package that can load the resources
|
|
* @param componentInfo ComponentInfo object whose resources are to be loaded
|
|
* @param snippetView the snippet view
|
|
*/
|
|
public static View initSnippetForInstalledApp(Context pContext,
|
|
ApplicationInfo appInfo, View snippetView) {
|
|
return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
|
|
}
|
|
|
|
/**
|
|
* Utility method to display a snippet of an installed application.
|
|
* The content view should have been set on context before invoking this method.
|
|
* appSnippet view should include R.id.app_icon and R.id.app_name
|
|
* defined on it.
|
|
*
|
|
* @param pContext context of package that can load the resources
|
|
* @param componentInfo ComponentInfo object whose resources are to be loaded
|
|
* @param snippetView the snippet view
|
|
* @param UserHandle user that the app si installed for.
|
|
*/
|
|
public static View initSnippetForInstalledApp(Context pContext,
|
|
ApplicationInfo appInfo, View snippetView, UserHandle user) {
|
|
final PackageManager pm = pContext.getPackageManager();
|
|
Drawable icon = appInfo.loadIcon(pm);
|
|
if (user != null) {
|
|
icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
|
|
}
|
|
return initSnippet(
|
|
snippetView,
|
|
appInfo.loadLabel(pm),
|
|
icon);
|
|
}
|
|
|
|
static public class AppSnippet {
|
|
@NonNull public CharSequence label;
|
|
@Nullable public Drawable icon;
|
|
public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
|
|
this.label = label;
|
|
this.icon = icon;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Utility method to load application label
|
|
*
|
|
* @param pContext context of package that can load the resources
|
|
* @param appInfo ApplicationInfo object of package whose resources are to be loaded
|
|
* @param sourceFile File the package is in
|
|
*/
|
|
public static AppSnippet getAppSnippet(
|
|
Activity pContext, ApplicationInfo appInfo, File sourceFile) {
|
|
final String archiveFilePath = sourceFile.getAbsolutePath();
|
|
Resources pRes = pContext.getResources();
|
|
AssetManager assmgr = new AssetManager();
|
|
assmgr.addAssetPath(archiveFilePath);
|
|
Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
|
|
CharSequence label = null;
|
|
// Try to load the label from the package's resources. If an app has not explicitly
|
|
// specified any label, just use the package name.
|
|
if (appInfo.labelRes != 0) {
|
|
try {
|
|
label = res.getText(appInfo.labelRes);
|
|
} catch (Resources.NotFoundException e) {
|
|
}
|
|
}
|
|
if (label == null) {
|
|
label = (appInfo.nonLocalizedLabel != null) ?
|
|
appInfo.nonLocalizedLabel : appInfo.packageName;
|
|
}
|
|
Drawable icon = null;
|
|
// Try to load the icon from the package's resources. If an app has not explicitly
|
|
// specified any resource, just use the default icon for now.
|
|
try {
|
|
if (appInfo.icon != 0) {
|
|
try {
|
|
icon = res.getDrawable(appInfo.icon);
|
|
} catch (Resources.NotFoundException e) {
|
|
}
|
|
}
|
|
if (icon == null) {
|
|
icon = pContext.getPackageManager().getDefaultActivityIcon();
|
|
}
|
|
} catch (OutOfMemoryError e) {
|
|
Log.i(LOG_TAG, "Could not load app icon", e);
|
|
}
|
|
return new PackageUtil.AppSnippet(label, icon);
|
|
}
|
|
|
|
/**
|
|
* Get the maximum target sdk for a UID.
|
|
*
|
|
* @param context The context to use
|
|
* @param uid The UID requesting the install/uninstall
|
|
*
|
|
* @return The maximum target SDK or -1 if the uid does not match any packages.
|
|
*/
|
|
static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) {
|
|
PackageManager pm = context.getPackageManager();
|
|
final String[] packages = pm.getPackagesForUid(uid);
|
|
int targetSdkVersion = -1;
|
|
if (packages != null) {
|
|
for (String packageName : packages) {
|
|
try {
|
|
ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
|
|
targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion);
|
|
} catch (PackageManager.NameNotFoundException e) {
|
|
// Ignore and try the next package
|
|
}
|
|
}
|
|
}
|
|
return targetSdkVersion;
|
|
}
|
|
}
|