Merge "Remove active translation on Activity destroyed" into tm-qpr-dev am: 9c185693d4

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20022962

Change-Id: I1d3c6b4776c2b635a2c40d26ec47daecd478fb72
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mark Punzalan
2022-10-13 18:04:58 +00:00
committed by Automerger Merge Worker
2 changed files with 31 additions and 36 deletions

View File

@@ -175,10 +175,7 @@ public class UiTranslationController implements Dumpable {
*/ */
public void onActivityDestroyed() { public void onActivityDestroyed() {
synchronized (mLock) { synchronized (mLock) {
if (DEBUG) { Log.i(TAG, "onActivityDestroyed(): mCurrentState is " + stateToString(mCurrentState));
Log.i(TAG,
"onActivityDestroyed(): mCurrentState is " + stateToString(mCurrentState));
}
if (mCurrentState != STATE_UI_TRANSLATION_FINISHED) { if (mCurrentState != STATE_UI_TRANSLATION_FINISHED) {
notifyTranslationFinished(/* activityDestroyed= */ true); notifyTranslationFinished(/* activityDestroyed= */ true);
} }

View File

@@ -210,21 +210,15 @@ final class TranslationManagerServiceImpl extends
final int translatedAppUid = final int translatedAppUid =
getAppUidByComponentName(getContext(), componentName, getUserId()); getAppUidByComponentName(getContext(), componentName, getUserId());
final String packageName = componentName.getPackageName(); final String packageName = componentName.getPackageName();
if (activityDestroyed) { // In the Activity destroyed case, we only call onTranslationFinished() in
// In the Activity destroy case, we only calls onTranslationFinished() in // non-finishTranslation() state. If there is a finishTranslation() call by apps, we
// non-finisTranslation() state. If there is a finisTranslation() calls by apps, we // should remove the waiting callback to avoid invoking callbacks twice.
// should remove the waiting callback to avoid callback twice. if (activityDestroyed || mWaitingFinishedCallbackActivities.contains(token)) {
invokeCallbacks(STATE_UI_TRANSLATION_FINISHED, invokeCallbacks(STATE_UI_TRANSLATION_FINISHED,
/* sourceSpec= */ null, /* targetSpec= */ null, /* sourceSpec= */ null, /* targetSpec= */ null,
packageName, translatedAppUid); packageName, translatedAppUid);
mWaitingFinishedCallbackActivities.remove(token); mWaitingFinishedCallbackActivities.remove(token);
} else { mActiveTranslations.remove(token);
if (mWaitingFinishedCallbackActivities.contains(token)) {
invokeCallbacks(STATE_UI_TRANSLATION_FINISHED,
/* sourceSpec= */ null, /* targetSpec= */ null,
packageName, translatedAppUid);
mWaitingFinishedCallbackActivities.remove(token);
}
} }
} }
@@ -237,6 +231,9 @@ final class TranslationManagerServiceImpl extends
// Activity is the new Activity, the original Activity is paused in the same task. // Activity is the new Activity, the original Activity is paused in the same task.
// To make sure the operation still work, we use the token to find the target Activity in // To make sure the operation still work, we use the token to find the target Activity in
// this task, not the top Activity only. // this task, not the top Activity only.
//
// Note: getAttachedNonFinishingActivityForTask() takes the shareable activity token. We
// call this method so that we can get the regular activity token below.
ActivityTokens candidateActivityTokens = ActivityTokens candidateActivityTokens =
mActivityTaskManagerInternal.getAttachedNonFinishingActivityForTask(taskId, token); mActivityTaskManagerInternal.getAttachedNonFinishingActivityForTask(taskId, token);
if (candidateActivityTokens == null) { if (candidateActivityTokens == null) {
@@ -263,27 +260,27 @@ final class TranslationManagerServiceImpl extends
getAppUidByComponentName(getContext(), componentName, getUserId()); getAppUidByComponentName(getContext(), componentName, getUserId());
String packageName = componentName.getPackageName(); String packageName = componentName.getPackageName();
invokeCallbacksIfNecessaryLocked(state, sourceSpec, targetSpec, packageName, activityToken, invokeCallbacksIfNecessaryLocked(state, sourceSpec, targetSpec, packageName, token,
translatedAppUid); translatedAppUid);
updateActiveTranslationsLocked(state, sourceSpec, targetSpec, packageName, activityToken, updateActiveTranslationsLocked(state, sourceSpec, targetSpec, packageName, token,
translatedAppUid); translatedAppUid);
} }
@GuardedBy("mLock") @GuardedBy("mLock")
private void updateActiveTranslationsLocked(int state, TranslationSpec sourceSpec, private void updateActiveTranslationsLocked(int state, TranslationSpec sourceSpec,
TranslationSpec targetSpec, String packageName, IBinder activityToken, TranslationSpec targetSpec, String packageName, IBinder shareableActivityToken,
int translatedAppUid) { int translatedAppUid) {
// We keep track of active translations and their state so that we can: // We keep track of active translations and their state so that we can:
// 1. Trigger callbacks that are registered after translation has started. // 1. Trigger callbacks that are registered after translation has started.
// See registerUiTranslationStateCallbackLocked(). // See registerUiTranslationStateCallbackLocked().
// 2. NOT trigger callbacks when the state didn't change. // 2. NOT trigger callbacks when the state didn't change.
// See invokeCallbacksIfNecessaryLocked(). // See invokeCallbacksIfNecessaryLocked().
ActiveTranslation activeTranslation = mActiveTranslations.get(activityToken); ActiveTranslation activeTranslation = mActiveTranslations.get(shareableActivityToken);
switch (state) { switch (state) {
case STATE_UI_TRANSLATION_STARTED: { case STATE_UI_TRANSLATION_STARTED: {
if (activeTranslation == null) { if (activeTranslation == null) {
try { try {
activityToken.linkToDeath(this, /* flags= */ 0); shareableActivityToken.linkToDeath(this, /* flags= */ 0);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Failed to call linkToDeath for translated app with uid=" Slog.w(TAG, "Failed to call linkToDeath for translated app with uid="
+ translatedAppUid + "; activity is already dead", e); + translatedAppUid + "; activity is already dead", e);
@@ -294,7 +291,7 @@ final class TranslationManagerServiceImpl extends
packageName, translatedAppUid); packageName, translatedAppUid);
return; return;
} }
mActiveTranslations.put(activityToken, mActiveTranslations.put(shareableActivityToken,
new ActiveTranslation(sourceSpec, targetSpec, translatedAppUid, new ActiveTranslation(sourceSpec, targetSpec, translatedAppUid,
packageName)); packageName));
} }
@@ -317,7 +314,7 @@ final class TranslationManagerServiceImpl extends
case STATE_UI_TRANSLATION_FINISHED: { case STATE_UI_TRANSLATION_FINISHED: {
if (activeTranslation != null) { if (activeTranslation != null) {
mActiveTranslations.remove(activityToken); mActiveTranslations.remove(shareableActivityToken);
} }
break; break;
} }
@@ -332,12 +329,12 @@ final class TranslationManagerServiceImpl extends
@GuardedBy("mLock") @GuardedBy("mLock")
private void invokeCallbacksIfNecessaryLocked(int state, TranslationSpec sourceSpec, private void invokeCallbacksIfNecessaryLocked(int state, TranslationSpec sourceSpec,
TranslationSpec targetSpec, String packageName, IBinder activityToken, TranslationSpec targetSpec, String packageName, IBinder shareableActivityToken,
int translatedAppUid) { int translatedAppUid) {
boolean shouldInvokeCallbacks = true; boolean shouldInvokeCallbacks = true;
int stateForCallbackInvocation = state; int stateForCallbackInvocation = state;
ActiveTranslation activeTranslation = mActiveTranslations.get(activityToken); ActiveTranslation activeTranslation = mActiveTranslations.get(shareableActivityToken);
if (activeTranslation == null) { if (activeTranslation == null) {
if (state != STATE_UI_TRANSLATION_STARTED) { if (state != STATE_UI_TRANSLATION_STARTED) {
shouldInvokeCallbacks = false; shouldInvokeCallbacks = false;
@@ -403,14 +400,6 @@ final class TranslationManagerServiceImpl extends
} }
} }
if (DEBUG) {
Slog.d(TAG,
(shouldInvokeCallbacks ? "" : "NOT ")
+ "Invoking callbacks for translation state="
+ stateForCallbackInvocation + " for app with uid=" + translatedAppUid
+ " packageName=" + packageName);
}
if (shouldInvokeCallbacks) { if (shouldInvokeCallbacks) {
invokeCallbacks(stateForCallbackInvocation, sourceSpec, targetSpec, packageName, invokeCallbacks(stateForCallbackInvocation, sourceSpec, targetSpec, packageName,
translatedAppUid); translatedAppUid);
@@ -448,7 +437,7 @@ final class TranslationManagerServiceImpl extends
pw.println(waitingFinishCallbackSize); pw.println(waitingFinishCallbackSize);
for (IBinder activityToken : mWaitingFinishedCallbackActivities) { for (IBinder activityToken : mWaitingFinishedCallbackActivities) {
pw.print(prefix); pw.print(prefix);
pw.print("activityToken: "); pw.print("shareableActivityToken: ");
pw.println(activityToken); pw.println(activityToken);
} }
} }
@@ -458,7 +447,14 @@ final class TranslationManagerServiceImpl extends
int state, TranslationSpec sourceSpec, TranslationSpec targetSpec, String packageName, int state, TranslationSpec sourceSpec, TranslationSpec targetSpec, String packageName,
int translatedAppUid) { int translatedAppUid) {
Bundle result = createResultForCallback(state, sourceSpec, targetSpec, packageName); Bundle result = createResultForCallback(state, sourceSpec, targetSpec, packageName);
if (mCallbacks.getRegisteredCallbackCount() == 0) { int registeredCallbackCount = mCallbacks.getRegisteredCallbackCount();
if (DEBUG) {
Slog.d(TAG, "Invoking " + registeredCallbackCount + " callbacks for translation state="
+ state + " for app with uid=" + translatedAppUid
+ " packageName=" + packageName);
}
if (registeredCallbackCount == 0) {
return; return;
} }
List<InputMethodInfo> enabledInputMethods = getEnabledInputMethods(); List<InputMethodInfo> enabledInputMethods = getEnabledInputMethods();
@@ -521,8 +517,10 @@ final class TranslationManagerServiceImpl extends
@GuardedBy("mLock") @GuardedBy("mLock")
public void registerUiTranslationStateCallbackLocked(IRemoteCallback callback, int sourceUid) { public void registerUiTranslationStateCallbackLocked(IRemoteCallback callback, int sourceUid) {
mCallbacks.register(callback, sourceUid); mCallbacks.register(callback, sourceUid);
int numActiveTranslations = mActiveTranslations.size();
if (mActiveTranslations.size() == 0) { Slog.i(TAG, "New registered callback for sourceUid=" + sourceUid + " with currently "
+ numActiveTranslations + " active translations");
if (numActiveTranslations == 0) {
return; return;
} }