package cm.android.common.pm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.content.Context;
import android.content.pm.IPackageDeleteObserver;
import android.net.Uri;
import android.os.RemoteException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cm.java.util.ReflectUtil;
import cm.java.util.Singleton;
/**
* The type Zte package manager.
*/
public class PackageManager {
private static Logger logger = LoggerFactory.getLogger("pm");
private static final String IPACKAGE_INSTALL_OBSERVER = "android.content.pm.IPackageInstallObserver";
private static final String IPACKAGE_DELETE_OBSERVER = "android.content.pm.IPackageDeleteObserver";
/**
* Flag parameter for {@link #android.content.pm.PackageManager.installPackage} to indicate
* that
* you want to replace an already
* installed package, if one exists.
*/
public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
public static final int INSTALL_SUCCEEDED = 1;
public static final int INSTALL_FAILED_INVALID_APK = -2;
public static final int INSTALL_FAILED_INVALID_URI = -3;
public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
public static final int INSTALL_FAILED_DEXOPT = -11;
public static final int INSTALL_FAILED_OLDER_SDK = -12;
public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
public static final int INSTALL_FAILED_NEWER_SDK = -14;
public static final int INSTALL_FAILED_TEST_ONLY = -15;
public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
public static final int INSTALL_FAILED_MISSING_FEATURE = -17;
// ------ Errors related to sdcard
public static final int INSTALL_FAILED_CONTAINER_ERROR = -18;
public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21;
public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22;
public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23;
public static final int INSTALL_FAILED_UID_CHANGED = -24;
public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25;
public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26;
public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
public static final int INSTALL_FAILED_USER_RESTRICTED = -111;
public static final int INSTALL_FAILED_DUPLICATE_PERMISSION = -112;
public static final int INSTALL_FAILED_NO_MATCHING_ABIS = -113;
public static final int NO_NATIVE_LIBRARIES = -114;
public static final int INSTALL_FAILED_ABORTED = -115;
public static final int DELETE_SUCCEEDED = 1;
public static final int DELETE_FAILED_INTERNAL_ERROR = -1;
public static final int DELETE_FAILED_DEVICE_POLICY_MANAGER = -2;
public static final int DELETE_FAILED_USER_RESTRICTED = -3;
public static final int DELETE_FAILED_OWNER_BLOCKED = -4;
public static final int DELETE_FAILED_ABORTED = -5;
private static volatile PackageManager INSTANCE;
private static final Singleton<PackageManager> singleton = new Singleton<PackageManager>() {
@Override
protected PackageManager create() {
return new PackageManager();
}
};
public static PackageManager getInstance() {
return singleton.get();
}
private PackageManager() {
}
/**
* Install.
*
* @param uri the uri
* @param observer the observer
*/
public void installPackage(Context context, Uri uri, final PackageInstallObserver observer, int flags) {
Class clazz = null;
try {
clazz = Class.forName(IPACKAGE_INSTALL_OBSERVER);
} catch (ClassNotFoundException e) {
logger.error("error = {}", e.getMessage());
return;
}
Method installPackage = ReflectUtil.getMethod(context.getPackageManager().getClass(), "installPackage", new Class[]{Uri.class, clazz, int.class, String.class});
Object observerProxy = Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
logger.info("method = {}", method);
if ("installPackage".equals(method.getName())) {
logger.info("installPackage method = {}, packageName = {}, returnCode = {}", method.getName(), args[0], args[1]);
if (null != observer) {
observer.onPackageInstalled(String.valueOf(args[0]), (int) args[1]);
}
}
return null;
}
});
ReflectUtil.doMethod(context.getPackageManager(), installPackage, new Object[]{uri, observerProxy, flags, context.getPackageName()});
}
/**
* Uninstall.
*
* @param packageName the package name
* @param observer the observer
*/
public void deletePackage(Context context, String packageName, final PackageDeleteObserver observer, int flags) {
Class clazz = null;
try {
clazz = Class.forName(IPACKAGE_DELETE_OBSERVER);
} catch (ClassNotFoundException e) {
logger.error("error = {}", e.getMessage());
return;
}
Method deletePackage = ReflectUtil.getMethod(context.getPackageManager().getClass(), "deletePackage", new Class[]{String.class, clazz, int.class});
Object observerProxy = Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
logger.info("method = {}", method);
if ("asBinder".equals(method.getName())) {
return new IPackageDeleteObserver.Stub() {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
logger.info("packageDeleted pacakageName = {}, returnCode = {}", packageName, returnCode);
if (null != observer) {
observer.onPackageDeleted(packageName, returnCode);
}
}
};
}
return null;
}
});
ReflectUtil.doMethod(context.getPackageManager(), deletePackage, new Object[]{packageName, observerProxy, flags});
}
/**
* The interface Package install observer.
*/
public interface PackageInstallObserver {
/**
* On package installed.
*
* @param packageName the package name
* @param returnCode the return code
*/
void onPackageInstalled(String packageName, int returnCode);
}
/**
* The interface Package delete observer.
*/
public interface PackageDeleteObserver {
/**
* On package deleted.
*
* @param packageName the package name
* @param returnCode the return code
*/
void onPackageDeleted(String packageName, int returnCode);
}
}