package me.ele.amigo.utils;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import me.ele.amigo.reflect.FieldUtils;
public class CommonUtils {
public static int getVersionCode(Context context) {
PackageManager pm = context.getPackageManager();
try {
return pm.getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
return 0;
}
}
public static String getVersionName(Context context) {
PackageManager pm = context.getPackageManager();
try {
return pm.getPackageInfo(context.getPackageName(), 0).versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
return "";
}
}
public static PackageInfo getPackageInfo(Context context, File patchApk, int flags) {
PackageManager pm = context.getPackageManager();
return pm.getPackageArchiveInfo(patchApk.getAbsolutePath(), flags);
}
public static Signature getSignature(Context context) throws NameNotFoundException {
return context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];
}
public static Signature getSignature(Context context, File patchApk) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return context.getPackageManager().getPackageArchiveInfo(patchApk.getAbsolutePath(),
PackageManager.GET_SIGNATURES).signatures[0];
} else {
return getPackageArchiveInfo(patchApk.getAbsolutePath(),
PackageManager.GET_SIGNATURES).signatures[0];
}
}
public static ApplicationInfo getApplicationInfo(Context context) throws NameNotFoundException {
PackageManager pm;
String packageName;
try {
pm = context.getPackageManager();
packageName = context.getPackageName();
} catch (RuntimeException e) {
/* Ignore those exceptions so that we don't break tests replying on Context like
* a android.text.MockContext or a android.content.ContextWrapper with a null
* base Context.
*/
return null;
}
if (pm == null || packageName == null) {
// This is most likely a mock context, so just return without patching.
return null;
}
return pm.getApplicationInfo(packageName, 0);
}
public static PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
// Workaround for https://code.google.com/p/android/issues/detail?id=9151#c8
try {
Class packageParserClass = Class.forName("android.content.pm.PackageParser");
Class packageParserPackageClass = Class.forName("android.content.pm" +
".PackageParser$Package");
Constructor packageParserConstructor = packageParserClass.getConstructor(String.class);
Method parsePackageMethod = packageParserClass.getDeclaredMethod(
"parsePackage", File.class, String.class, DisplayMetrics.class, int.class);
Method collectCertificatesMethod = packageParserClass.getDeclaredMethod(
"collectCertificates", packageParserPackageClass, int.class);
Method generatePackageInfoMethod;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
generatePackageInfoMethod = packageParserClass.getDeclaredMethod(
"generatePackageInfo", packageParserPackageClass, int[].class, int.class,
long.class, long.class);
} else {
generatePackageInfoMethod = packageParserClass.getDeclaredMethod(
"generatePackageInfo", packageParserPackageClass, int[].class, int.class);
}
packageParserConstructor.setAccessible(true);
parsePackageMethod.setAccessible(true);
collectCertificatesMethod.setAccessible(true);
generatePackageInfoMethod.setAccessible(true);
Object packageParser = packageParserConstructor.newInstance(archiveFilePath);
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
final File sourceFile = new File(archiveFilePath);
Object pkg = parsePackageMethod.invoke(
packageParser,
sourceFile,
archiveFilePath,
metrics,
0);
if (pkg == null) {
return null;
}
if ((flags & android.content.pm.PackageManager.GET_SIGNATURES) != 0) {
collectCertificatesMethod.invoke(packageParser, pkg, 0);
}
PackageInfo packageInfo;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
packageInfo = (PackageInfo) generatePackageInfoMethod.invoke(null, pkg, null,
flags, 0, 0);
} else {
packageInfo = (PackageInfo) generatePackageInfoMethod.invoke(null, pkg, null,
flags);
}
if ((flags & PackageManager.GET_META_DATA) != 0) {
try {
Bundle mAppMetaData = (Bundle) FieldUtils.readField(pkg, "mAppMetaData", true);
packageInfo.applicationInfo.metaData = mAppMetaData;
} catch (Exception e) {
e.printStackTrace();
}
}
return packageInfo;
} catch (Exception e) {
e.printStackTrace();
Log.e("Signature Monitor", "android.content.pm.PackageParser reflection failed: " + e
.toString());
}
return null;
}
}