Merge "Align locale with activity that start the task"

This commit is contained in:
Calvin Pan
2023-01-10 04:29:25 +00:00
committed by Android (Google) Code Review
6 changed files with 83 additions and 0 deletions

View File

@@ -9085,6 +9085,25 @@ public class Activity extends ContextThemeWrapper
state, sourceSpec, targetSpec, viewIds, uiTranslationSpec);
}
/**
* If set, any activity launch in the same task will be overridden to the locale of activity
* that started the task.
*
* <p>Currently, Android supports per app languages, and system apps are able to start
* activities of another package on the same task, which may cause users to set different
* languages in different apps and display two different languages in one app.</p>
*
* <p>The <a href="https://developer.android.com/guide/topics/large-screens/activity-embedding">
* activity embedding feature</a> will align the locale with root activity automatically, but
* it doesn't land on the phone yet. If activity embedding land on the phone in the future,
* please consider adapting activity embedding directly.</p>
*
* @hide
*/
public void enableTaskLocaleOverride() {
ActivityClient.getInstance().enableTaskLocaleOverride(mToken);
}
class HostCallbacks extends FragmentHostCallback<Activity> {
public HostCallbacks() {
super(Activity.this /*activity*/);

View File

@@ -563,6 +563,14 @@ public class ActivityClient {
}
}
void enableTaskLocaleOverride(IBinder token) {
try {
getActivityClientController().enableTaskLocaleOverride(token);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/**
* Shows or hides a Camera app compat toggle for stretched issues with the requested state.
*

View File

@@ -171,4 +171,10 @@ interface IActivityClientController {
*/
oneway void requestCompatCameraControl(in IBinder token, boolean showControl,
boolean transformationApplied, in ICompatCameraControlCallback callback);
/**
* If set, any activity launch in the same task will be overridden to the locale of activity
* that started the task.
*/
void enableTaskLocaleOverride(in IBinder token);
}

View File

@@ -1644,4 +1644,19 @@ class ActivityClientController extends IActivityClientController.Stub {
}
return false;
}
@Override
public void enableTaskLocaleOverride(IBinder token) {
if (UserHandle.getAppId(Binder.getCallingUid()) != SYSTEM_UID) {
// Only allow system to align locale.
return;
}
synchronized (mGlobalLock) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.getTask().mAlignActivityLocaleWithTask = true;
}
}
}
}

View File

@@ -298,6 +298,7 @@ import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.LocaleList;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
@@ -7998,6 +7999,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
super.resolveOverrideConfiguration(newParentConfiguration);
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
applyLocaleOverrideIfNeeded(resolvedConfig);
if (isFixedRotationTransforming()) {
// The resolved configuration is applied with rotated display configuration. If this
// activity matches its parent (the following resolving procedures are no-op), then it
@@ -10160,6 +10164,35 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
private void applyLocaleOverrideIfNeeded(Configuration resolvedConfig) {
// We always align the locale for ActivityEmbedding apps. System apps or some apps which
// has set known cert apps can embed across different uid activity.
boolean shouldAlignLocale = isEmbedded()
|| (task != null && task.mAlignActivityLocaleWithTask);
if (!shouldAlignLocale) {
return;
}
boolean differentPackage = task != null
&& task.realActivity != null
&& !task.realActivity.getPackageName().equals(packageName);
if (!differentPackage) {
return;
}
LocaleList locale;
final ActivityTaskManagerInternal.PackageConfig appConfig =
mAtmService.mPackageConfigPersister.findPackageConfiguration(
task.realActivity.getPackageName(), mUserId);
// if there is no app locale for the package, clear the target activity's locale.
if (appConfig == null || appConfig.mLocales == null || appConfig.mLocales.isEmpty()) {
locale = LocaleList.getEmptyLocaleList();
} else {
locale = appConfig.mLocales;
}
resolvedConfig.setLocales(locale);
}
/**
* Whether we should send fake focus when the activity is resumed. This is done because some
* game engines wait to get focus before drawing the content of the app.

View File

@@ -612,6 +612,8 @@ class Task extends TaskFragment {
boolean mLastSurfaceShowing = true;
boolean mAlignActivityLocaleWithTask = false;
private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,