3838Usage:
3939 Specify which apk to generate priv-app permissions for. If no apk is \
4040 specified, this will default to all APKs under "<ANDROID_PRODUCT_OUT>/ \
41- system/priv-app".
41+ system/priv-app and (system/)product/priv-app ".
4242
4343Examples:
4444
@@ -156,9 +156,18 @@ def __init__(self, adb_path=None, aapt_path=None, use_device=None,
156156 'You must either set up your build environment, or specify a '
157157 'device to run against. See --help for more info.' )
158158
159- self .privapp_apks = self ._resolve_apks (apks )
160- self .permissions_dir = self ._resolve_sys_path ('system/etc/permissions' )
161- self .sysconfig_dir = self ._resolve_sys_path ('system/etc/sysconfig' )
159+ self .system_privapp_apks , self .product_privapp_apks = (
160+ self ._resolve_apks (apks ))
161+ self .system_permissions_dir = (
162+ self ._resolve_sys_path ('system/etc/permissions' ))
163+ self .system_sysconfig_dir = (
164+ self ._resolve_sys_path ('system/etc/sysconfig' ))
165+ self .product_permissions_dir = (
166+ self ._resolve_sys_path ('product/etc/permissions' ,
167+ 'system/product/etc/permissions' ))
168+ self .product_sysconfig_dir = (
169+ self ._resolve_sys_path ('product/etc/sysconfig' ,
170+ 'system/product/etc/sysconfig' ))
162171 self .framework_res_apk = self ._resolve_sys_path ('system/framework/'
163172 'framework-res.apk' )
164173
@@ -289,7 +298,8 @@ def _resolve_apks(self, apks):
289298 be found.
290299 """
291300 if not apks :
292- return self ._resolve_all_privapps ()
301+ return (self ._resolve_all_system_privapps (),
302+ self ._resolve_all_product_privapps ())
293303
294304 ret_apks = []
295305 for apk in apks :
@@ -306,29 +316,77 @@ def _resolve_apks(self, apks):
306316 raise MissingResourceError ('File "%s" does not exist.' % apk )
307317 else :
308318 ret_apks .append (apk )
309- return ret_apks
319+ return ret_apks , None
310320
311- def _resolve_all_privapps (self ):
321+ def _resolve_all_system_privapps (self ):
312322 """Extract package name and requested permissions."""
313323 if self ._is_android_env :
314- priv_app_dir = os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ],
315- 'system/priv-app' )
324+ system_priv_app_dir = (
325+ os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ],
326+ 'system/priv-app' ))
316327 else :
317328 try :
318- priv_app_dir = self .adb .pull ('/system/priv-app/' )
329+ system_priv_app_dir = self .adb .pull ('/system/priv-app/' )
319330 except subprocess .CalledProcessError :
320331 raise MissingResourceError (
321332 'Directory "/system/priv-app" could not be pulled from on '
322333 'device "%s".' % self .adb .serial )
323334
324- return get_output ('find %s -name "*.apk"' % priv_app_dir ).split ()
335+ return get_output ('find %s -name "*.apk"' % system_priv_app_dir ).split ()
325336
326- def _resolve_sys_path (self , file_path ):
337+ def _resolve_all_product_privapps (self ):
338+ """Extract package name and requested permissions."""
339+ if self ._is_android_env :
340+ product_priv_app_dir = (
341+ os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ],
342+ 'product/priv-app' ))
343+ if not os .path .exists (product_priv_app_dir ):
344+ product_priv_app_dir = (
345+ os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ],
346+ 'system/product/priv-app' ))
347+ else :
348+ try :
349+ product_priv_app_dir = self .adb .pull ('/product/priv-app/' )
350+ except subprocess .CalledProcessError :
351+ print ('Warning: Directory "/product/priv-app" could not be '
352+ 'pulled from on device "%s". Trying '
353+ '"/system/product/priv-app"' % self .adb .serial ,
354+ file = sys .stderr )
355+ try :
356+ product_priv_app_dir = (
357+ self .adb .pull ('/system/product/priv-app/' ))
358+ except subprocess .CalledProcessError :
359+ raise MissingResourceError (
360+ 'Directory "/system/product/priv-app" could not be '
361+ 'pulled from on device "%s".' % self .adb .serial )
362+
363+ return get_output (
364+ 'find %s -name "*.apk"' % product_priv_app_dir ).split ()
365+
366+ def _resolve_sys_path (self , file_path , fallback_file_path = None ):
327367 """Resolves a path that is a part of an Android System Image."""
328368 if self ._is_android_env :
329- return os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ], file_path )
369+ sys_path = (
370+ os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ], file_path ))
371+ if not os .path .exists (sys_path ):
372+ sys_path = (
373+ os .path .join (os .environ ['ANDROID_PRODUCT_OUT' ],
374+ fallback_file_path ))
330375 else :
331- return self .adb .pull (file_path )
376+ try :
377+ sys_path = self .adb .pull (file_path )
378+ except subprocess .CalledProcessError :
379+ print ('Warning: Directory %s could not be pulled from on device'
380+ '"%s". Trying "/system/product/priv-app"'
381+ % (file_path , self .adb .serial ), file = sys .stderr )
382+ try :
383+ sys_path = self .adb .pull (fallback_file_path )
384+ except subprocess .CalledProcessError :
385+ raise MissingResourceError (
386+ 'Directory %s could not be pulled from on '
387+ 'device "%s".' % (fallback_file_path , self .adb .serial ))
388+
389+ return sys_path
332390
333391
334392def get_output (command ):
@@ -390,17 +448,38 @@ def parse_args():
390448 help = 'A list of paths to priv-app APKs to generate permissions for. '
391449 'To make a path device-side, prefix the path with "device:".'
392450 )
451+ parser .add_argument (
452+ '-w' ,
453+ '--writetodisk' ,
454+ action = 'store_true' ,
455+ default = False ,
456+ required = False ,
457+ help = 'Whether or not to store the generated permissions directly to '
458+ 'a file. See --systemfile/--productfile for more information.'
459+ )
460+ parser .add_argument (
461+ '--systemfile' ,
462+ default = './system.xml' ,
463+ required = False ,
464+ help = 'Path to system permissions file. Default value is ./system.xml'
465+ )
466+ parser .add_argument (
467+ '--productfile' ,
468+ default = './product.xml' ,
469+ required = False ,
470+ help = 'Path to system permissions file. Default value is ./product.xml'
471+ )
393472 cmd_args = parser .parse_args ()
394473
395474 return cmd_args
396475
397-
398- def create_permission_file ( resources ):
476+ def create_permission_file ( resources , privapp_apks , permissions_dir ,
477+ sysconfig_dir , file = None ):
399478 # Parse base XML files in /etc dir, permissions listed there don't have
400479 # to be re-added
401480 base_permissions = {}
402- base_xml_files = itertools .chain (list_xml_files (resources . permissions_dir ),
403- list_xml_files (resources . sysconfig_dir ))
481+ base_xml_files = itertools .chain (list_xml_files (permissions_dir ),
482+ list_xml_files (sysconfig_dir ))
404483 for xml_file in base_xml_files :
405484 parse_config_xml (xml_file , base_permissions )
406485
@@ -409,7 +488,7 @@ def create_permission_file(resources):
409488
410489 apps_redefine_base = []
411490 results = {}
412- for priv_app in resources . privapp_apks :
491+ for priv_app in privapp_apks :
413492 pkg_info = extract_pkg_and_requested_permissions (resources .aapt ,
414493 priv_app )
415494 pkg_name = pkg_info ['package_name' ]
@@ -426,7 +505,8 @@ def create_permission_file(resources):
426505 results [pkg_name ] = sorted (priv_perms )
427506
428507 print_xml (results , apps_redefine_base )
429-
508+ if file is not None :
509+ print_xml (results , apps_redefine_base , file )
430510
431511def print_xml (results , apps_redefine_base , fd = sys .stdout ):
432512 """Print results to the given file."""
@@ -572,7 +652,43 @@ def cleanup():
572652 serial = args .serial ,
573653 apks = args .apks
574654 )
575- create_permission_file (tool_resources )
655+ system_permission_file = None
656+ product_permission_file = None
657+ print ('#' * 80 )
658+ print ('#' )
659+ if args .writetodisk :
660+ print ('#System XML written to %s:' % args .systemfile )
661+ system_permission_file = open (args .systemfile , 'w' )
662+ else :
663+ print ('#System XML:' )
664+ print ('#' )
665+ print ('#' * 80 )
666+ create_permission_file (
667+ tool_resources ,
668+ tool_resources .system_privapp_apks ,
669+ tool_resources .system_permissions_dir ,
670+ tool_resources .system_sysconfig_dir ,
671+ system_permission_file )
672+ if args .writetodisk :
673+ system_permission_file .close ()
674+ if tool_resources .product_privapp_apks :
675+ print ('#' * 80 )
676+ print ('#' )
677+ if args .writetodisk :
678+ print ('#Product XML written to %s:' % args .productfile )
679+ product_permission_file = open (args .productfile , 'w' )
680+ else :
681+ print ('#Product XML:' )
682+ print ('#' )
683+ print ('#' * 80 )
684+ create_permission_file (
685+ tool_resources ,
686+ tool_resources .product_privapp_apks ,
687+ tool_resources .product_permissions_dir ,
688+ tool_resources .product_sysconfig_dir ,
689+ product_permission_file )
690+ if args .writetodisk :
691+ product_permission_file .close ()
576692 except MissingResourceError as e :
577693 print (str (e ), file = sys .stderr )
578694 exit (1 )
0 commit comments