1 #! /usr/bin/env python 2 # Copyright 2017 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import unittest 7 8 from devil import base_error 9 from devil import devil_env 10 from devil.android import apk_helper 11 from devil.utils import mock_calls 12 13 with devil_env.SysPath(devil_env.PYMOCK_PATH): 14 import mock # pylint: disable=import-error 15 16 17 _MANIFEST_DUMP = """N: android=http://schemas.android.com/apk/res/android 18 E: manifest (line=1) 19 A: package="org.chromium.abc" (Raw: "org.chromium.abc") 20 A: split="random_split" (Raw: "random_split") 21 E: uses-permission (line=2) 22 A: android:name(0x01010003)="android.permission.INTERNET" (Raw: "android.permission.INTERNET") 23 E: uses-permission (line=3) 24 A: android:name(0x01010003)="android.permission.READ_EXTERNAL_STORAGE" (Raw: "android.permission.READ_EXTERNAL_STORAGE") 25 E: uses-permission (line=4) 26 A: android:name(0x01010003)="android.permission.ACCESS_FINE_LOCATION" (Raw: "android.permission.ACCESS_FINE_LOCATION") 27 E: application (line=5) 28 E: activity (line=6) 29 A: android:name(0x01010003)="org.chromium.ActivityName" (Raw: "org.chromium.ActivityName") 30 A: android:exported(0x01010010)=(type 0x12)0xffffffff 31 E: service (line=7) 32 A: android:name(0x01010001)="org.chromium.RandomService" (Raw: "org.chromium.RandomService") 33 A: android:isolatedProcess(0x01010888)=(type 0x12)0xffffffff 34 E: activity (line=173) 35 A: android:name(0x01010003)=".MainActivity" (Raw: ".MainActivity") 36 E: intent-filter (line=177) 37 E: action (line=178) 38 A: android:name(0x01010003)="android.intent.action.MAIN" (Raw: "android.intent.action.MAIN") 39 E: category (line=180) 40 A: android:name(0x01010003)="android.intent.category.DEFAULT" (Raw: "android.intent.category.DEFAULT") 41 E: category (line=181) 42 A: android:name(0x01010003)="android.intent.category.LAUNCHER" (Raw: "android.intent.category.LAUNCHER") 43 E: activity-alias (line=173) 44 A: android:name(0x01010003)="org.chromium.ViewActivity" (Raw: "org.chromium.ViewActivity") 45 A: android:targetActivity(0x01010202)="org.chromium.ActivityName" (Raw: "org.chromium.ActivityName") 46 E: intent-filter (line=191) 47 E: action (line=192) 48 A: android:name(0x01010003)="android.intent.action.VIEW" (Raw: "android.intent.action.VIEW") 49 E: data (line=198) 50 A: android:scheme(0x01010027)="http" (Raw: "http") 51 E: data (line=199) 52 A: android:scheme(0x01010027)="https" (Raw: "https") 53 E: meta-data (line=43) 54 A: android:name(0x01010003)="name1" (Raw: "name1") 55 A: android:value(0x01010024)="value1" (Raw: "value1") 56 E: meta-data (line=43) 57 A: android:name(0x01010003)="name2" (Raw: "name2") 58 A: android:value(0x01010024)="value2" (Raw: "value2") 59 E: instrumentation (line=8) 60 A: android:label(0x01010001)="abc" (Raw: "abc") 61 A: android:name(0x01010003)="org.chromium.RandomJUnit4TestRunner" (Raw: "org.chromium.RandomJUnit4TestRunner") 62 A: android:targetPackage(0x01010021)="org.chromium.random_package" (Raw:"org.chromium.random_pacakge") 63 A: junit4=(type 0x12)0xffffffff (Raw: "true") 64 E: instrumentation (line=9) 65 A: android:label(0x01010001)="abc" (Raw: "abc") 66 A: android:name(0x01010003)="org.chromium.RandomTestRunner" (Raw: "org.chromium.RandomTestRunner") 67 A: android:targetPackage(0x01010021)="org.chromium.random_package" (Raw:"org.chromium.random_pacakge") 68 """ 69 70 _NO_ISOLATED_SERVICES = """N: android=http://schemas.android.com/apk/res/android 71 E: manifest (line=1) 72 A: package="org.chromium.abc" (Raw: "org.chromium.abc") 73 E: application (line=5) 74 E: activity (line=6) 75 A: android:name(0x01010003)="org.chromium.ActivityName" (Raw: "org.chromium.ActivityName") 76 A: android:exported(0x01010010)=(type 0x12)0xffffffff 77 E: service (line=7) 78 A: android:name(0x01010001)="org.chromium.RandomService" (Raw: "org.chromium.RandomService") 79 """ 80 81 _NO_SERVICES = """N: android=http://schemas.android.com/apk/res/android 82 E: manifest (line=1) 83 A: package="org.chromium.abc" (Raw: "org.chromium.abc") 84 E: application (line=5) 85 E: activity (line=6) 86 A: android:name(0x01010003)="org.chromium.ActivityName" (Raw: "org.chromium.ActivityName") 87 A: android:exported(0x01010010)=(type 0x12)0xffffffff 88 """ 89 90 _NO_APPLICATION = """N: android=http://schemas.android.com/apk/res/android 91 E: manifest (line=1) 92 A: package="org.chromium.abc" (Raw: "org.chromium.abc") 93 """ 94 95 _SINGLE_INSTRUMENTATION_MANIFEST_DUMP = """N: android=http://schemas.android.com/apk/res/android 96 E: manifest (line=1) 97 A: package="org.chromium.xyz" (Raw: "org.chromium.xyz") 98 E: instrumentation (line=8) 99 A: android:label(0x01010001)="xyz" (Raw: "xyz") 100 A: android:name(0x01010003)="org.chromium.RandomTestRunner" (Raw: "org.chromium.RandomTestRunner") 101 A: android:targetPackage(0x01010021)="org.chromium.random_package" (Raw:"org.chromium.random_pacakge") 102 """ 103 104 _SINGLE_J4_INSTRUMENTATION_MANIFEST_DUMP = """N: android=http://schemas.android.com/apk/res/android 105 E: manifest (line=1) 106 A: package="org.chromium.xyz" (Raw: "org.chromium.xyz") 107 E: instrumentation (line=8) 108 A: android:label(0x01010001)="xyz" (Raw: "xyz") 109 A: android:name(0x01010003)="org.chromium.RandomJ4TestRunner" (Raw: "org.chromium.RandomJ4TestRunner") 110 A: android:targetPackage(0x01010021)="org.chromium.random_package" (Raw:"org.chromium.random_pacakge") 111 A: junit4=(type 0x12)0xffffffff (Raw: "true") 112 """ 113 114 _NO_NAMESPACE_MANIFEST_DUMP = """E: manifest (line=1) 115 A: package="org.chromium.xyz" (Raw: "org.chromium.xyz") 116 E: instrumentation (line=8) 117 A: http://schemas.android.com/apk/res/android:label(0x01010001)="xyz" (Raw: "xyz") 118 A: http://schemas.android.com/apk/res/android:name(0x01010003)="org.chromium.RandomTestRunner" (Raw: "org.chromium.RandomTestRunner") 119 A: http://schemas.android.com/apk/res/android:targetPackage(0x01010021)="org.chromium.random_package" (Raw:"org.chromium.random_pacakge") 120 """ 121 122 123 def _MockAaptDump(manifest_dump): 124 return mock.patch( 125 'devil.android.sdk.aapt.Dump', 126 mock.Mock(side_effect=None, return_value=manifest_dump.split('\n'))) 127 128 class ApkHelperTest(mock_calls.TestCase): 129 130 def testGetInstrumentationName(self): 131 with _MockAaptDump(_MANIFEST_DUMP): 132 helper = apk_helper.ApkHelper('') 133 with self.assertRaises(base_error.BaseError): 134 helper.GetInstrumentationName() 135 136 def testGetActivityName(self): 137 with _MockAaptDump(_MANIFEST_DUMP): 138 helper = apk_helper.ApkHelper('') 139 self.assertEquals( 140 helper.GetActivityName(), 'org.chromium.abc.MainActivity') 141 142 def testGetViewActivityName(self): 143 with _MockAaptDump(_MANIFEST_DUMP): 144 helper = apk_helper.ApkHelper('') 145 self.assertEquals( 146 helper.GetViewActivityName(), 'org.chromium.ViewActivity') 147 148 def testGetAllInstrumentations(self): 149 with _MockAaptDump(_MANIFEST_DUMP): 150 helper = apk_helper.ApkHelper('') 151 all_instrumentations = helper.GetAllInstrumentations() 152 self.assertEquals(len(all_instrumentations), 2) 153 self.assertEquals(all_instrumentations[0]['android:name'], 154 'org.chromium.RandomJUnit4TestRunner') 155 self.assertEquals(all_instrumentations[1]['android:name'], 156 'org.chromium.RandomTestRunner') 157 158 def testGetPackageName(self): 159 with _MockAaptDump(_MANIFEST_DUMP): 160 helper = apk_helper.ApkHelper('') 161 self.assertEquals(helper.GetPackageName(), 'org.chromium.abc') 162 163 def testGetPermssions(self): 164 with _MockAaptDump(_MANIFEST_DUMP): 165 helper = apk_helper.ApkHelper('') 166 all_permissions = helper.GetPermissions() 167 self.assertEquals(len(all_permissions), 3) 168 self.assertTrue('android.permission.INTERNET' in all_permissions) 169 self.assertTrue( 170 'android.permission.READ_EXTERNAL_STORAGE' in all_permissions) 171 self.assertTrue( 172 'android.permission.ACCESS_FINE_LOCATION' in all_permissions) 173 174 def testGetSplitName(self): 175 with _MockAaptDump(_MANIFEST_DUMP): 176 helper = apk_helper.ApkHelper('') 177 self.assertEquals(helper.GetSplitName(), 'random_split') 178 179 def testHasIsolatedProcesses_noApplication(self): 180 with _MockAaptDump(_NO_APPLICATION): 181 helper = apk_helper.ApkHelper('') 182 self.assertFalse(helper.HasIsolatedProcesses()) 183 184 def testHasIsolatedProcesses_noServices(self): 185 with _MockAaptDump(_NO_SERVICES): 186 helper = apk_helper.ApkHelper('') 187 self.assertFalse(helper.HasIsolatedProcesses()) 188 189 def testHasIsolatedProcesses_oneNotIsolatedProcess(self): 190 with _MockAaptDump(_NO_ISOLATED_SERVICES): 191 helper = apk_helper.ApkHelper('') 192 self.assertFalse(helper.HasIsolatedProcesses()) 193 194 def testHasIsolatedProcesses_oneIsolatedProcess(self): 195 with _MockAaptDump(_MANIFEST_DUMP): 196 helper = apk_helper.ApkHelper('') 197 self.assertTrue(helper.HasIsolatedProcesses()) 198 199 def testGetSingleInstrumentationName(self): 200 with _MockAaptDump(_SINGLE_INSTRUMENTATION_MANIFEST_DUMP): 201 helper = apk_helper.ApkHelper('') 202 self.assertEquals('org.chromium.RandomTestRunner', 203 helper.GetInstrumentationName()) 204 205 def testGetSingleJUnit4InstrumentationName(self): 206 with _MockAaptDump(_SINGLE_J4_INSTRUMENTATION_MANIFEST_DUMP): 207 helper = apk_helper.ApkHelper('') 208 self.assertEquals('org.chromium.RandomJ4TestRunner', 209 helper.GetInstrumentationName()) 210 211 def testGetAllMetadata(self): 212 with _MockAaptDump(_MANIFEST_DUMP): 213 helper = apk_helper.ApkHelper('') 214 self.assertEquals([('name1', 'value1'), ('name2', 'value2')], 215 helper.GetAllMetadata()) 216 217 def testGetSingleInstrumentationName_strippedNamespaces(self): 218 with _MockAaptDump(_NO_NAMESPACE_MANIFEST_DUMP): 219 helper = apk_helper.ApkHelper('') 220 self.assertEquals('org.chromium.RandomTestRunner', 221 helper.GetInstrumentationName()) 222 223 224 if __name__ == '__main__': 225 unittest.main(verbosity=2) 226