def _ResourceSizes(args): chartjson = _BASE_CHART.copy() if args.output_format else None reporter = _ChartJsonReporter(chartjson) # Create DexStatsCollector here to track unique methods across trichrome APKs. dex_stats_collector = method_count.DexStatsCollector() specs = [ ('Chrome_', args.trichrome_chrome), ('WebView_', args.trichrome_webview), ('Library_', args.trichrome_library), ] for prefix, path in specs: if path: reporter.trace_title_prefix = prefix child_dex_stats_collector = _AnalyzeApkOrApks(reporter, path, args.out_dir) dex_stats_collector.MergeFrom(prefix, child_dex_stats_collector) if any(path for _, path in specs): reporter.SynthesizeTotals(dex_stats_collector.GetUniqueMethodCount()) else: _AnalyzeApkOrApks(reporter, args.input, args.out_dir) if chartjson: _DumpChartJson(args, chartjson)
def do_measure(split_name, on_demand): logging.info('Measuring %s on_demand=%s', split_name, on_demand) # Use no-op reporting functions to get normalized size for DFMs. inner_report_func = report_func inner_dex_stats_collector = dex_stats_collector if on_demand: inner_report_func = lambda *_: None inner_dex_stats_collector = method_count.DexStatsCollector() size = _AnalyzeInternal(f.name, sdk_version, inner_report_func, inner_dex_stats_collector, out_dir, apks_path=apk_path, split_name=split_name) report_func('DFM_' + split_name, 'Size with hindi', size, 'bytes')
def _AnalyzeApkOrApks(report_func, apk_path, args): # Create DexStatsCollector here to track unique methods across base & chrome # modules. dex_stats_collector = method_count.DexStatsCollector() out_dir, tool_prefix = _ConfigOutDirAndToolsPrefix(args.out_dir) if apk_path.endswith('.apk'): sdk_version, _, _ = _ParseManifestAttributes(apk_path) _AnalyzeInternal(apk_path, sdk_version, report_func, dex_stats_collector, out_dir, tool_prefix) elif apk_path.endswith('.apks'): with tempfile.NamedTemporaryFile(suffix='.apk') as f: with zipfile.ZipFile(apk_path) as z: # Currently bundletool is creating two apks when .apks is created # without specifying an sdkVersion. Always measure the one with an # uncompressed shared library. try: info = z.getinfo('splits/base-master_2.apk') except KeyError: info = z.getinfo('splits/base-master.apk') _ExtractToTempFile(z, info.filename, f) sdk_version, _, _ = _ParseManifestAttributes(f.name) orig_report_func = report_func report_func = _AccumulatingReporter() def do_measure(split_name, on_demand): logging.info('Measuring %s on_demand=%s', split_name, on_demand) # Use no-op reporting functions to get normalized size for DFMs. inner_report_func = report_func inner_dex_stats_collector = dex_stats_collector if on_demand: inner_report_func = lambda *_: None inner_dex_stats_collector = method_count.DexStatsCollector( ) size = _AnalyzeInternal(f.name, sdk_version, inner_report_func, inner_dex_stats_collector, out_dir, tool_prefix, apks_path=apk_path, split_name=split_name) report_func('DFM_' + split_name, 'Size with hindi', size, 'bytes') # Measure base outside of the loop since we've already extracted it. do_measure('base', on_demand=False) for subpath, split_name in _IterSplits(z.namelist()): if split_name != 'base': _ExtractToTempFile(z, subpath, f) _, _, on_demand = _ParseManifestAttributes(f.name) do_measure(split_name, on_demand=on_demand) report_func.DumpReports(orig_report_func) report_func = orig_report_func else: raise Exception('Unknown file type: ' + apk_path) # Report dex stats outside of _AnalyzeInternal() so that the "unique methods" # metric is not just the sum of the base and chrome modules. for metric, count in dex_stats_collector.GetTotalCounts().items(): report_func('Dex', metric, count, 'entries') report_func('Dex', 'unique methods', dex_stats_collector.GetUniqueMethodCount(), 'entries') report_func('DexCache', 'DexCache', dex_stats_collector.GetDexCacheSize(pre_oreo=sdk_version < 26), 'bytes') return dex_stats_collector