1*9e965d6fSRomain Jobredeaux# Copyright 2018 The Bazel Authors. All rights reserved. 2*9e965d6fSRomain Jobredeaux# 3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License. 5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at 6*9e965d6fSRomain Jobredeaux# 7*9e965d6fSRomain Jobredeaux# http://www.apache.org/licenses/LICENSE-2.0 8*9e965d6fSRomain Jobredeaux# 9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software 10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS, 11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and 13*9e965d6fSRomain Jobredeaux# limitations under the License. 14*9e965d6fSRomain Jobredeaux"""Creates the app launcher scripts.""" 15*9e965d6fSRomain Jobredeaux 16*9e965d6fSRomain Jobredeauxload(":deploy_info.bzl", "make_deploy_info_pb") 17*9e965d6fSRomain Jobredeauxload(":providers.bzl", "MIAppInfo", "MIAppLaunchInfo") 18*9e965d6fSRomain Jobredeauxload(":utils.bzl", "utils") 19*9e965d6fSRomain Jobredeauxload(":workspace.bzl", "make_dex_sync", "make_generic_sync", "merge_syncs") 20*9e965d6fSRomain Jobredeauxload("//rules/flags:flags.bzl", "flags") 21*9e965d6fSRomain Jobredeaux 22*9e965d6fSRomain JobredeauxHOST_TEST_WORKSPACE = "host_test_runner_workspace" 23*9e965d6fSRomain Jobredeaux 24*9e965d6fSRomain Jobredeaux_DEPLOY_SCRIPT = '''#!/bin/bash 25*9e965d6fSRomain Jobredeauxset -e # exit on failure 26*9e965d6fSRomain Jobredeauxumask 022 # set default file/dir creation mode to 755 27*9e965d6fSRomain Jobredeaux 28*9e965d6fSRomain JobredeauxAPP_FLAGS={app_flags} 29*9e965d6fSRomain JobredeauxGOOGPLAYSRVCS_CONTAINER_FLAGS={googplayservices_container_flags} 30*9e965d6fSRomain JobredeauxTEST_FLAGS={test_flags} 31*9e965d6fSRomain JobredeauxDEPLOY={deploy} 32*9e965d6fSRomain Jobredeaux 33*9e965d6fSRomain JobredeauxALL_TEST_ARGS=("$@") 34*9e965d6fSRomain Jobredeauxif [[ ! -z ${{TEST_FLAGS}} ]]; then 35*9e965d6fSRomain Jobredeaux RULE_TEST_ARGS={test_args} 36*9e965d6fSRomain Jobredeaux ALL_TEST_ARGS=("--nolaunch_app" "${{RULE_TEST_ARGS[@]}}" "$@") 37*9e965d6fSRomain Jobredeauxfi 38*9e965d6fSRomain Jobredeaux 39*9e965d6fSRomain Jobredeauxif [[ ! -z ${{GOOGPLAYSRVCS_CONTAINER_FLAGS}} ]]; then 40*9e965d6fSRomain Jobredeaux "${{DEPLOY}}" \ 41*9e965d6fSRomain Jobredeaux -flagfile="${{GOOGPLAYSRVCS_CONTAINER_FLAGS}}" \ 42*9e965d6fSRomain Jobredeaux "${{ALL_TEST_ARGS[@]}}" 43*9e965d6fSRomain Jobredeauxfi 44*9e965d6fSRomain Jobredeaux 45*9e965d6fSRomain Jobredeauxif [[ ! -z ${{APP_FLAGS}} ]]; then 46*9e965d6fSRomain Jobredeaux "${{DEPLOY}}" \ 47*9e965d6fSRomain Jobredeaux -flagfile="${{APP_FLAGS}}" \ 48*9e965d6fSRomain Jobredeaux "${{ALL_TEST_ARGS[@]}}" 49*9e965d6fSRomain Jobredeauxfi 50*9e965d6fSRomain Jobredeaux 51*9e965d6fSRomain Jobredeauxif [[ ! -z ${{TEST_FLAGS}} ]]; then 52*9e965d6fSRomain Jobredeaux "${{DEPLOY}}" \ 53*9e965d6fSRomain Jobredeaux -flagfile="${{TEST_FLAGS}}" \ 54*9e965d6fSRomain Jobredeaux --is_test=true \ 55*9e965d6fSRomain Jobredeaux "${{ALL_TEST_ARGS[@]}}" 56*9e965d6fSRomain Jobredeauxfi 57*9e965d6fSRomain Jobredeaux''' 58*9e965d6fSRomain Jobredeaux 59*9e965d6fSRomain Jobredeauxdef _make_deploy_script( 60*9e965d6fSRomain Jobredeaux ctx, 61*9e965d6fSRomain Jobredeaux out_script, 62*9e965d6fSRomain Jobredeaux deploy, 63*9e965d6fSRomain Jobredeaux app_flags = "", 64*9e965d6fSRomain Jobredeaux googplayservices_container_flags = "", 65*9e965d6fSRomain Jobredeaux test_flags = "", 66*9e965d6fSRomain Jobredeaux test_args = ""): 67*9e965d6fSRomain Jobredeaux deploy_contents = _DEPLOY_SCRIPT.format( 68*9e965d6fSRomain Jobredeaux app_flags = app_flags, 69*9e965d6fSRomain Jobredeaux googplayservices_container_flags = googplayservices_container_flags, 70*9e965d6fSRomain Jobredeaux deploy = deploy, 71*9e965d6fSRomain Jobredeaux test_flags = test_flags, 72*9e965d6fSRomain Jobredeaux test_args = test_args, 73*9e965d6fSRomain Jobredeaux ) 74*9e965d6fSRomain Jobredeaux ctx.actions.write(out_script, deploy_contents, is_executable = True) 75*9e965d6fSRomain Jobredeaux 76*9e965d6fSRomain Jobredeauxdef _make_app_runner( 77*9e965d6fSRomain Jobredeaux ctx, 78*9e965d6fSRomain Jobredeaux data_sync, 79*9e965d6fSRomain Jobredeaux manifest_package_name_path, 80*9e965d6fSRomain Jobredeaux out_launcher, 81*9e965d6fSRomain Jobredeaux out_launcher_flags, 82*9e965d6fSRomain Jobredeaux shell_apk = None, 83*9e965d6fSRomain Jobredeaux splits = None, 84*9e965d6fSRomain Jobredeaux deploy_info_pb = None, 85*9e965d6fSRomain Jobredeaux test_apk = None, 86*9e965d6fSRomain Jobredeaux test_support_apks = None, 87*9e965d6fSRomain Jobredeaux test_data = None, 88*9e965d6fSRomain Jobredeaux test_args = None, 89*9e965d6fSRomain Jobredeaux instrumented_app = None, 90*9e965d6fSRomain Jobredeaux googplayservices_container_app = None, 91*9e965d6fSRomain Jobredeaux use_adb_root = True, 92*9e965d6fSRomain Jobredeaux enable_metrics_logging = False, 93*9e965d6fSRomain Jobredeaux is_test = False): 94*9e965d6fSRomain Jobredeaux path_type = "path" if ctx.attr._mi_is_cmd else "short_path" 95*9e965d6fSRomain Jobredeaux 96*9e965d6fSRomain Jobredeaux deploy = utils.first(ctx.attr._deploy.files.to_list()) 97*9e965d6fSRomain Jobredeaux 98*9e965d6fSRomain Jobredeaux args = { 99*9e965d6fSRomain Jobredeaux "data_sync_path": getattr(data_sync, path_type), 100*9e965d6fSRomain Jobredeaux "is_cmd": str(ctx.attr._mi_is_cmd).lower(), 101*9e965d6fSRomain Jobredeaux "manifest_package_name_path": getattr(manifest_package_name_path, path_type), 102*9e965d6fSRomain Jobredeaux "target": ctx.label, 103*9e965d6fSRomain Jobredeaux } 104*9e965d6fSRomain Jobredeaux if shell_apk: 105*9e965d6fSRomain Jobredeaux args["shell_app_path"] = getattr(shell_apk, path_type) 106*9e965d6fSRomain Jobredeaux 107*9e965d6fSRomain Jobredeaux if splits: 108*9e965d6fSRomain Jobredeaux args["splits"] = [getattr(s, path_type) for s in splits] 109*9e965d6fSRomain Jobredeaux args["enable_splits"] = True 110*9e965d6fSRomain Jobredeaux 111*9e965d6fSRomain Jobredeaux if ctx.attr._mi_is_cmd: 112*9e965d6fSRomain Jobredeaux args["host_test_runner_workspace"] = HOST_TEST_WORKSPACE 113*9e965d6fSRomain Jobredeaux if test_support_apks or test_apk: 114*9e965d6fSRomain Jobredeaux args["apks"] = ",".join([apk.short_path for apk in [test_apk] + test_support_apks]) 115*9e965d6fSRomain Jobredeaux 116*9e965d6fSRomain Jobredeaux args["java_home"] = utils.host_jvm_path(ctx) 117*9e965d6fSRomain Jobredeaux 118*9e965d6fSRomain Jobredeaux args["studio_deployer"] = getattr(ctx.file._studio_deployer, path_type) 119*9e965d6fSRomain Jobredeaux args["use_adb_root"] = str(use_adb_root).lower() 120*9e965d6fSRomain Jobredeaux args["enable_metrics_logging"] = str(enable_metrics_logging).lower() 121*9e965d6fSRomain Jobredeaux 122*9e965d6fSRomain Jobredeaux android_test_runner = None 123*9e965d6fSRomain Jobredeaux if is_test and hasattr(ctx.attr, "_android_test_runner"): 124*9e965d6fSRomain Jobredeaux android_test_runner = ctx.file._android_test_runner 125*9e965d6fSRomain Jobredeaux args["android_test_runner"] = getattr(android_test_runner, path_type) 126*9e965d6fSRomain Jobredeaux 127*9e965d6fSRomain Jobredeaux if test_data: 128*9e965d6fSRomain Jobredeaux args["data_files"] = ",".join([f.short_path for f in test_data]) 129*9e965d6fSRomain Jobredeaux 130*9e965d6fSRomain Jobredeaux if test_apk: 131*9e965d6fSRomain Jobredeaux args["test_apk"] = test_apk.path 132*9e965d6fSRomain Jobredeaux 133*9e965d6fSRomain Jobredeaux if deploy_info_pb: 134*9e965d6fSRomain Jobredeaux args["deploy_info"] = getattr(deploy_info_pb, path_type) 135*9e965d6fSRomain Jobredeaux 136*9e965d6fSRomain Jobredeaux utils.create_flag_file(ctx, out_launcher_flags, **args) 137*9e965d6fSRomain Jobredeaux 138*9e965d6fSRomain Jobredeaux _make_deploy_script( 139*9e965d6fSRomain Jobredeaux ctx, 140*9e965d6fSRomain Jobredeaux out_launcher, 141*9e965d6fSRomain Jobredeaux getattr(deploy, path_type), 142*9e965d6fSRomain Jobredeaux app_flags = ( 143*9e965d6fSRomain Jobredeaux getattr(instrumented_app[MIAppLaunchInfo].launcher_flags, path_type) if instrumented_app else getattr(out_launcher_flags, path_type) 144*9e965d6fSRomain Jobredeaux ), 145*9e965d6fSRomain Jobredeaux googplayservices_container_flags = ( 146*9e965d6fSRomain Jobredeaux getattr(googplayservices_container_app[MIAppLaunchInfo].launcher_flags, path_type) if googplayservices_container_app else "" 147*9e965d6fSRomain Jobredeaux ), 148*9e965d6fSRomain Jobredeaux # Converts the python array of args into a bash array. Each arg is 149*9e965d6fSRomain Jobredeaux # wrapped with quotes to handle "space" separted flag value entries 150*9e965d6fSRomain Jobredeaux # and as result also escapes existing quotes. 151*9e965d6fSRomain Jobredeaux test_args = ("(%s)" % " ".join([ 152*9e965d6fSRomain Jobredeaux '"--test_arg=%s"' % arg.replace('"', '\\"') 153*9e965d6fSRomain Jobredeaux for arg in test_args 154*9e965d6fSRomain Jobredeaux ])) if test_args else "", 155*9e965d6fSRomain Jobredeaux test_flags = getattr(out_launcher_flags, path_type) if test_args or is_test else "", 156*9e965d6fSRomain Jobredeaux ) 157*9e965d6fSRomain Jobredeaux 158*9e965d6fSRomain Jobredeaux runner = [deploy] 159*9e965d6fSRomain Jobredeaux if android_test_runner: 160*9e965d6fSRomain Jobredeaux runner.extend(ctx.attr._java_jdk.files.to_list()) 161*9e965d6fSRomain Jobredeaux runner.append(android_test_runner) 162*9e965d6fSRomain Jobredeaux return runner 163*9e965d6fSRomain Jobredeaux 164*9e965d6fSRomain Jobredeauxdef make_launcher( 165*9e965d6fSRomain Jobredeaux ctx, 166*9e965d6fSRomain Jobredeaux mi_app_info, 167*9e965d6fSRomain Jobredeaux launcher, 168*9e965d6fSRomain Jobredeaux test_data = None, 169*9e965d6fSRomain Jobredeaux test_args = None, 170*9e965d6fSRomain Jobredeaux test_support_apks = None, 171*9e965d6fSRomain Jobredeaux googplayservices_container_app = None, 172*9e965d6fSRomain Jobredeaux use_adb_root = True, 173*9e965d6fSRomain Jobredeaux is_test = False): 174*9e965d6fSRomain Jobredeaux """ Runfiles for launching the apps are created. 175*9e965d6fSRomain Jobredeaux 176*9e965d6fSRomain Jobredeaux Args: 177*9e965d6fSRomain Jobredeaux ctx: The context 178*9e965d6fSRomain Jobredeaux mi_app_info: The MIAppInfo provider 179*9e965d6fSRomain Jobredeaux launcher: The launcher file 180*9e965d6fSRomain Jobredeaux test_data: The test data 181*9e965d6fSRomain Jobredeaux test_support_apks: The test support apks 182*9e965d6fSRomain Jobredeaux test_args: The test arguments 183*9e965d6fSRomain Jobredeaux googplayservices_container_app: The Google Play Services container app 184*9e965d6fSRomain Jobredeaux use_adb_root: Boolean argument to restart adb with root permissions. 185*9e965d6fSRomain Jobredeaux is_test: Boolean argument to identify if it's a test 186*9e965d6fSRomain Jobredeaux Returns: 187*9e965d6fSRomain Jobredeaux A list of files required for runtime common for both running binary and test. 188*9e965d6fSRomain Jobredeaux """ 189*9e965d6fSRomain Jobredeaux sync_pbs = [] 190*9e965d6fSRomain Jobredeaux runfiles = [] 191*9e965d6fSRomain Jobredeaux 192*9e965d6fSRomain Jobredeaux launcher_flags = utils.isolated_declare_file(ctx, "launcher.flag", sibling = launcher) 193*9e965d6fSRomain Jobredeaux 194*9e965d6fSRomain Jobredeaux runfiles.extend([launcher, launcher_flags]) 195*9e965d6fSRomain Jobredeaux 196*9e965d6fSRomain Jobredeaux runfiles.append(ctx.file._studio_deployer) 197*9e965d6fSRomain Jobredeaux if getattr(mi_app_info, "merged_manifest", None): 198*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_info.merged_manifest) 199*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_info.manifest_package_name) 200*9e965d6fSRomain Jobredeaux shell_apk = None 201*9e965d6fSRomain Jobredeaux splits = None 202*9e965d6fSRomain Jobredeaux if not is_test: 203*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "shell_apk"): 204*9e965d6fSRomain Jobredeaux shell_apk = mi_app_info.shell_apk 205*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_info.shell_apk) 206*9e965d6fSRomain Jobredeaux 207*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "splits"): 208*9e965d6fSRomain Jobredeaux splits = mi_app_info.splits 209*9e965d6fSRomain Jobredeaux runfiles.extend(mi_app_info.splits) 210*9e965d6fSRomain Jobredeaux 211*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "native_zip") and mi_app_info.native_zip: 212*9e965d6fSRomain Jobredeaux sync_pbs.append(make_generic_sync(ctx, zips = [mi_app_info.native_zip], sibling = launcher)) 213*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_info.native_zip) 214*9e965d6fSRomain Jobredeaux 215*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "r_dex"): 216*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_info.r_dex) 217*9e965d6fSRomain Jobredeaux sync_pbs.append(make_dex_sync(ctx, mi_app_info.r_dex, dir_name = "rdexes", sibling = launcher)) 218*9e965d6fSRomain Jobredeaux 219*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "merged_dex_shards"): 220*9e965d6fSRomain Jobredeaux runfiles.extend(mi_app_info.merged_dex_shards) 221*9e965d6fSRomain Jobredeaux bin_dex_sync = merge_syncs( 222*9e965d6fSRomain Jobredeaux ctx, 223*9e965d6fSRomain Jobredeaux [ 224*9e965d6fSRomain Jobredeaux make_dex_sync(ctx, dex_shard, sibling = launcher) 225*9e965d6fSRomain Jobredeaux for dex_shard in mi_app_info.merged_dex_shards 226*9e965d6fSRomain Jobredeaux ], 227*9e965d6fSRomain Jobredeaux "bin", 228*9e965d6fSRomain Jobredeaux sibling = launcher, 229*9e965d6fSRomain Jobredeaux ) 230*9e965d6fSRomain Jobredeaux sync_pbs.append(bin_dex_sync) 231*9e965d6fSRomain Jobredeaux 232*9e965d6fSRomain Jobredeaux instrumented_app = None 233*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "instrumented_app") and mi_app_info.instrumented_app: 234*9e965d6fSRomain Jobredeaux instrumented_app = mi_app_info.instrumented_app 235*9e965d6fSRomain Jobredeaux runfiles.extend(mi_app_info.instrumented_app[MIAppInfo].merged_dex_shards) 236*9e965d6fSRomain Jobredeaux 237*9e965d6fSRomain Jobredeaux # Add the binary under test dex shards to find additional tests. 238*9e965d6fSRomain Jobredeaux but_dex_sync = merge_syncs( 239*9e965d6fSRomain Jobredeaux ctx, 240*9e965d6fSRomain Jobredeaux [ 241*9e965d6fSRomain Jobredeaux make_dex_sync(ctx, dex_shard, sibling = launcher) 242*9e965d6fSRomain Jobredeaux for dex_shard in mi_app_info.instrumented_app[MIAppInfo].merged_dex_shards 243*9e965d6fSRomain Jobredeaux ], 244*9e965d6fSRomain Jobredeaux "but", 245*9e965d6fSRomain Jobredeaux sibling = launcher, 246*9e965d6fSRomain Jobredeaux ) 247*9e965d6fSRomain Jobredeaux sync_pbs.append(but_dex_sync) 248*9e965d6fSRomain Jobredeaux 249*9e965d6fSRomain Jobredeaux if test_data: 250*9e965d6fSRomain Jobredeaux runfiles.extend(test_data) 251*9e965d6fSRomain Jobredeaux if test_support_apks: 252*9e965d6fSRomain Jobredeaux runfiles.extend(test_support_apks) 253*9e965d6fSRomain Jobredeaux if is_test: 254*9e965d6fSRomain Jobredeaux test_apk = mi_app_info.apk 255*9e965d6fSRomain Jobredeaux runfiles.append(test_apk) 256*9e965d6fSRomain Jobredeaux else: 257*9e965d6fSRomain Jobredeaux test_apk = None 258*9e965d6fSRomain Jobredeaux 259*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "shell_apk") and mi_app_info.shell_apk and not is_test: 260*9e965d6fSRomain Jobredeaux sync_pbs.append( 261*9e965d6fSRomain Jobredeaux make_generic_sync( 262*9e965d6fSRomain Jobredeaux ctx, 263*9e965d6fSRomain Jobredeaux files = [mi_app_info.shell_apk], 264*9e965d6fSRomain Jobredeaux replacements = [ 265*9e965d6fSRomain Jobredeaux mi_app_info.shell_apk.short_path[:mi_app_info.shell_apk.short_path.rindex("/")], 266*9e965d6fSRomain Jobredeaux "apk", 267*9e965d6fSRomain Jobredeaux ], 268*9e965d6fSRomain Jobredeaux sibling = launcher, 269*9e965d6fSRomain Jobredeaux ), 270*9e965d6fSRomain Jobredeaux ) 271*9e965d6fSRomain Jobredeaux deploy_info_pb = None 272*9e965d6fSRomain Jobredeaux if hasattr(mi_app_info, "merged_manifest"): 273*9e965d6fSRomain Jobredeaux deploy_info_pb = make_deploy_info_pb( 274*9e965d6fSRomain Jobredeaux ctx, 275*9e965d6fSRomain Jobredeaux mi_app_info.merged_manifest, 276*9e965d6fSRomain Jobredeaux mi_app_info.splits if mi_app_info.splits else [mi_app_info.shell_apk], 277*9e965d6fSRomain Jobredeaux ) 278*9e965d6fSRomain Jobredeaux runfiles.append(deploy_info_pb) 279*9e965d6fSRomain Jobredeaux 280*9e965d6fSRomain Jobredeaux final_sync_pb = None 281*9e965d6fSRomain Jobredeaux 282*9e965d6fSRomain Jobredeaux # Create the final sync pb. 283*9e965d6fSRomain Jobredeaux if ctx.var.get("use_direct_deploy"): 284*9e965d6fSRomain Jobredeaux final_sync_pb = utils.make_sync(ctx, sync_pbs, mi_app_info.manifest_package_name, "app", sibling = launcher) 285*9e965d6fSRomain Jobredeaux else: 286*9e965d6fSRomain Jobredeaux final_sync_pb = merge_syncs(ctx, sync_pbs, "app", sibling = launcher) 287*9e965d6fSRomain Jobredeaux runfiles.append(final_sync_pb) 288*9e965d6fSRomain Jobredeaux 289*9e965d6fSRomain Jobredeaux runfiles.extend(_make_app_runner( 290*9e965d6fSRomain Jobredeaux ctx, 291*9e965d6fSRomain Jobredeaux final_sync_pb, 292*9e965d6fSRomain Jobredeaux mi_app_info.manifest_package_name, 293*9e965d6fSRomain Jobredeaux launcher, 294*9e965d6fSRomain Jobredeaux launcher_flags, 295*9e965d6fSRomain Jobredeaux shell_apk = shell_apk, 296*9e965d6fSRomain Jobredeaux splits = splits, 297*9e965d6fSRomain Jobredeaux deploy_info_pb = deploy_info_pb, 298*9e965d6fSRomain Jobredeaux test_apk = test_apk, 299*9e965d6fSRomain Jobredeaux test_support_apks = test_support_apks, 300*9e965d6fSRomain Jobredeaux test_data = test_data, 301*9e965d6fSRomain Jobredeaux test_args = test_args, 302*9e965d6fSRomain Jobredeaux instrumented_app = instrumented_app, 303*9e965d6fSRomain Jobredeaux googplayservices_container_app = googplayservices_container_app, 304*9e965d6fSRomain Jobredeaux use_adb_root = use_adb_root, 305*9e965d6fSRomain Jobredeaux enable_metrics_logging = flags.get(ctx).enable_metrics_logging, 306*9e965d6fSRomain Jobredeaux is_test = is_test, 307*9e965d6fSRomain Jobredeaux )) 308*9e965d6fSRomain Jobredeaux 309*9e965d6fSRomain Jobredeaux # Collect launcher details for additional apps 310*9e965d6fSRomain Jobredeaux mi_app_launch_infos = [] 311*9e965d6fSRomain Jobredeaux if instrumented_app: 312*9e965d6fSRomain Jobredeaux mi_app_launch_infos.append(mi_app_info.instrumented_app[MIAppLaunchInfo]) 313*9e965d6fSRomain Jobredeaux if googplayservices_container_app: 314*9e965d6fSRomain Jobredeaux mi_app_launch_infos.append(googplayservices_container_app[MIAppLaunchInfo]) 315*9e965d6fSRomain Jobredeaux 316*9e965d6fSRomain Jobredeaux # Append the additional launch and launcher flags. 317*9e965d6fSRomain Jobredeaux if mi_app_launch_infos: 318*9e965d6fSRomain Jobredeaux for mi_app_launch_info in mi_app_launch_infos: 319*9e965d6fSRomain Jobredeaux runfiles.append(mi_app_launch_info.launcher_flags) 320*9e965d6fSRomain Jobredeaux runfiles.extend(mi_app_launch_info.runfiles) 321*9e965d6fSRomain Jobredeaux 322*9e965d6fSRomain Jobredeaux return MIAppLaunchInfo( 323*9e965d6fSRomain Jobredeaux launcher = launcher, 324*9e965d6fSRomain Jobredeaux launcher_flags = launcher_flags, 325*9e965d6fSRomain Jobredeaux runfiles = runfiles, 326*9e965d6fSRomain Jobredeaux ) 327