From d490c57905bc47a4d583d69049864e6348171c61 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 17 Apr 2020 01:39:27 +0800 Subject: Send fixed rotation adjustments to the associated client So the real information of display can be adjusted according to the adjustments for the application started with fixed rotation transform. The enabling adjustments may be sent in different ways: - Launch activity The information is bundled with LaunchActivityItem. - Resume activity or update non-activity window Send a standalone FixedRotationAdjustmentsItem. The disabling adjustments (null) are always sent by FixedRotationAdjustmentsItem. Bug: 147213487 Test: AppConfigurationTests#testRotatedInfoWithFixedRotationTransform TransactionParcelTests#testFixedRotationAdjustments Change-Id: I5238888a5c8352db83fc12749f4de2bfabf46026 --- core/java/android/app/ActivityThread.java | 60 ++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'core/java/android/app/ActivityThread.java') diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index e97ebd7eee06..778fa61ca298 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -156,6 +156,8 @@ import android.util.proto.ProtoOutputStream; import android.view.Choreographer; import android.view.ContextThemeWrapper; import android.view.Display; +import android.view.DisplayAdjustments; +import android.view.DisplayAdjustments.FixedRotationAdjustments; import android.view.ThreadedRenderer; import android.view.View; import android.view.ViewDebug; @@ -215,6 +217,7 @@ import java.util.Objects; import java.util.TimeZone; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; final class RemoteServiceException extends AndroidRuntimeException { public RemoteServiceException(String msg) { @@ -405,6 +408,9 @@ public final class ActivityThread extends ClientTransactionHandler { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final ResourcesManager mResourcesManager; + /** The active adjustments that override the {@link DisplayAdjustments} in resources. */ + private ArrayList>> mActiveRotationAdjustments; + // Registry of remote cancellation transports pending a reply with reply handles. @GuardedBy("this") private @Nullable Map mRemoteCancellations; @@ -541,6 +547,12 @@ public final class ActivityThread extends ClientTransactionHandler { @UnsupportedAppUsage boolean mPreserveWindow; + /** + * If non-null, the activity is launching with a specified rotation, the adjustments should + * be consumed before activity creation. + */ + FixedRotationAdjustments mPendingFixedRotationAdjustments; + @LifecycleState private int mLifecycleState = PRE_ON_CREATE; @@ -557,7 +569,7 @@ public final class ActivityThread extends ClientTransactionHandler { PersistableBundle persistentState, List pendingResults, List pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo, ClientTransactionHandler client, - IBinder assistToken) { + IBinder assistToken, FixedRotationAdjustments fixedRotationAdjustments) { this.token = token; this.assistToken = assistToken; this.ident = ident; @@ -575,6 +587,7 @@ public final class ActivityThread extends ClientTransactionHandler { this.overrideConfig = overrideConfig; this.packageInfo = client.getPackageInfoNoCheck(activityInfo.applicationInfo, compatInfo); + mPendingFixedRotationAdjustments = fixedRotationAdjustments; init(); } @@ -3233,6 +3246,44 @@ public final class ActivityThread extends ClientTransactionHandler { sendMessage(H.CLEAN_UP_CONTEXT, cci); } + @Override + public void handleFixedRotationAdjustments(@NonNull IBinder token, + @Nullable FixedRotationAdjustments fixedRotationAdjustments) { + final Consumer override = fixedRotationAdjustments != null + ? displayAdjustments -> displayAdjustments.setFixedRotationAdjustments( + fixedRotationAdjustments) + : null; + if (!mResourcesManager.overrideTokenDisplayAdjustments(token, override)) { + // No resources are associated with the token. + return; + } + if (mActivities.get(token) == null) { + // Only apply the override to application for activity token because the appearance of + // activity is usually more sensitive to the application resources. + return; + } + + // Apply the last override to application resources for compatibility. Because the Resources + // of Display can be from application, e.g. + // applicationContext.getSystemService(DisplayManager.class).getDisplay(displayId) + // and the deprecated usage: + // applicationContext.getSystemService(WindowManager.class).getDefaultDisplay(); + final Consumer appOverride; + if (mActiveRotationAdjustments == null) { + mActiveRotationAdjustments = new ArrayList<>(2); + } + if (override != null) { + mActiveRotationAdjustments.add(Pair.create(token, override)); + appOverride = override; + } else { + mActiveRotationAdjustments.removeIf(adjustmentsPair -> adjustmentsPair.first == token); + appOverride = mActiveRotationAdjustments.isEmpty() + ? null + : mActiveRotationAdjustments.get(mActiveRotationAdjustments.size() - 1).second; + } + mInitialApplication.getResources().overrideDisplayAdjustments(appOverride); + } + /** Core implementation of activity launch. */ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; @@ -3446,6 +3497,13 @@ public final class ActivityThread extends ClientTransactionHandler { ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); + // The rotation adjustments must be applied before creating the activity, so the activity + // can get the adjusted display info during creation. + if (r.mPendingFixedRotationAdjustments != null) { + handleFixedRotationAdjustments(r.token, r.mPendingFixedRotationAdjustments); + r.mPendingFixedRotationAdjustments = null; + } + final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); // For debugging purposes, if the activity's package name contains the value of // the "debug.use-second-display" system property as a substring, then show -- cgit v1.2.3