Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Localization on Android #590

Merged
merged 10 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 87 additions & 5 deletions packages/vscode-extension/src/devices/AndroidEmulatorDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ChildProcess, exec, lineReader } from "../utilities/subprocess";
import { BuildResult } from "../builders/BuildManager";
import { AndroidSystemImageInfo, DeviceInfo, DevicePlatform } from "../common/DeviceManager";
import { Logger } from "../Logger";
import { AppPermissionType, DeviceSettings } from "../common/Project";
import { AppPermissionType, DeviceSettings, Locale } from "../common/Project";
import { getAndroidSystemImages } from "../utilities/sdkmanager";
import { EXPO_GO_PACKAGE_NAME, fetchExpoLaunchDeeplink } from "../builders/expoGo";
import { Platform } from "../utilities/platform";
Expand Down Expand Up @@ -78,7 +78,71 @@ export class AndroidEmulatorDevice extends DeviceBase {
}, DISPOSE_TIMEOUT);
}

private async shouldUpdateLocale(newLocale: Locale) {
const locale = newLocale.replace("_", "-");
const { stdout } = await exec(ADB_PATH, [
"-s",
this.serial!,
"shell",
"settings",
"get",
"system",
"system_locales",
]);

// if user did not use the device before it might not have system_locales property
// as en-US is the default locale, used by the system, when no setting is provided
// we assume that no value in stdout is the same as en-US
if ((stdout ?? "en-US") === locale) {
return false;
}
return true;
}

/**
* This method changes device locale by modifying system_locales system setting.
*/
private async changeLocale(newLocale: Locale): Promise<void> {
const locale = newLocale.replace("_", "-");

await exec(ADB_PATH, [
"-s",
this.serial!,
"shell",
"settings",
"put",
"system",
"system_locales",
locale,
]);

// this is needed to make sure that changes will persist
await exec(ADB_PATH, ["-s", this.serial!, "shell", "sync"]);

// TODO: Find a way to change or remove persist.sys.locale without root access. note: removing the whole
// data/property/persistent_properties file would also work as we persist device settings globally in Radon IDE
const { stdout } = await exec(ADB_PATH, [
"-s",
this.serial!,
"shell",
"getprop",
"persist.sys.locale",
]);

if (stdout) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would feel more natural if we made this check before the other exec call given you use a transient stdout variable

Logger.warn(
"Updating locale will not take effect as the device has altered locale via system settings which always takes precedence over the device setting the IDE uses."
);
}
}

async changeSettings(settings: DeviceSettings) {
let shouldRestart = false;
if (await this.shouldUpdateLocale(settings.locale)) {
shouldRestart = true;
await this.changeLocale(settings.locale);
}

await exec(ADB_PATH, [
"-s",
this.serial!,
Expand Down Expand Up @@ -125,10 +189,29 @@ export class AndroidEmulatorDevice extends DeviceBase {
settings.location.latitude.toString(),
]);
}
return false;
return shouldRestart;
}

/**
* This method restarts the emulator process using SIGKILL signal.
* Should be used for the situations when quick reboot is necessary
* and when we don't care about the emulator's process state
*/
private async forcefullyResetDevice() {
this.emulatorProcess?.kill(9);
await this.internalBootDevice();
}

async bootDevice(deviceSettings: DeviceSettings): Promise<void> {
await this.internalBootDevice();

let shouldRestart = await this.changeSettings(deviceSettings);
if (shouldRestart) {
await this.forcefullyResetDevice();
}
}

async bootDevice(settings: DeviceSettings) {
async internalBootDevice() {
// this prevents booting device with the same AVD twice
await ensureOldEmulatorProcessExited(this.avdId);

Expand All @@ -144,6 +227,7 @@ export class AndroidEmulatorDevice extends DeviceBase {
"-no-boot-anim",
"-grpc-use-token",
"-no-snapshot-save",
"-writable-system",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this option? why are we adding it here? It should be explained in PR description

],
{ env: { ANDROID_AVD_HOME: avdDirectory } }
);
Expand Down Expand Up @@ -172,8 +256,6 @@ export class AndroidEmulatorDevice extends DeviceBase {
});

this.serial = await initPromise;

await this.changeSettings(settings);
}

async configureExpoDevMenu(packageName: string) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode-extension/src/devices/DeviceBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from "fs";
import { Disposable } from "vscode";
import { Preview } from "./preview";
import { BuildResult } from "../builders/BuildManager";
import { AppPermissionType, DeviceSettings, TouchPoint, Locale } from "../common/Project";
import { AppPermissionType, DeviceSettings, TouchPoint } from "../common/Project";
import { DeviceInfo, DevicePlatform } from "../common/DeviceManager";
import { tryAcquiringLock } from "../utilities/common";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function DeviceSettingsDropdown({ children, disabled }: DeviceSettingsDropdownPr
<span className="codicon codicon-location" />
Set Device Location
</DropdownMenu.Item>
{projectState.selectedDevice?.platform === DevicePlatform.IOS && <LocalizationItem />}
<LocalizationItem />
<Label>Permissions</Label>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger className="dropdown-menu-item">
Expand Down