Merge "Revert^2 Fix testRegisterComponentCallbacksOnWindowContext flaky" into tm-dev
This commit is contained in:
@@ -165,10 +165,11 @@ public abstract class WindowProviderService extends Service implements WindowPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress the lint because ths is overridden from Context.
|
||||||
@SuppressLint("OnNameExpected")
|
@SuppressLint("OnNameExpected")
|
||||||
@Override
|
@Override
|
||||||
// Suppress the lint because ths is overridden from Context.
|
@Nullable
|
||||||
public @Nullable Object getSystemService(@NonNull String name) {
|
public Object getSystemService(@NonNull String name) {
|
||||||
if (WINDOW_SERVICE.equals(name)) {
|
if (WINDOW_SERVICE.equals(name)) {
|
||||||
return mWindowManager;
|
return mWindowManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
|
|||||||
import static android.window.ConfigurationHelper.isDifferentDisplay;
|
import static android.window.ConfigurationHelper.isDifferentDisplay;
|
||||||
import static android.window.ConfigurationHelper.shouldUpdateResources;
|
import static android.window.ConfigurationHelper.shouldUpdateResources;
|
||||||
|
|
||||||
|
import android.annotation.AnyThread;
|
||||||
import android.annotation.BinderThread;
|
import android.annotation.BinderThread;
|
||||||
import android.annotation.MainThread;
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.IWindowToken;
|
import android.app.IWindowToken;
|
||||||
@@ -40,6 +40,7 @@ import android.view.IWindowManager;
|
|||||||
import android.view.WindowManager.LayoutParams.WindowType;
|
import android.view.WindowManager.LayoutParams.WindowType;
|
||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -68,6 +69,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
|
|
||||||
private IWindowManager mWms;
|
private IWindowManager mWms;
|
||||||
|
|
||||||
|
@GuardedBy("itself")
|
||||||
private final Configuration mConfiguration = new Configuration();
|
private final Configuration mConfiguration = new Configuration();
|
||||||
|
|
||||||
private boolean mShouldDumpConfigForIme;
|
private boolean mShouldDumpConfigForIme;
|
||||||
@@ -91,7 +93,6 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
throw new IllegalStateException("Context is already attached.");
|
throw new IllegalStateException("Context is already attached.");
|
||||||
}
|
}
|
||||||
mContextRef = new WeakReference<>(context);
|
mContextRef = new WeakReference<>(context);
|
||||||
mConfiguration.setTo(context.getResources().getConfiguration());
|
|
||||||
mShouldDumpConfigForIme = Build.IS_DEBUGGABLE
|
mShouldDumpConfigForIme = Build.IS_DEBUGGABLE
|
||||||
&& context instanceof AbstractInputMethodService;
|
&& context instanceof AbstractInputMethodService;
|
||||||
}
|
}
|
||||||
@@ -137,8 +138,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
if (configuration == null) {
|
if (configuration == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mHandler.post(() -> onConfigurationChanged(configuration, displayId,
|
onConfigurationChanged(configuration, displayId, false /* shouldReportConfigChange */);
|
||||||
false /* shouldReportConfigChange */));
|
|
||||||
mAttachToWindowContainer = true;
|
mAttachToWindowContainer = true;
|
||||||
return true;
|
return true;
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -199,8 +199,19 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
*
|
*
|
||||||
* Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control
|
* Similar to {@link #onConfigurationChanged(Configuration, int)}, but adds a flag to control
|
||||||
* whether to dispatch configuration update or not.
|
* whether to dispatch configuration update or not.
|
||||||
|
* <p>
|
||||||
|
* Note that this method must be executed on the main thread if
|
||||||
|
* {@code shouldReportConfigChange} is {@code true}, which is usually from
|
||||||
|
* {@link IWindowToken#onConfigurationChanged(Configuration, int)}
|
||||||
|
* directly, while this method could be run on any thread if it is used to initialize
|
||||||
|
* Context's {@code Configuration} via {@link #attachToDisplayArea(int, int, Bundle)}
|
||||||
|
* or {@link #attachToDisplayContent(int)}.
|
||||||
|
*
|
||||||
|
* @param shouldReportConfigChange {@code true} to indicate that the {@code Configuration}
|
||||||
|
* should be dispatched to listeners.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
@MainThread
|
@AnyThread
|
||||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||||
public void onConfigurationChanged(Configuration newConfig, int newDisplayId,
|
public void onConfigurationChanged(Configuration newConfig, int newDisplayId,
|
||||||
boolean shouldReportConfigChange) {
|
boolean shouldReportConfigChange) {
|
||||||
@@ -208,18 +219,29 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
if (context == null) {
|
if (context == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
|
final boolean displayChanged;
|
||||||
final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
|
final boolean shouldUpdateResources;
|
||||||
newConfig, newConfig /* overrideConfig */, displayChanged,
|
final int diff;
|
||||||
null /* configChanged */);
|
final Configuration currentConfig;
|
||||||
|
|
||||||
|
synchronized (mConfiguration) {
|
||||||
|
displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
|
||||||
|
shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
|
||||||
|
newConfig, newConfig /* overrideConfig */, displayChanged,
|
||||||
|
null /* configChanged */);
|
||||||
|
diff = mConfiguration.diffPublicOnly(newConfig);
|
||||||
|
currentConfig = mShouldDumpConfigForIme ? new Configuration(mConfiguration) : null;
|
||||||
|
if (shouldUpdateResources) {
|
||||||
|
mConfiguration.setTo(newConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!shouldUpdateResources && mShouldDumpConfigForIme) {
|
if (!shouldUpdateResources && mShouldDumpConfigForIme) {
|
||||||
Log.d(TAG, "Configuration not dispatch to IME because configuration is up"
|
Log.d(TAG, "Configuration not dispatch to IME because configuration is up"
|
||||||
+ " to date. Current config=" + context.getResources().getConfiguration()
|
+ " to date. Current config=" + context.getResources().getConfiguration()
|
||||||
+ ", reported config=" + mConfiguration
|
+ ", reported config=" + currentConfig
|
||||||
+ ", updated config=" + newConfig);
|
+ ", updated config=" + newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldUpdateResources) {
|
if (shouldUpdateResources) {
|
||||||
// TODO(ag/9789103): update resource manager logic to track non-activity tokens
|
// TODO(ag/9789103): update resource manager logic to track non-activity tokens
|
||||||
mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
|
mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
|
||||||
@@ -229,7 +251,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
windowContext.dispatchConfigurationChanged(newConfig);
|
windowContext.dispatchConfigurationChanged(newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int diff = mConfiguration.diffPublicOnly(newConfig);
|
|
||||||
if (shouldReportConfigChange && diff != 0
|
if (shouldReportConfigChange && diff != 0
|
||||||
&& context instanceof WindowProviderService) {
|
&& context instanceof WindowProviderService) {
|
||||||
final WindowProviderService windowProviderService = (WindowProviderService) context;
|
final WindowProviderService windowProviderService = (WindowProviderService) context;
|
||||||
@@ -244,11 +266,10 @@ public class WindowTokenClient extends IWindowToken.Stub {
|
|||||||
Log.d(TAG, "Configuration not dispatch to IME because configuration has no "
|
Log.d(TAG, "Configuration not dispatch to IME because configuration has no "
|
||||||
+ " public difference with updated config. "
|
+ " public difference with updated config. "
|
||||||
+ " Current config=" + context.getResources().getConfiguration()
|
+ " Current config=" + context.getResources().getConfiguration()
|
||||||
+ ", reported config=" + mConfiguration
|
+ ", reported config=" + currentConfig
|
||||||
+ ", updated config=" + newConfig);
|
+ ", updated config=" + newConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mConfiguration.setTo(newConfig);
|
|
||||||
}
|
}
|
||||||
if (displayChanged) {
|
if (displayChanged) {
|
||||||
context.updateDisplay(newDisplayId);
|
context.updateDisplay(newDisplayId);
|
||||||
|
|||||||
@@ -637,12 +637,19 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void registerConfigurationChangeListener(ConfigurationContainerListener listener) {
|
void registerConfigurationChangeListener(ConfigurationContainerListener listener) {
|
||||||
|
registerConfigurationChangeListener(listener, true /* shouldDispatchConfig */);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerConfigurationChangeListener(ConfigurationContainerListener listener,
|
||||||
|
boolean shouldDispatchConfig) {
|
||||||
if (mChangeListeners.contains(listener)) {
|
if (mChangeListeners.contains(listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mChangeListeners.add(listener);
|
mChangeListeners.add(listener);
|
||||||
listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
|
if (shouldDispatchConfig) {
|
||||||
listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
|
listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
|
||||||
|
listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
|
void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
|
||||||
|
|||||||
@@ -3747,13 +3747,20 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
}
|
}
|
||||||
|
|
||||||
void registerWindowContainerListener(WindowContainerListener listener) {
|
void registerWindowContainerListener(WindowContainerListener listener) {
|
||||||
|
registerWindowContainerListener(listener, true /* shouldPropConfig */);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerWindowContainerListener(WindowContainerListener listener,
|
||||||
|
boolean shouldDispatchConfig) {
|
||||||
if (mListeners.contains(listener)) {
|
if (mListeners.contains(listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mListeners.add(listener);
|
mListeners.add(listener);
|
||||||
// Also register to ConfigurationChangeListener to receive configuration changes.
|
// Also register to ConfigurationChangeListener to receive configuration changes.
|
||||||
registerConfigurationChangeListener(listener);
|
registerConfigurationChangeListener(listener, shouldDispatchConfig);
|
||||||
listener.onDisplayChanged(getDisplayContent());
|
if (shouldDispatchConfig) {
|
||||||
|
listener.onDisplayChanged(getDisplayContent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterWindowContainerListener(WindowContainerListener listener) {
|
void unregisterWindowContainerListener(WindowContainerListener listener) {
|
||||||
|
|||||||
@@ -68,6 +68,16 @@ class WindowContextListenerController {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>();
|
final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #registerWindowContainerListener(IBinder, WindowContainer, int, int, Bundle, boolean)
|
||||||
|
*/
|
||||||
|
void registerWindowContainerListener(@NonNull IBinder clientToken,
|
||||||
|
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
|
||||||
|
@Nullable Bundle options) {
|
||||||
|
registerWindowContainerListener(clientToken, container, ownerUid, type, options,
|
||||||
|
true /* shouDispatchConfigWhenRegistering */);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the listener to a {@code container} which is associated with
|
* Registers the listener to a {@code container} which is associated with
|
||||||
* a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the
|
* a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the
|
||||||
@@ -80,15 +90,18 @@ class WindowContextListenerController {
|
|||||||
* @param ownerUid the caller UID
|
* @param ownerUid the caller UID
|
||||||
* @param type the window type
|
* @param type the window type
|
||||||
* @param options a bundle used to pass window-related options.
|
* @param options a bundle used to pass window-related options.
|
||||||
|
* @param shouDispatchConfigWhenRegistering {@code true} to indicate the current
|
||||||
|
* {@code container}'s config will dispatch to the client side when
|
||||||
|
* registering the {@link WindowContextListenerImpl}
|
||||||
*/
|
*/
|
||||||
void registerWindowContainerListener(@NonNull IBinder clientToken,
|
void registerWindowContainerListener(@NonNull IBinder clientToken,
|
||||||
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
|
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
|
||||||
@Nullable Bundle options) {
|
@Nullable Bundle options, boolean shouDispatchConfigWhenRegistering) {
|
||||||
WindowContextListenerImpl listener = mListeners.get(clientToken);
|
WindowContextListenerImpl listener = mListeners.get(clientToken);
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type,
|
listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type,
|
||||||
options);
|
options);
|
||||||
listener.register();
|
listener.register(shouDispatchConfigWhenRegistering);
|
||||||
} else {
|
} else {
|
||||||
listener.updateContainer(container);
|
listener.updateContainer(container);
|
||||||
}
|
}
|
||||||
@@ -228,12 +241,16 @@ class WindowContextListenerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void register() {
|
private void register() {
|
||||||
|
register(true /* shouldDispatchConfig */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void register(boolean shouldDispatchConfig) {
|
||||||
final IBinder token = mClientToken.asBinder();
|
final IBinder token = mClientToken.asBinder();
|
||||||
if (mDeathRecipient == null) {
|
if (mDeathRecipient == null) {
|
||||||
throw new IllegalStateException("Invalid client token: " + token);
|
throw new IllegalStateException("Invalid client token: " + token);
|
||||||
}
|
}
|
||||||
mListeners.putIfAbsent(token, this);
|
mListeners.putIfAbsent(token, this);
|
||||||
mContainer.registerWindowContainerListener(this);
|
mContainer.registerWindowContainerListener(this, shouldDispatchConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregister() {
|
private void unregister() {
|
||||||
|
|||||||
@@ -2772,12 +2772,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
}
|
}
|
||||||
// TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
|
// TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
|
||||||
// the feature b/155340867 is completed.
|
// the feature b/155340867 is completed.
|
||||||
final DisplayArea da = dc.findAreaForWindowType(type, options,
|
final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
|
||||||
callerCanManageAppTokens, false /* roundedCornerOverlay */);
|
callerCanManageAppTokens, false /* roundedCornerOverlay */);
|
||||||
// TODO(b/190019118): Avoid to send onConfigurationChanged because it has been done
|
|
||||||
// in return value of attachWindowContextToDisplayArea.
|
|
||||||
mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
|
mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
|
||||||
callingUid, type, options);
|
callingUid, type, options, false /* shouDispatchConfigWhenRegistering */);
|
||||||
return da.getConfiguration();
|
return da.getConfiguration();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -2873,7 +2871,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
|
mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
|
||||||
callingUid, INVALID_WINDOW_TYPE, null /* options */);
|
callingUid, INVALID_WINDOW_TYPE, null /* options */,
|
||||||
|
false /* shouDispatchConfigWhenRegistering */);
|
||||||
return dc.getConfiguration();
|
return dc.getConfiguration();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user