13d6e487dSEvan Baconimport fs from 'fs';
23d6e487dSEvan Baconimport path from 'path';
33d6e487dSEvan Bacon
43d6e487dSEvan Baconimport { GradleProps } from './resolveGradleProps';
5*8a424bebSJames Ideimport { Device, DeviceABI, getDeviceABIsAsync } from '../../start/platforms/android/adb';
63d6e487dSEvan Bacon
7474a7a4bSEvan Baconconst debug = require('debug')('expo:run:android:resolveInstallApkName') as typeof console.log;
8474a7a4bSEvan Bacon
93d6e487dSEvan Baconexport async function resolveInstallApkNameAsync(
103d6e487dSEvan Bacon  device: Pick<Device, 'name' | 'pid'>,
113d6e487dSEvan Bacon  { appName, buildType, flavors, apkVariantDirectory }: GradleProps
123d6e487dSEvan Bacon) {
133d6e487dSEvan Bacon  const availableCPUs = await getDeviceABIsAsync(device);
143d6e487dSEvan Bacon  availableCPUs.push(DeviceABI.universal);
153d6e487dSEvan Bacon
16474a7a4bSEvan Bacon  debug('Supported ABIs: ' + availableCPUs.join(', '));
17474a7a4bSEvan Bacon  debug('Searching for APK: ' + apkVariantDirectory);
183d6e487dSEvan Bacon
193d6e487dSEvan Bacon  // Check for cpu specific builds first
203d6e487dSEvan Bacon  for (const availableCPU of availableCPUs) {
213d6e487dSEvan Bacon    const apkName = getApkFileName(appName, buildType, flavors, availableCPU);
223d6e487dSEvan Bacon    const apkPath = path.join(apkVariantDirectory, apkName);
23474a7a4bSEvan Bacon    debug('Checking for APK at:', apkPath);
243d6e487dSEvan Bacon    if (fs.existsSync(apkPath)) {
253d6e487dSEvan Bacon      return apkName;
263d6e487dSEvan Bacon    }
273d6e487dSEvan Bacon  }
283d6e487dSEvan Bacon
293d6e487dSEvan Bacon  // Otherwise use the default apk named after the variant: app-debug.apk
303d6e487dSEvan Bacon  const apkName = getApkFileName(appName, buildType, flavors);
313d6e487dSEvan Bacon  const apkPath = path.join(apkVariantDirectory, apkName);
32474a7a4bSEvan Bacon  debug('Checking for fallback APK at:', apkPath);
333d6e487dSEvan Bacon  if (fs.existsSync(apkPath)) {
343d6e487dSEvan Bacon    return apkName;
353d6e487dSEvan Bacon  }
363d6e487dSEvan Bacon
373d6e487dSEvan Bacon  return null;
383d6e487dSEvan Bacon}
393d6e487dSEvan Bacon
403d6e487dSEvan Baconfunction getApkFileName(
413d6e487dSEvan Bacon  appName: string,
423d6e487dSEvan Bacon  buildType: string,
433d6e487dSEvan Bacon  flavors?: string[] | null,
443d6e487dSEvan Bacon  cpuArch?: string | null
453d6e487dSEvan Bacon) {
463d6e487dSEvan Bacon  let apkName = `${appName}-`;
473d6e487dSEvan Bacon  if (flavors) {
483d6e487dSEvan Bacon    apkName += flavors.reduce((rest, flavor) => `${rest}${flavor}-`, '');
493d6e487dSEvan Bacon  }
503d6e487dSEvan Bacon  if (cpuArch) {
513d6e487dSEvan Bacon    apkName += `${cpuArch}-`;
523d6e487dSEvan Bacon  }
533d6e487dSEvan Bacon  apkName += `${buildType}.apk`;
543d6e487dSEvan Bacon
553d6e487dSEvan Bacon  return apkName;
563d6e487dSEvan Bacon}
57