1import fs from 'fs';
2import path from 'path';
3
4import * as Log from '../../log';
5import { Device, DeviceABI, getDeviceABIsAsync } from '../../start/platforms/android/adb';
6import { GradleProps } from './resolveGradleProps';
7
8export async function resolveInstallApkNameAsync(
9  device: Pick<Device, 'name' | 'pid'>,
10  { appName, buildType, flavors, apkVariantDirectory }: GradleProps
11) {
12  const availableCPUs = await getDeviceABIsAsync(device);
13  availableCPUs.push(DeviceABI.universal);
14
15  Log.debug('Supported ABIs: ' + availableCPUs.join(', '));
16  Log.debug('Searching for APK: ' + apkVariantDirectory);
17
18  // Check for cpu specific builds first
19  for (const availableCPU of availableCPUs) {
20    const apkName = getApkFileName(appName, buildType, flavors, availableCPU);
21    const apkPath = path.join(apkVariantDirectory, apkName);
22    Log.debug('Checking for APK at:', apkPath);
23    if (fs.existsSync(apkPath)) {
24      return apkName;
25    }
26  }
27
28  // Otherwise use the default apk named after the variant: app-debug.apk
29  const apkName = getApkFileName(appName, buildType, flavors);
30  const apkPath = path.join(apkVariantDirectory, apkName);
31  Log.debug('Checking for fallback APK at:', apkPath);
32  if (fs.existsSync(apkPath)) {
33    return apkName;
34  }
35
36  return null;
37}
38
39function getApkFileName(
40  appName: string,
41  buildType: string,
42  flavors?: string[] | null,
43  cpuArch?: string | null
44) {
45  let apkName = `${appName}-`;
46  if (flavors) {
47    apkName += flavors.reduce((rest, flavor) => `${rest}${flavor}-`, '');
48  }
49  if (cpuArch) {
50    apkName += `${cpuArch}-`;
51  }
52  apkName += `${buildType}.apk`;
53
54  return apkName;
55}
56