1#!/usr/bin/python2.4 2# 3# 4# Copyright 2009, The Android Open Source Project 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18"""In memory representation of AndroidManifest.xml file. 19 20Specification of AndroidManifest.xml can be found at 21http://developer.android.com/guide/topics/manifest/manifest-intro.html 22""" 23 24# python imports 25import os 26import xml.dom.minidom 27import xml.parsers 28 29 30class AndroidManifest(object): 31 """In memory representation of AndroidManifest.xml file.""" 32 33 FILENAME = 'AndroidManifest.xml' 34 35 def __init__(self, app_path=None): 36 if app_path: 37 self._ParseManifest(app_path) 38 39 def GetAppPath(self): 40 """Retrieve file system path to this manifest file's directory.""" 41 return self._app_path 42 43 def GetPackageName(self): 44 """Retrieve package name defined at <manifest package="...">. 45 46 Returns: 47 Package name if defined, otherwise None 48 """ 49 manifest = self._GetManifestElement() 50 if not manifest or not manifest.hasAttribute('package'): 51 return None 52 return manifest.getAttribute('package') 53 54 def _ParseManifest(self, app_path): 55 """Parse AndroidManifest.xml at the specified path. 56 57 Args: 58 app_path: path to folder containing AndroidManifest.xml 59 Raises: 60 IOError: AndroidManifest.xml cannot be found at given path, or cannot be 61 opened for reading 62 """ 63 self._app_path = app_path 64 self._manifest_path = os.path.join(app_path, self.FILENAME) 65 self._dom = xml.dom.minidom.parse(self._manifest_path) 66 67 def AddUsesSdk(self, min_sdk_version): 68 """Adds a uses-sdk element to manifest. 69 70 Args: 71 min_sdk_version: value to provide for minSdkVersion attribute. 72 """ 73 manifest = self._GetManifestElement() 74 uses_sdk_elements = manifest.getElementsByTagName('uses-sdk') 75 if uses_sdk_elements: 76 uses_sdk_element = uses_sdk_elements[0] 77 else: 78 uses_sdk_element = self._dom.createElement('uses-sdk') 79 manifest.appendChild(uses_sdk_element) 80 81 uses_sdk_element.setAttribute('android:minSdkVersion', min_sdk_version) 82 self._SaveXml() 83 84 def GetInstrumentationNames(self): 85 """Get the instrumentation names from manifest. 86 87 Returns: 88 list of names, might be empty 89 """ 90 instr_elements = self._dom.getElementsByTagName('instrumentation') 91 instrs = [] 92 for element in instr_elements: 93 instrs.append(element.getAttribute('android:name')) 94 return instrs 95 96 def _GetManifestElement(self): 97 """Retrieve the root manifest element. 98 99 Returns: 100 the DOM element for manifest or None. 101 """ 102 manifests = self._dom.getElementsByTagName('manifest') 103 if not manifests: 104 return None 105 return manifests[0] 106 107 def _SaveXml(self): 108 """Saves the manifest to disk.""" 109 self._dom.writexml(open(self._manifest_path, mode='w'), encoding='utf-8') 110 111 112def CreateAndroidManifest(path): 113 """Factory method for creating a AndroidManifest. 114 115 Args: 116 path: the directory for the manifest file 117 118 Return: 119 the AndroidManifest or None if there was no file present 120 """ 121 manifest_path = os.path.join(path, AndroidManifest.FILENAME) 122 if os.path.isfile(manifest_path): 123 manifest = AndroidManifest() 124 manifest._ParseManifest(path) 125 return manifest 126 else: 127 return None 128