1 package org.robolectric.shadows; 2 3 import static org.robolectric.util.ReflectionHelpers.ClassParameter.from; 4 5 import android.content.pm.PackageParser; 6 import android.content.pm.PackageParser.Package; 7 import android.os.Build; 8 import android.util.DisplayMetrics; 9 import java.io.File; 10 import java.util.List; 11 import org.robolectric.RuntimeEnvironment; 12 import org.robolectric.annotation.Implementation; 13 import org.robolectric.annotation.Implements; 14 import org.robolectric.annotation.RealObject; 15 import org.robolectric.res.FsFile; 16 import org.robolectric.shadows.ShadowLog.LogItem; 17 import org.robolectric.util.ReflectionHelpers; 18 19 @Implements(value = PackageParser.class, isInAndroidSdk = false) 20 public class ShadowPackageParser { 21 22 @RealObject private PackageParser realObject; 23 24 @Implementation __constructor__()25 protected void __constructor__() { 26 if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.O) { 27 realObject.setCallback(new Callback()); 28 } 29 } 30 31 /** Parses an AndroidManifest.xml file using the framework PackageParser. */ callParsePackage(FsFile apkFile)32 public static Package callParsePackage(FsFile apkFile) { 33 PackageParser packageParser = new PackageParser(); 34 35 int flags = PackageParser.PARSE_IGNORE_PROCESSES; 36 try { 37 Package thePackage; 38 if (RuntimeEnvironment.getApiLevel() >= Build.VERSION_CODES.LOLLIPOP) { 39 thePackage = packageParser.parsePackage(new File(apkFile.getPath()), flags); 40 } else { // JB -> KK 41 thePackage = ReflectionHelpers.callInstanceMethod( 42 PackageParser.class, 43 packageParser, 44 "parsePackage", 45 from(File.class, new File(apkFile.getPath())), 46 from(String.class, apkFile.getPath()), 47 from(DisplayMetrics.class, new DisplayMetrics()), 48 from(int.class, flags)); 49 } 50 51 if (thePackage == null) { 52 List<LogItem> logItems = ShadowLog.getLogsForTag("PackageParser"); 53 if (logItems.isEmpty()) { 54 throw new RuntimeException( 55 "Failed to parse package " + apkFile); 56 } else { 57 LogItem logItem = logItems.get(0); 58 throw new RuntimeException( 59 "Failed to parse package " + apkFile + ": " + logItem.msg, logItem.throwable); 60 } 61 } 62 63 return thePackage; 64 } catch (Exception e) { 65 throw new RuntimeException(e); 66 } 67 } 68 69 private static class Callback implements PackageParser.Callback { 70 71 @Override hasFeature(String feature)72 public boolean hasFeature(String feature) { 73 return false; 74 } 75 76 @Override getOverlayPaths(String targetPackageName, String targetPath)77 public String[] getOverlayPaths(String targetPackageName, String targetPath) { 78 return null; 79 } 80 81 @Override getOverlayApks(String targetPackageName)82 public String[] getOverlayApks(String targetPackageName) { 83 return null; 84 } 85 } 86 } 87