Loading core/java/android/app/servertransaction/ClientTransactionListenerController.java +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static com.android.window.flags.Flags.bundleClientTransactionFlag; import static java.util.Objects.requireNonNull; import android.annotation.AnyThread; import android.annotation.MainThread; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityThread; Loading Loading @@ -94,6 +96,7 @@ public class ClientTransactionListenerController { * The listener will be invoked with two parameters: {@link Activity#getActivityToken()} and * {@link ActivityWindowInfo}. */ @AnyThread public void registerActivityWindowInfoChangedListener( @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) { if (!activityWindowInfoFlag()) { Loading @@ -108,6 +111,7 @@ public class ClientTransactionListenerController { * Unregisters the listener that was previously registered via * {@link #registerActivityWindowInfoChangedListener(BiConsumer)} */ @AnyThread public void unregisterActivityWindowInfoChangedListener( @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) { if (!activityWindowInfoFlag()) { Loading @@ -122,6 +126,7 @@ public class ClientTransactionListenerController { * Called when receives a {@link ClientTransaction} that is updating an activity's * {@link ActivityWindowInfo}. */ @MainThread public void onActivityWindowInfoChanged(@NonNull IBinder activityToken, @NonNull ActivityWindowInfo activityWindowInfo) { if (!activityWindowInfoFlag()) { Loading @@ -141,17 +146,20 @@ public class ClientTransactionListenerController { } /** Called when starts executing a remote {@link ClientTransaction}. */ @MainThread public void onClientTransactionStarted() { mIsClientTransactionExecuting = true; } /** Called when finishes executing a remote {@link ClientTransaction}. */ @MainThread public void onClientTransactionFinished() { notifyDisplayManagerIfNeeded(); mIsClientTransactionExecuting = false; } /** Called before updating the Configuration of the given {@code context}. */ @MainThread public void onContextConfigurationPreChanged(@NonNull Context context) { if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) { // Not enable for system server. Loading @@ -166,6 +174,7 @@ public class ClientTransactionListenerController { } /** Called after updating the Configuration of the given {@code context}. */ @MainThread public void onContextConfigurationPostChanged(@NonNull Context context) { if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) { // Not enable for system server. Loading core/java/android/window/WindowTokenClient.java +23 −7 Original line number Diff line number Diff line Loading @@ -144,17 +144,26 @@ public class WindowTokenClient extends Binder { if (context == null) { return; } if (shouldReportConfigChange) { // Only report to ClientTransactionListenerController when shouldReportConfigChange, // which is on the MainThread. final ClientTransactionListenerController controller = ClientTransactionListenerController.getInstance(); getClientTransactionListenerController(); controller.onContextConfigurationPreChanged(context); try { onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); } finally { controller.onContextConfigurationPostChanged(context); } } else { onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); } } private void onConfigurationChangedInner(@NonNull Context context, /** Handles onConfiguration changed. */ @VisibleForTesting public void onConfigurationChangedInner(@NonNull Context context, @NonNull Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { CompatibilityInfo.applyOverrideScaleIfNeeded(newConfig); final boolean displayChanged; Loading Loading @@ -233,4 +242,11 @@ public class WindowTokenClient extends Binder { mContextRef.clear(); } } /** Gets {@link ClientTransactionListenerController}. */ @VisibleForTesting @NonNull public ClientTransactionListenerController getClientTransactionListenerController() { return ClientTransactionListenerController.getInstance(); } } core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -23,15 +23,19 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; Loading @@ -45,6 +49,7 @@ import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.view.DisplayInfo; import android.window.ActivityWindowInfo; import android.window.WindowTokenClient; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; Loading @@ -55,6 +60,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading Loading @@ -180,4 +186,36 @@ public class ClientTransactionListenerControllerTest { verify(mActivityWindowInfoListener, never()).accept(any(), any()); } @Test public void testWindowTokenClient_onConfigurationChanged() { doNothing().when(mController).onContextConfigurationPreChanged(any()); doNothing().when(mController).onContextConfigurationPostChanged(any()); final WindowTokenClient windowTokenClient = spy(new WindowTokenClient()); final Context context = mock(Context.class); windowTokenClient.attachContext(context); doReturn(mController).when(windowTokenClient).getClientTransactionListenerController(); doNothing().when(windowTokenClient).onConfigurationChangedInner(any(), any(), anyInt(), anyBoolean()); // Not trigger when shouldReportConfigChange is false. windowTokenClient.onConfigurationChanged(mConfiguration, 123 /* newDisplayId */, false /* shouldReportConfigChange*/); verify(mController, never()).onContextConfigurationPreChanged(any()); verify(mController, never()).onContextConfigurationPostChanged(any()); // Trigger in order when shouldReportConfigChange is true. clearInvocations(windowTokenClient); final InOrder inOrder = inOrder(mController, windowTokenClient); windowTokenClient.onConfigurationChanged(mConfiguration, 123 /* newDisplayId */, true /* shouldReportConfigChange*/); inOrder.verify(mController).onContextConfigurationPreChanged(context); inOrder.verify(windowTokenClient).onConfigurationChangedInner(context, mConfiguration, 123 /* newDisplayId */, true /* shouldReportConfigChange*/); inOrder.verify(mController).onContextConfigurationPostChanged(context); } } Loading
core/java/android/app/servertransaction/ClientTransactionListenerController.java +9 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static com.android.window.flags.Flags.bundleClientTransactionFlag; import static java.util.Objects.requireNonNull; import android.annotation.AnyThread; import android.annotation.MainThread; import android.annotation.NonNull; import android.app.Activity; import android.app.ActivityThread; Loading Loading @@ -94,6 +96,7 @@ public class ClientTransactionListenerController { * The listener will be invoked with two parameters: {@link Activity#getActivityToken()} and * {@link ActivityWindowInfo}. */ @AnyThread public void registerActivityWindowInfoChangedListener( @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) { if (!activityWindowInfoFlag()) { Loading @@ -108,6 +111,7 @@ public class ClientTransactionListenerController { * Unregisters the listener that was previously registered via * {@link #registerActivityWindowInfoChangedListener(BiConsumer)} */ @AnyThread public void unregisterActivityWindowInfoChangedListener( @NonNull BiConsumer<IBinder, ActivityWindowInfo> listener) { if (!activityWindowInfoFlag()) { Loading @@ -122,6 +126,7 @@ public class ClientTransactionListenerController { * Called when receives a {@link ClientTransaction} that is updating an activity's * {@link ActivityWindowInfo}. */ @MainThread public void onActivityWindowInfoChanged(@NonNull IBinder activityToken, @NonNull ActivityWindowInfo activityWindowInfo) { if (!activityWindowInfoFlag()) { Loading @@ -141,17 +146,20 @@ public class ClientTransactionListenerController { } /** Called when starts executing a remote {@link ClientTransaction}. */ @MainThread public void onClientTransactionStarted() { mIsClientTransactionExecuting = true; } /** Called when finishes executing a remote {@link ClientTransaction}. */ @MainThread public void onClientTransactionFinished() { notifyDisplayManagerIfNeeded(); mIsClientTransactionExecuting = false; } /** Called before updating the Configuration of the given {@code context}. */ @MainThread public void onContextConfigurationPreChanged(@NonNull Context context) { if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) { // Not enable for system server. Loading @@ -166,6 +174,7 @@ public class ClientTransactionListenerController { } /** Called after updating the Configuration of the given {@code context}. */ @MainThread public void onContextConfigurationPostChanged(@NonNull Context context) { if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) { // Not enable for system server. Loading
core/java/android/window/WindowTokenClient.java +23 −7 Original line number Diff line number Diff line Loading @@ -144,17 +144,26 @@ public class WindowTokenClient extends Binder { if (context == null) { return; } if (shouldReportConfigChange) { // Only report to ClientTransactionListenerController when shouldReportConfigChange, // which is on the MainThread. final ClientTransactionListenerController controller = ClientTransactionListenerController.getInstance(); getClientTransactionListenerController(); controller.onContextConfigurationPreChanged(context); try { onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); } finally { controller.onContextConfigurationPostChanged(context); } } else { onConfigurationChangedInner(context, newConfig, newDisplayId, shouldReportConfigChange); } } private void onConfigurationChangedInner(@NonNull Context context, /** Handles onConfiguration changed. */ @VisibleForTesting public void onConfigurationChangedInner(@NonNull Context context, @NonNull Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) { CompatibilityInfo.applyOverrideScaleIfNeeded(newConfig); final boolean displayChanged; Loading Loading @@ -233,4 +242,11 @@ public class WindowTokenClient extends Binder { mContextRef.clear(); } } /** Gets {@link ClientTransactionListenerController}. */ @VisibleForTesting @NonNull public ClientTransactionListenerController getClientTransactionListenerController() { return ClientTransactionListenerController.getInstance(); } }
core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -23,15 +23,19 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; Loading @@ -45,6 +49,7 @@ import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.view.DisplayInfo; import android.window.ActivityWindowInfo; import android.window.WindowTokenClient; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; Loading @@ -55,6 +60,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading Loading @@ -180,4 +186,36 @@ public class ClientTransactionListenerControllerTest { verify(mActivityWindowInfoListener, never()).accept(any(), any()); } @Test public void testWindowTokenClient_onConfigurationChanged() { doNothing().when(mController).onContextConfigurationPreChanged(any()); doNothing().when(mController).onContextConfigurationPostChanged(any()); final WindowTokenClient windowTokenClient = spy(new WindowTokenClient()); final Context context = mock(Context.class); windowTokenClient.attachContext(context); doReturn(mController).when(windowTokenClient).getClientTransactionListenerController(); doNothing().when(windowTokenClient).onConfigurationChangedInner(any(), any(), anyInt(), anyBoolean()); // Not trigger when shouldReportConfigChange is false. windowTokenClient.onConfigurationChanged(mConfiguration, 123 /* newDisplayId */, false /* shouldReportConfigChange*/); verify(mController, never()).onContextConfigurationPreChanged(any()); verify(mController, never()).onContextConfigurationPostChanged(any()); // Trigger in order when shouldReportConfigChange is true. clearInvocations(windowTokenClient); final InOrder inOrder = inOrder(mController, windowTokenClient); windowTokenClient.onConfigurationChanged(mConfiguration, 123 /* newDisplayId */, true /* shouldReportConfigChange*/); inOrder.verify(mController).onContextConfigurationPreChanged(context); inOrder.verify(windowTokenClient).onConfigurationChangedInner(context, mConfiguration, 123 /* newDisplayId */, true /* shouldReportConfigChange*/); inOrder.verify(mController).onContextConfigurationPostChanged(context); } }