1a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwinpackage com.xtremelabs.robolectric; 2a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 3fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport android.app.Application; 4fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport com.xtremelabs.robolectric.internal.ClassNameResolver; 5fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport org.w3c.dom.Document; 6fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport org.w3c.dom.Node; 7fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport org.w3c.dom.NodeList; 8a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 9fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport javax.xml.parsers.DocumentBuilder; 10fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport javax.xml.parsers.DocumentBuilderFactory; 11a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwinimport java.io.File; 12a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwinimport java.io.FileNotFoundException; 1372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richardimport java.util.ArrayList; 1472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richardimport java.util.List; 15a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 16fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawalaimport static android.content.pm.ApplicationInfo.*; 1708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 18a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwinpublic class RobolectricConfig { 1964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final File androidManifestFile; 2064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final File resourceDirectory; 2164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final File assetsDirectory; 22147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin private String rClassName; 23147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin private String packageName; 2408f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz private String processName; 25147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin private String applicationName; 26147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin private boolean manifestIsParsed = false; 273fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin private int sdkVersion; 2808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz private int minSdkVersion; 2964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private boolean sdkVersionSpecified = true; 3064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private boolean minSdkVersionSpecified = true; 3108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz private int applicationFlags; 3264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final List<ReceiverAndIntentFilter> receivers = new ArrayList<ReceiverAndIntentFilter>(); 3322e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi private boolean strictI18n = false; 34dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao private String locale = ""; 35dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao private String oldLocale = ""; 3672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 3772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard /** 38a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * Creates a Robolectric configuration using default Android files relative to the specified base directory. 3940c6251719cccc0a84ae99c976d2836b14374ce6Christian Williams * <p/> 40a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * The manifest will be baseDir/AndroidManifest.xml, res will be baseDir/res, and assets in baseDir/assets. 41a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * 42a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * @param baseDir the base directory of your Android project 43a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin */ 4464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public RobolectricConfig(final File baseDir) { 45a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin this(new File(baseDir, "AndroidManifest.xml"), new File(baseDir, "res"), new File(baseDir, "assets")); 46a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 47a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 4864a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public RobolectricConfig(final File androidManifestFile, final File resourceDirectory) { 49a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin this(androidManifestFile, resourceDirectory, new File(resourceDirectory.getParent(), "assets")); 50a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 51a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 52a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin /** 53a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * Creates a Robolectric configuration using specified locations. 54a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * 55a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * @param androidManifestFile location of the AndroidManifest.xml file 56a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * @param resourceDirectory location of the res directory 57a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin * @param assetsDirectory location of the assets directory 58a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin */ 5964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public RobolectricConfig(final File androidManifestFile, final File resourceDirectory, final File assetsDirectory) { 60a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin this.androidManifestFile = androidManifestFile; 61a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin this.resourceDirectory = resourceDirectory; 62a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin this.assetsDirectory = assetsDirectory; 63a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 64a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 65147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin public String getRClassName() throws Exception { 66147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin parseAndroidManifest(); 67147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin return rClassName; 686bdf10c660dd53023a3f889ca8d7b6da049e720dChristian Williams & Phil Goodwin } 696bdf10c660dd53023a3f889ca8d7b6da049e720dChristian Williams & Phil Goodwin 706bdf10c660dd53023a3f889ca8d7b6da049e720dChristian Williams & Phil Goodwin public void validate() throws FileNotFoundException { 71147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin if (!androidManifestFile.exists() || !androidManifestFile.isFile()) { 72147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin throw new FileNotFoundException(androidManifestFile.getAbsolutePath() + " not found or not a file; it should point to your project's AndroidManifest.xml"); 73a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 74a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 75a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin if (!getResourceDirectory().exists() || !getResourceDirectory().isDirectory()) { 76a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin throw new FileNotFoundException(getResourceDirectory().getAbsolutePath() + " not found or not a directory; it should point to your project's res directory"); 77a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 78a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 79a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 80147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin private void parseAndroidManifest() { 81147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin if (manifestIsParsed) { 82147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin return; 83147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 84a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 85147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin try { 86147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin DocumentBuilder db = dbf.newDocumentBuilder(); 873fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin Document manifestDocument = db.parse(androidManifestFile); 88147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin 89147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin packageName = getTagAttributeText(manifestDocument, "manifest", "package"); 90147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin rClassName = packageName + ".R"; 91147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin applicationName = getTagAttributeText(manifestDocument, "application", "android:name"); 9264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas Integer minSdkVer = getTagAttributeIntValue(manifestDocument, "uses-sdk", "android:minSdkVersion"); 9364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas Integer sdkVer = getTagAttributeIntValue(manifestDocument, "uses-sdk", "android:targetSdkVersion"); 9464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (minSdkVer == null) { 9564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas minSdkVersion = 10; 9664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas minSdkVersionSpecified = false; 9764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } else { 9864a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas minSdkVersion = minSdkVer; 9964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 10064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (sdkVer == null) { 10164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas sdkVersion = 10; 10264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas sdkVersionSpecified = false; 10364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } else { 10464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas sdkVersion = sdkVer; 10564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 10608f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 10708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz processName = getTagAttributeText(manifestDocument, "application", "android:process"); 10808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz if (processName == null) { 10908f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz processName = packageName; 11008f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 11108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 11208f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz parseApplicationFlags(manifestDocument); 113fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawala parseReceivers(manifestDocument, packageName); 114147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } catch (Exception ignored) { 115147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 116147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin manifestIsParsed = true; 117147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 118a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 119fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawala private void parseReceivers(final Document manifestDocument, String packageName) { 12072ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard Node application = manifestDocument.getElementsByTagName("application").item(0); 12172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard if (application == null) { 12272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return; 12372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 12472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard for (Node receiverNode : getChildrenTags(application, "receiver")) { 12572ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard Node namedItem = receiverNode.getAttributes().getNamedItem("android:name"); 12672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard if (namedItem == null) { 12772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard continue; 12872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 12972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard String receiverName = namedItem.getTextContent(); 130fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawala if (receiverName.startsWith(".")) { 131fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawala receiverName = packageName + receiverName; 132fe7bed4efc83bcbdc6048405f3b579175e5277b8Lenny Turetsky & Rick Kawala } 13372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard for (Node intentFilterNode : getChildrenTags(receiverNode, "intent-filter")) { 13472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard List<String> actions = new ArrayList<String>(); 13572ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard for (Node actionNode : getChildrenTags(intentFilterNode, "action")) { 13672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard Node nameNode = actionNode.getAttributes().getNamedItem("android:name"); 13772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard if (nameNode != null) { 13872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard actions.add(nameNode.getTextContent()); 13972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 14072ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 14172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard receivers.add(new ReceiverAndIntentFilter(receiverName, actions)); 14272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 14372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 14472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 14572ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 14664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private List<Node> getChildrenTags(final Node node, final String tagName) { 14772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard List<Node> children = new ArrayList<Node>(); 14872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard for (int i = 0; i < node.getChildNodes().getLength(); i++) { 14972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard Node childNode = node.getChildNodes().item(i); 15072ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard if (childNode.getNodeName().equalsIgnoreCase(tagName)) { 15172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard children.add(childNode); 15272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 15372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 15472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return children; 15572ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 15672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 15764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private void parseApplicationFlags(final Document manifestDocument) { 15808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags = getApplicationFlag(manifestDocument, "android:allowBackup", FLAG_ALLOW_BACKUP); 15908f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:allowClearUserData", FLAG_ALLOW_CLEAR_USER_DATA); 16008f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:allowTaskReparenting", FLAG_ALLOW_TASK_REPARENTING); 16108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:debuggable", FLAG_DEBUGGABLE); 16208f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:hasCode", FLAG_HAS_CODE); 16308f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:killAfterRestore", FLAG_KILL_AFTER_RESTORE); 16408f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:persistent", FLAG_PERSISTENT); 16508f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:resizeable", FLAG_RESIZEABLE_FOR_SCREENS); 16608f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:restoreAnyVersion", FLAG_RESTORE_ANY_VERSION); 16708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:largeScreens", FLAG_SUPPORTS_LARGE_SCREENS); 16808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:normalScreens", FLAG_SUPPORTS_NORMAL_SCREENS); 16908f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:anyDensity", FLAG_SUPPORTS_SCREEN_DENSITIES); 17008f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:smallScreens", FLAG_SUPPORTS_SMALL_SCREENS); 17108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:testOnly", FLAG_TEST_ONLY); 17208f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz applicationFlags += getApplicationFlag(manifestDocument, "android:vmSafeMode", FLAG_VM_SAFE_MODE); 17308f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 17408f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 17564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private int getApplicationFlag(final Document doc, final String attribute, final int attributeValue) { 17608f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz String flagString = getTagAttributeText(doc, "application", attribute); 17708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz return "true".equalsIgnoreCase(flagString) ? attributeValue : 0; 17808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 17908f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 18064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private Integer getTagAttributeIntValue(final Document doc, final String tag, final String attribute) { 18164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return getTagAttributeIntValue(doc, tag, attribute, null); 18264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 18364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas 18464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private Integer getTagAttributeIntValue(final Document doc, final String tag, final String attribute, final Integer defaultValue) { 18508f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz String valueString = getTagAttributeText(doc, tag, attribute); 18608f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz if (valueString != null) { 18708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz return Integer.parseInt(valueString); 1883fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin } 1893fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin return defaultValue; 1903fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin } 1913fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin 192147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin public String getApplicationName() { 193147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin parseAndroidManifest(); 194147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin return applicationName; 195a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 196a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 197147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin public String getPackageName() { 198147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin parseAndroidManifest(); 199147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin return packageName; 200a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 20108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 20208f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz public int getMinSdkVersion() { 20308f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz parseAndroidManifest(); 20408f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz return minSdkVersion; 20508f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 206a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 2073fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin public int getSdkVersion() { 2083fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin parseAndroidManifest(); 2093fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin return sdkVersion; 2103fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin } 2113fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin 21208f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz public int getApplicationFlags() { 21308f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz parseAndroidManifest(); 21408f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz return applicationFlags; 21508f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 21608f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 21708f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz public String getProcessName() { 21808f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz parseAndroidManifest(); 21908f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz return processName; 22008f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz } 22108f79939304d82b7cfbb80d20b88fbe26eeab7a9Joe Moore and Tyler Schultz 222a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin public File getResourceDirectory() { 223a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return resourceDirectory; 224a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 225a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 226a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin public File getAssetsDirectory() { 227a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return assetsDirectory; 228a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 229a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 23072ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard public int getReceiverCount() { 23172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard parseAndroidManifest(); 23272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return receivers.size(); 23372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 23472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 23564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public String getReceiverClassName(final int receiverIndex) { 23672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard parseAndroidManifest(); 23772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return receivers.get(receiverIndex).getBroadcastReceiverClassName(); 23872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 23972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 24064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public List<String> getReceiverIntentFilterActions(final int receiverIndex) { 24172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard parseAndroidManifest(); 24272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return receivers.get(receiverIndex).getIntentFilterActions(); 24372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 24472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 24522e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi public boolean getStrictI18n() { 24622e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi return strictI18n; 24722e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi } 24822e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi 24922e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi public void setStrictI18n(boolean strict) { 25022e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi strictI18n = strict; 25122e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi } 25222e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi 253dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao public void setLocale( String locale ){ 254dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao this.oldLocale = this.locale; 255dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao this.locale = locale; 256dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 257dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao 258dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao public String getLocale() { 259dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao return this.locale; 260dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 261dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao 262ccc48a273af15b7513d5f5fc28110a0eebb82454Michael Portuesi public boolean isLocaleChanged() { 263dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao return !locale.equals( oldLocale ); 264dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao } 265dd40f718cf785a56e63c0685feeb73d266c13e3fWenhui Yao 26664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private static String getTagAttributeText(final Document doc, final String tag, final String attribute) { 267147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin NodeList elementsByTagName = doc.getElementsByTagName(tag); 2683fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin for (int i = 0; i < elementsByTagName.getLength(); ++i) { 2693fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin Node item = elementsByTagName.item(i); 2703fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin Node namedItem = item.getAttributes().getNamedItem(attribute); 2713fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin if (namedItem != null) { 2723fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin return namedItem.getTextContent(); 2733fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin } 2743fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin } 2753fab0d6b94c13c0ab7fc14b1d7f19dbe10991acbPhil Goodwin return null; 276147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 27722e617961e21946fd47d3b96cc670181ccd3a2bdMichael Portuesi 27864a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private static Application newApplicationInstance(final String packageName, final String applicationName) { 279147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin Application application; 280147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin try { 281147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin Class<? extends Application> applicationClass = 282147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin new ClassNameResolver<Application>(packageName, applicationName).resolve(); 283147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin application = applicationClass.newInstance(); 284147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } catch (Exception e) { 285147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin throw new RuntimeException(e); 286147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 287147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin return application; 288147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin } 289147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin 290a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin @Override 29164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public boolean equals(final Object o) { 29264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (this == o) { 29364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return true; 29464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 29564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (o == null || getClass() != o.getClass()) { 29664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return false; 29764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 298a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 299a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin RobolectricConfig that = (RobolectricConfig) o; 300a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 30164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (androidManifestFile != null ? !androidManifestFile.equals(that.androidManifestFile) : that.androidManifestFile != null) { 302a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return false; 30364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 30464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (getAssetsDirectory() != null ? !getAssetsDirectory().equals(that.getAssetsDirectory()) : that.getAssetsDirectory() != null) { 305a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return false; 30664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 30764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (getResourceDirectory() != null ? !getResourceDirectory().equals(that.getResourceDirectory()) : that.getResourceDirectory() != null) { 308a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return false; 30964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 310a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 311a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return true; 312a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 313a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin 314a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin @Override 315a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin public int hashCode() { 316147cdda64f4a372a27599ae1f902bd7be90bee5cPhil Goodwin int result = androidManifestFile != null ? androidManifestFile.hashCode() : 0; 317a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin result = 31 * result + (getResourceDirectory() != null ? getResourceDirectory().hashCode() : 0); 318a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin result = 31 * result + (getAssetsDirectory() != null ? getAssetsDirectory().hashCode() : 0); 319a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin return result; 320a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin } 32164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas 32264a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public int getRealSdkVersion() { 32364a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas parseAndroidManifest(); 32464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (sdkVersionSpecified) { 32564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return sdkVersion; 32664a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 32764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas if (minSdkVersionSpecified) { 32864a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return minSdkVersion; 32964a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 33064a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas return sdkVersion; 33164a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas } 33272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 33372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard private static class ReceiverAndIntentFilter { 33464a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final List<String> intentFilterActions; 33564a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas private final String broadcastReceiverClassName; 33672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 33764a6b8b69ff3076e1994899fa2de780d80bd57fcMartin Gontovnikas public ReceiverAndIntentFilter(final String broadcastReceiverClassName, final List<String> intentFilterActions) { 33872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard this.broadcastReceiverClassName = broadcastReceiverClassName; 33972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard this.intentFilterActions = intentFilterActions; 34072ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 34172ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 34272ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard public String getBroadcastReceiverClassName() { 34372ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return broadcastReceiverClassName; 34472ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 34572ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard 34672ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard public List<String> getIntentFilterActions() { 34772ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard return intentFilterActions; 34872ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 34972ca49dced475c55926dbad730c306184bb6a68eDavid Farber & Ryan Richard } 350a6ff2c2b15018092af3a28697b521d1ca5e789f0Christian Williams & Phil Goodwin} 351