( device: DeviceInfo, packageName: string, xml: string, )
| 112 | } |
| 113 | |
| 114 | async function writeAndroidDevPrefs( |
| 115 | device: DeviceInfo, |
| 116 | packageName: string, |
| 117 | xml: string, |
| 118 | ): Promise<void> { |
| 119 | const probeArgs = ['shell', 'run-as', packageName, 'id']; |
| 120 | const probeResult = await runAndroidAdb(device, probeArgs, { allowFailure: true }); |
| 121 | if (probeResult.exitCode !== 0) { |
| 122 | const runAsDenied = isAndroidRunAsDeniedOutput(probeResult.stdout, probeResult.stderr); |
| 123 | throw new AppError( |
| 124 | 'COMMAND_FAILED', |
| 125 | runAsDenied |
| 126 | ? `Failed to access Android app sandbox for ${packageName}` |
| 127 | : `Failed to probe Android app sandbox for ${packageName}`, |
| 128 | { |
| 129 | package: packageName, |
| 130 | cmd: 'adb', |
| 131 | args: probeArgs, |
| 132 | stdout: probeResult.stdout, |
| 133 | stderr: probeResult.stderr, |
| 134 | exitCode: probeResult.exitCode, |
| 135 | hint: runAsDenied ? ANDROID_RUN_AS_HINT : ANDROID_PROBE_HINT, |
| 136 | }, |
| 137 | ); |
| 138 | } |
| 139 | |
| 140 | try { |
| 141 | await runAndroidAdb(device, ['shell', 'run-as', packageName, 'mkdir', '-p', 'shared_prefs']); |
| 142 | await runAndroidAdb(device, ['shell', 'run-as', packageName, 'tee', ANDROID_DEV_PREFS_PATH], { |
| 143 | stdin: xml.trimEnd(), |
| 144 | }); |
| 145 | } catch (error) { |
| 146 | const appErr = asAppError(error); |
| 147 | if (appErr.code === 'TOOL_MISSING') throw appErr; |
| 148 | const stdout = typeof appErr.details?.stdout === 'string' ? appErr.details.stdout : ''; |
| 149 | const stderr = typeof appErr.details?.stderr === 'string' ? appErr.details.stderr : ''; |
| 150 | const runAsDenied = isAndroidRunAsDeniedOutput(stdout, stderr); |
| 151 | throw new AppError( |
| 152 | 'COMMAND_FAILED', |
| 153 | runAsDenied |
| 154 | ? `Failed to access Android app sandbox for ${packageName}` |
| 155 | : `Failed to write Android runtime hints for ${packageName}`, |
| 156 | { |
| 157 | ...(appErr.details ?? {}), |
| 158 | package: packageName, |
| 159 | cmd: 'adb', |
| 160 | phase: 'write-runtime-hints', |
| 161 | hint: runAsDenied ? ANDROID_RUN_AS_HINT : ANDROID_WRITE_HINT, |
| 162 | }, |
| 163 | appErr, |
| 164 | ); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | async function applyIosSimulatorRuntimeHints( |
| 169 | device: DeviceInfo, |
no test coverage detected