Merge changes from topic "b147213487" into rvc-dev am: 8e726a2ef7
Change-Id: Ic8fbd04c2ae5bf57c76476639ad28dea1e560d27
This commit is contained in:
@@ -7151,6 +7151,11 @@ public class Activity extends ContextThemeWrapper
|
||||
writer.println(mChangingConfigurations);
|
||||
writer.print(innerPrefix); writer.print("mCurrentConfig=");
|
||||
writer.println(mCurrentConfig);
|
||||
if (getResources().hasOverrideDisplayAdjustments()) {
|
||||
writer.print(innerPrefix);
|
||||
writer.print("FixedRotationAdjustments=");
|
||||
writer.println(getResources().getDisplayAdjustments().getFixedRotationAdjustments());
|
||||
}
|
||||
|
||||
mFragments.dumpLoaders(innerPrefix, fd, writer, args);
|
||||
mFragments.getFragmentManager().dump(innerPrefix, fd, writer, args);
|
||||
|
||||
@@ -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<Pair<IBinder, Consumer<DisplayAdjustments>>> mActiveRotationAdjustments;
|
||||
|
||||
// Registry of remote cancellation transports pending a reply with reply handles.
|
||||
@GuardedBy("this")
|
||||
private @Nullable Map<SafeCancellationTransport, CancellationSignal> 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<ResultInfo> pendingResults,
|
||||
List<ReferrerIntent> 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<DisplayAdjustments> 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<DisplayAdjustments> 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
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
import android.util.MergedConfiguration;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
@@ -167,6 +168,10 @@ public abstract class ClientTransactionHandler {
|
||||
/** Deliver app configuration change notification. */
|
||||
public abstract void handleConfigurationChanged(Configuration config);
|
||||
|
||||
/** Apply addition adjustments to override display information. */
|
||||
public abstract void handleFixedRotationAdjustments(IBinder token,
|
||||
FixedRotationAdjustments fixedRotationAdjustments);
|
||||
|
||||
/**
|
||||
* Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
|
||||
* provided token.
|
||||
|
||||
@@ -59,6 +59,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/** @hide */
|
||||
@@ -1296,6 +1297,35 @@ public class ResourcesManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the display adjustments of all resources which are associated with the given token.
|
||||
*
|
||||
* @param token The token that owns the resources.
|
||||
* @param override The operation to override the existing display adjustments. If it is null,
|
||||
* the override adjustments will be cleared.
|
||||
* @return {@code true} if the override takes effect.
|
||||
*/
|
||||
public boolean overrideTokenDisplayAdjustments(IBinder token,
|
||||
@Nullable Consumer<DisplayAdjustments> override) {
|
||||
boolean handled = false;
|
||||
synchronized (this) {
|
||||
final ActivityResources tokenResources = mActivityResourceReferences.get(token);
|
||||
if (tokenResources == null) {
|
||||
return false;
|
||||
}
|
||||
final ArrayList<WeakReference<Resources>> resourcesRefs =
|
||||
tokenResources.activityResources;
|
||||
for (int i = resourcesRefs.size() - 1; i >= 0; i--) {
|
||||
final Resources res = resourcesRefs.get(i).get();
|
||||
if (res != null) {
|
||||
res.overrideDisplayAdjustments(override);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
private class UpdateHandler implements Resources.UpdateCallbacks {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app.servertransaction;
|
||||
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The request to update display adjustments for a rotated activity or window token.
|
||||
* @hide
|
||||
*/
|
||||
public class FixedRotationAdjustmentsItem extends ClientTransactionItem {
|
||||
|
||||
/** The token who may have {@link android.content.res.Resources}. */
|
||||
private IBinder mToken;
|
||||
|
||||
/**
|
||||
* The adjustments for the display adjustments of resources. If it is null, the existing
|
||||
* rotation adjustments will be dropped to restore natural state.
|
||||
*/
|
||||
private FixedRotationAdjustments mFixedRotationAdjustments;
|
||||
|
||||
private FixedRotationAdjustmentsItem() {}
|
||||
|
||||
/** Obtain an instance initialized with provided params. */
|
||||
public static FixedRotationAdjustmentsItem obtain(IBinder token,
|
||||
FixedRotationAdjustments fixedRotationAdjustments) {
|
||||
FixedRotationAdjustmentsItem instance =
|
||||
ObjectPool.obtain(FixedRotationAdjustmentsItem.class);
|
||||
if (instance == null) {
|
||||
instance = new FixedRotationAdjustmentsItem();
|
||||
}
|
||||
instance.mToken = token;
|
||||
instance.mFixedRotationAdjustments = fixedRotationAdjustments;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
PendingTransactionActions pendingActions) {
|
||||
client.handleFixedRotationAdjustments(mToken, mFixedRotationAdjustments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
mToken = null;
|
||||
mFixedRotationAdjustments = null;
|
||||
ObjectPool.recycle(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeStrongBinder(mToken);
|
||||
dest.writeTypedObject(mFixedRotationAdjustments, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FixedRotationAdjustmentsItem other = (FixedRotationAdjustmentsItem) o;
|
||||
return Objects.equals(mToken, other.mToken)
|
||||
&& Objects.equals(mFixedRotationAdjustments, other.mFixedRotationAdjustments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + Objects.hashCode(mToken);
|
||||
result = 31 * result + Objects.hashCode(mFixedRotationAdjustments);
|
||||
return result;
|
||||
}
|
||||
|
||||
private FixedRotationAdjustmentsItem(Parcel in) {
|
||||
mToken = in.readStrongBinder();
|
||||
mFixedRotationAdjustments = in.readTypedObject(FixedRotationAdjustments.CREATOR);
|
||||
}
|
||||
|
||||
public static final Creator<FixedRotationAdjustmentsItem> CREATOR =
|
||||
new Creator<FixedRotationAdjustmentsItem>() {
|
||||
public FixedRotationAdjustmentsItem createFromParcel(Parcel in) {
|
||||
return new FixedRotationAdjustmentsItem(in);
|
||||
}
|
||||
|
||||
public FixedRotationAdjustmentsItem[] newArray(int size) {
|
||||
return new FixedRotationAdjustmentsItem[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Trace;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
|
||||
import com.android.internal.app.IVoiceInteractor;
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
@@ -64,6 +65,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
private boolean mIsForward;
|
||||
private ProfilerInfo mProfilerInfo;
|
||||
private IBinder mAssistToken;
|
||||
private FixedRotationAdjustments mFixedRotationAdjustments;
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
@@ -79,7 +81,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
|
||||
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
|
||||
mPendingResults, mPendingNewIntents, mIsForward,
|
||||
mProfilerInfo, client, mAssistToken);
|
||||
mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
|
||||
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -101,14 +103,14 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
|
||||
PersistableBundle persistentState, List<ResultInfo> pendingResults,
|
||||
List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
|
||||
IBinder assistToken) {
|
||||
IBinder assistToken, FixedRotationAdjustments fixedRotationAdjustments) {
|
||||
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
|
||||
if (instance == null) {
|
||||
instance = new LaunchActivityItem();
|
||||
}
|
||||
setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
|
||||
voiceInteractor, procState, state, persistentState, pendingResults,
|
||||
pendingNewIntents, isForward, profilerInfo, assistToken);
|
||||
pendingNewIntents, isForward, profilerInfo, assistToken, fixedRotationAdjustments);
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -116,7 +118,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
@Override
|
||||
public void recycle() {
|
||||
setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
|
||||
false, null, null);
|
||||
false, null, null, null);
|
||||
ObjectPool.recycle(this);
|
||||
}
|
||||
|
||||
@@ -142,6 +144,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
dest.writeBoolean(mIsForward);
|
||||
dest.writeTypedObject(mProfilerInfo, flags);
|
||||
dest.writeStrongBinder(mAssistToken);
|
||||
dest.writeTypedObject(mFixedRotationAdjustments, flags);
|
||||
}
|
||||
|
||||
/** Read from Parcel. */
|
||||
@@ -156,7 +159,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
in.createTypedArrayList(ResultInfo.CREATOR),
|
||||
in.createTypedArrayList(ReferrerIntent.CREATOR), in.readBoolean(),
|
||||
in.readTypedObject(ProfilerInfo.CREATOR),
|
||||
in.readStrongBinder());
|
||||
in.readStrongBinder(),
|
||||
in.readTypedObject(FixedRotationAdjustments.CREATOR));
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<LaunchActivityItem> CREATOR =
|
||||
@@ -192,7 +196,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
&& Objects.equals(mPendingNewIntents, other.mPendingNewIntents)
|
||||
&& mIsForward == other.mIsForward
|
||||
&& Objects.equals(mProfilerInfo, other.mProfilerInfo)
|
||||
&& Objects.equals(mAssistToken, other.mAssistToken);
|
||||
&& Objects.equals(mAssistToken, other.mAssistToken)
|
||||
&& Objects.equals(mFixedRotationAdjustments, other.mFixedRotationAdjustments);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -212,6 +217,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
result = 31 * result + (mIsForward ? 1 : 0);
|
||||
result = 31 * result + Objects.hashCode(mProfilerInfo);
|
||||
result = 31 * result + Objects.hashCode(mAssistToken);
|
||||
result = 31 * result + Objects.hashCode(mFixedRotationAdjustments);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -247,7 +253,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
+ ",referrer=" + mReferrer + ",procState=" + mProcState + ",state=" + mState
|
||||
+ ",persistentState=" + mPersistentState + ",pendingResults=" + mPendingResults
|
||||
+ ",pendingNewIntents=" + mPendingNewIntents + ",profilerInfo=" + mProfilerInfo
|
||||
+ " assistToken=" + mAssistToken
|
||||
+ ",assistToken=" + mAssistToken + ",rotationAdj=" + mFixedRotationAdjustments
|
||||
+ "}";
|
||||
}
|
||||
|
||||
@@ -257,7 +263,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
|
||||
int procState, Bundle state, PersistableBundle persistentState,
|
||||
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
|
||||
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken) {
|
||||
boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
|
||||
FixedRotationAdjustments fixedRotationAdjustments) {
|
||||
instance.mIntent = intent;
|
||||
instance.mIdent = ident;
|
||||
instance.mInfo = info;
|
||||
@@ -274,5 +281,6 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
instance.mIsForward = isForward;
|
||||
instance.mProfilerInfo = profilerInfo;
|
||||
instance.mAssistToken = assistToken;
|
||||
instance.mFixedRotationAdjustments = fixedRotationAdjustments;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Class for accessing an application's resources. This sits on top of the
|
||||
@@ -140,6 +141,9 @@ public class Resources {
|
||||
@UnsupportedAppUsage
|
||||
private DrawableInflater mDrawableInflater;
|
||||
|
||||
/** Used to override the returned adjustments of {@link #getDisplayAdjustments}. */
|
||||
private DisplayAdjustments mOverrideDisplayAdjustments;
|
||||
|
||||
/** Lock object used to protect access to {@link #mTmpValue}. */
|
||||
private final Object mTmpValueLock = new Object();
|
||||
|
||||
@@ -2055,9 +2059,40 @@ public class Resources {
|
||||
/** @hide */
|
||||
@UnsupportedAppUsage
|
||||
public DisplayAdjustments getDisplayAdjustments() {
|
||||
final DisplayAdjustments overrideDisplayAdjustments = mOverrideDisplayAdjustments;
|
||||
if (overrideDisplayAdjustments != null) {
|
||||
return overrideDisplayAdjustments;
|
||||
}
|
||||
return mResourcesImpl.getDisplayAdjustments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the display adjustments based on the current one in {@link #mResourcesImpl}, in
|
||||
* order to isolate the effect with other instances of {@link Resource} that may share the same
|
||||
* instance of {@link ResourcesImpl}.
|
||||
*
|
||||
* @param override The operation to override the existing display adjustments. If it is null,
|
||||
* the override adjustments will be cleared.
|
||||
* @hide
|
||||
*/
|
||||
public void overrideDisplayAdjustments(@Nullable Consumer<DisplayAdjustments> override) {
|
||||
if (override != null) {
|
||||
mOverrideDisplayAdjustments = new DisplayAdjustments(
|
||||
mResourcesImpl.getDisplayAdjustments());
|
||||
override.accept(mOverrideDisplayAdjustments);
|
||||
} else {
|
||||
mOverrideDisplayAdjustments = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the override display adjustments have been set.
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasOverrideDisplayAdjustments() {
|
||||
return mOverrideDisplayAdjustments != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current configuration that is in effect for this resource
|
||||
* object. The returned object should be treated as read-only.
|
||||
|
||||
@@ -103,6 +103,14 @@ public final class Display {
|
||||
private int mCachedAppWidthCompat;
|
||||
private int mCachedAppHeightCompat;
|
||||
|
||||
/**
|
||||
* Indicates that the application is started in a different rotation than the real display, so
|
||||
* the display information may be adjusted. That ensures the methods {@link #getRotation},
|
||||
* {@link #getRealSize}, {@link #getRealMetrics}, and {@link #getCutout} are consistent with how
|
||||
* the application window is laid out.
|
||||
*/
|
||||
private boolean mMayAdjustByFixedRotation;
|
||||
|
||||
/**
|
||||
* The default Display id, which is the id of the primary display assuming there is one.
|
||||
*/
|
||||
@@ -804,7 +812,9 @@ public final class Display {
|
||||
public int getRotation() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.rotation;
|
||||
return mMayAdjustByFixedRotation
|
||||
? getDisplayAdjustments().getRotation(mDisplayInfo.rotation)
|
||||
: mDisplayInfo.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -828,7 +838,9 @@ public final class Display {
|
||||
public DisplayCutout getCutout() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.displayCutout;
|
||||
return mMayAdjustByFixedRotation
|
||||
? getDisplayAdjustments().getDisplayCutout(mDisplayInfo.displayCutout)
|
||||
: mDisplayInfo.displayCutout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1140,6 +1152,9 @@ public final class Display {
|
||||
updateDisplayInfoLocked();
|
||||
outSize.x = mDisplayInfo.logicalWidth;
|
||||
outSize.y = mDisplayInfo.logicalHeight;
|
||||
if (mMayAdjustByFixedRotation) {
|
||||
getDisplayAdjustments().adjustSize(outSize, mDisplayInfo.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,6 +1174,9 @@ public final class Display {
|
||||
updateDisplayInfoLocked();
|
||||
mDisplayInfo.getLogicalMetrics(outMetrics,
|
||||
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
|
||||
if (mMayAdjustByFixedRotation) {
|
||||
getDisplayAdjustments().adjustMetrics(outMetrics, mDisplayInfo.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1225,6 +1243,9 @@ public final class Display {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mMayAdjustByFixedRotation = mResources != null
|
||||
&& mResources.hasOverrideDisplayAdjustments();
|
||||
}
|
||||
|
||||
private void updateCachedAppSizeIfNeededLocked() {
|
||||
@@ -1243,9 +1264,12 @@ public final class Display {
|
||||
public String toString() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
|
||||
final DisplayAdjustments adjustments = getDisplayAdjustments();
|
||||
mDisplayInfo.getAppMetrics(mTempMetrics, adjustments);
|
||||
return "Display id " + mDisplayId + ": " + mDisplayInfo
|
||||
+ ", " + mTempMetrics + ", isValid=" + mIsValid;
|
||||
+ (mMayAdjustByFixedRotation
|
||||
? (", " + adjustments.getFixedRotationAdjustments() + ", ") : ", ")
|
||||
+ mTempMetrics + ", isValid=" + mIsValid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -30,6 +34,7 @@ public class DisplayAdjustments {
|
||||
|
||||
private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
|
||||
private final Configuration mConfiguration = new Configuration(Configuration.EMPTY);
|
||||
private FixedRotationAdjustments mFixedRotationAdjustments;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public DisplayAdjustments() {
|
||||
@@ -44,6 +49,7 @@ public class DisplayAdjustments {
|
||||
public DisplayAdjustments(@NonNull DisplayAdjustments daj) {
|
||||
setCompatibilityInfo(daj.mCompatInfo);
|
||||
mConfiguration.setTo(daj.getConfiguration());
|
||||
mFixedRotationAdjustments = daj.mFixedRotationAdjustments;
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@@ -84,11 +90,78 @@ public class DisplayAdjustments {
|
||||
return mConfiguration;
|
||||
}
|
||||
|
||||
public void setFixedRotationAdjustments(FixedRotationAdjustments fixedRotationAdjustments) {
|
||||
mFixedRotationAdjustments = fixedRotationAdjustments;
|
||||
}
|
||||
|
||||
public FixedRotationAdjustments getFixedRotationAdjustments() {
|
||||
return mFixedRotationAdjustments;
|
||||
}
|
||||
|
||||
/** Returns {@code false} if the width and height of display should swap. */
|
||||
private boolean noFlip(@Surface.Rotation int realRotation) {
|
||||
final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
|
||||
if (rotationAdjustments == null) {
|
||||
return true;
|
||||
}
|
||||
// Check if the delta is rotated by 90 degrees.
|
||||
return (realRotation - rotationAdjustments.mRotation + 4) % 2 == 0;
|
||||
}
|
||||
|
||||
/** Adjusts the given size if possible. */
|
||||
public void adjustSize(@NonNull Point size, @Surface.Rotation int realRotation) {
|
||||
if (noFlip(realRotation)) {
|
||||
return;
|
||||
}
|
||||
final int w = size.x;
|
||||
size.x = size.y;
|
||||
size.y = w;
|
||||
}
|
||||
|
||||
/** Adjusts the given metrics if possible. */
|
||||
public void adjustMetrics(@NonNull DisplayMetrics metrics, @Surface.Rotation int realRotation) {
|
||||
if (noFlip(realRotation)) {
|
||||
return;
|
||||
}
|
||||
int w = metrics.widthPixels;
|
||||
metrics.widthPixels = metrics.heightPixels;
|
||||
metrics.heightPixels = w;
|
||||
|
||||
w = metrics.noncompatWidthPixels;
|
||||
metrics.noncompatWidthPixels = metrics.noncompatHeightPixels;
|
||||
metrics.noncompatHeightPixels = w;
|
||||
|
||||
float x = metrics.xdpi;
|
||||
metrics.xdpi = metrics.ydpi;
|
||||
metrics.ydpi = x;
|
||||
|
||||
x = metrics.noncompatXdpi;
|
||||
metrics.noncompatXdpi = metrics.noncompatYdpi;
|
||||
metrics.noncompatYdpi = x;
|
||||
}
|
||||
|
||||
/** Returns the adjusted cutout if available. Otherwise the original cutout is returned. */
|
||||
@Nullable
|
||||
public DisplayCutout getDisplayCutout(@Nullable DisplayCutout realCutout) {
|
||||
final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
|
||||
return rotationAdjustments != null && rotationAdjustments.mRotatedDisplayCutout != null
|
||||
? rotationAdjustments.mRotatedDisplayCutout
|
||||
: realCutout;
|
||||
}
|
||||
|
||||
/** Returns the adjusted rotation if available. Otherwise the original rotation is returned. */
|
||||
@Surface.Rotation
|
||||
public int getRotation(@Surface.Rotation int realRotation) {
|
||||
final FixedRotationAdjustments rotationAdjustments = mFixedRotationAdjustments;
|
||||
return rotationAdjustments != null ? rotationAdjustments.mRotation : realRotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 17;
|
||||
hash = hash * 31 + Objects.hashCode(mCompatInfo);
|
||||
hash = hash * 31 + Objects.hashCode(mConfiguration);
|
||||
hash = hash * 31 + Objects.hashCode(mFixedRotationAdjustments);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -98,7 +171,82 @@ public class DisplayAdjustments {
|
||||
return false;
|
||||
}
|
||||
DisplayAdjustments daj = (DisplayAdjustments)o;
|
||||
return Objects.equals(daj.mCompatInfo, mCompatInfo) &&
|
||||
Objects.equals(daj.mConfiguration, mConfiguration);
|
||||
return Objects.equals(daj.mCompatInfo, mCompatInfo)
|
||||
&& Objects.equals(daj.mConfiguration, mConfiguration)
|
||||
&& Objects.equals(daj.mFixedRotationAdjustments, mFixedRotationAdjustments);
|
||||
}
|
||||
|
||||
/**
|
||||
* An application can be launched in different rotation than the real display. This class
|
||||
* provides the information to adjust the values returned by {@link #Display}.
|
||||
* @hide
|
||||
*/
|
||||
public static class FixedRotationAdjustments implements Parcelable {
|
||||
/** The application-based rotation. */
|
||||
@Surface.Rotation
|
||||
final int mRotation;
|
||||
|
||||
/** Non-null if the device has cutout. */
|
||||
@Nullable
|
||||
final DisplayCutout mRotatedDisplayCutout;
|
||||
|
||||
public FixedRotationAdjustments(@Surface.Rotation int rotation, DisplayCutout cutout) {
|
||||
mRotation = rotation;
|
||||
mRotatedDisplayCutout = cutout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 17;
|
||||
hash = hash * 31 + mRotation;
|
||||
hash = hash * 31 + Objects.hashCode(mRotatedDisplayCutout);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof FixedRotationAdjustments)) {
|
||||
return false;
|
||||
}
|
||||
final FixedRotationAdjustments other = (FixedRotationAdjustments) o;
|
||||
return mRotation == other.mRotation
|
||||
&& Objects.equals(mRotatedDisplayCutout, other.mRotatedDisplayCutout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FixedRotationAdjustments{rotation=" + Surface.rotationToString(mRotation)
|
||||
+ " cutout=" + mRotatedDisplayCutout + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mRotation);
|
||||
dest.writeTypedObject(
|
||||
new DisplayCutout.ParcelableWrapper(mRotatedDisplayCutout), flags);
|
||||
}
|
||||
|
||||
private FixedRotationAdjustments(Parcel in) {
|
||||
mRotation = in.readInt();
|
||||
final DisplayCutout.ParcelableWrapper cutoutWrapper =
|
||||
in.readTypedObject(DisplayCutout.ParcelableWrapper.CREATOR);
|
||||
mRotatedDisplayCutout = cutoutWrapper != null ? cutoutWrapper.get() : null;
|
||||
}
|
||||
|
||||
public static final Creator<FixedRotationAdjustments> CREATOR =
|
||||
new Creator<FixedRotationAdjustments>() {
|
||||
public FixedRotationAdjustments createFromParcel(Parcel in) {
|
||||
return new FixedRotationAdjustments(in);
|
||||
}
|
||||
|
||||
public FixedRotationAdjustments[] newArray(int size) {
|
||||
return new FixedRotationAdjustments[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +144,12 @@ public class ObjectPoolTests {
|
||||
IBinder assistToken = new Binder();
|
||||
|
||||
LaunchActivityItem emptyItem = LaunchActivityItem.obtain(null, 0, null, null, null, null,
|
||||
null, null, 0, null, null, null, null, false, null, null);
|
||||
null, null, 0, null, null, null, null, false, null, null, null);
|
||||
LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo,
|
||||
config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
|
||||
procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
|
||||
true /* isForward */, null /* profilerInfo */, assistToken);
|
||||
true /* isForward */, null /* profilerInfo */, assistToken,
|
||||
null /* fixedRotationAdjustments */);
|
||||
assertNotSame(item, emptyItem);
|
||||
assertFalse(item.equals(emptyItem));
|
||||
|
||||
@@ -158,7 +159,8 @@ public class ObjectPoolTests {
|
||||
LaunchActivityItem item2 = LaunchActivityItem.obtain(intent, ident, activityInfo,
|
||||
config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
|
||||
procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
|
||||
true /* isForward */, null /* profilerInfo */, assistToken);
|
||||
true /* isForward */, null /* profilerInfo */, assistToken,
|
||||
null /* fixedRotationAdjustments */);
|
||||
assertSame(item, item2);
|
||||
assertFalse(item2.equals(emptyItem));
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ public class TransactionExecutorTests {
|
||||
null /* voiceInteractor */, 0 /* procState */, null /* state */,
|
||||
null /* persistentState */, null /* pendingResults */,
|
||||
null /* pendingNewIntents */, false /* isForward */, null /* profilerInfo */,
|
||||
null /* assistToken*/));
|
||||
null /* assistToken */, null /* fixedRotationAdjustments */));
|
||||
launchTransaction.addCallback(launchItem);
|
||||
mExecutor.execute(launchTransaction);
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ import android.os.PersistableBundle;
|
||||
import android.os.RemoteCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -187,11 +190,14 @@ public class TransactionParcelTests {
|
||||
bundle.putParcelable("data", new ParcelableData(1));
|
||||
PersistableBundle persistableBundle = new PersistableBundle();
|
||||
persistableBundle.putInt("k", 4);
|
||||
FixedRotationAdjustments fixedRotationAdjustments = new FixedRotationAdjustments(
|
||||
Surface.ROTATION_90, DisplayCutout.NO_CUTOUT);
|
||||
|
||||
LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo,
|
||||
config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
|
||||
procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
|
||||
true /* isForward */, null /* profilerInfo */, new Binder());
|
||||
true /* isForward */, null /* profilerInfo */, new Binder(),
|
||||
fixedRotationAdjustments);
|
||||
writeAndPrepareForReading(item);
|
||||
|
||||
// Read from parcel and assert
|
||||
@@ -340,6 +346,22 @@ public class TransactionParcelTests {
|
||||
assertTrue(transaction.equals(result));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedRotationAdjustments() {
|
||||
ClientTransaction transaction = ClientTransaction.obtain(new StubAppThread(),
|
||||
null /* activityToken */);
|
||||
transaction.addCallback(FixedRotationAdjustmentsItem.obtain(new Binder(),
|
||||
new FixedRotationAdjustments(Surface.ROTATION_270, DisplayCutout.NO_CUTOUT)));
|
||||
|
||||
writeAndPrepareForReading(transaction);
|
||||
|
||||
// Read from parcel and assert
|
||||
ClientTransaction result = ClientTransaction.CREATOR.createFromParcel(mParcel);
|
||||
|
||||
assertEquals(transaction.hashCode(), result.hashCode());
|
||||
assertTrue(transaction.equals(result));
|
||||
}
|
||||
|
||||
/** Write to {@link #mParcel} and reset its position to prepare for reading from the start. */
|
||||
private void writeAndPrepareForReading(Parcelable parcelable) {
|
||||
parcelable.writeToParcel(mParcel, 0 /* flags */);
|
||||
|
||||
@@ -259,4 +259,35 @@ public class ResourcesManagerTest extends TestCase {
|
||||
expectedConfig2.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
assertEquals(expectedConfig2, resources2.getConfiguration());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testOverrideDisplayAdjustments() {
|
||||
final int originalOverrideDensity = 200;
|
||||
final int overrideDisplayDensity = 400;
|
||||
final Binder token = new Binder();
|
||||
final Configuration overrideConfig = new Configuration();
|
||||
overrideConfig.densityDpi = originalOverrideDensity;
|
||||
final Resources resources = mResourcesManager.createBaseTokenResources(
|
||||
token, APP_ONE_RES_DIR, null /* splitResDirs */, null /* overlayDirs */,
|
||||
null /* libDirs */, Display.DEFAULT_DISPLAY, overrideConfig,
|
||||
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* classLoader */,
|
||||
null /* loaders */);
|
||||
|
||||
// Update the override.
|
||||
boolean handled = mResourcesManager.overrideTokenDisplayAdjustments(token,
|
||||
adjustments -> adjustments.getConfiguration().densityDpi = overrideDisplayDensity);
|
||||
|
||||
assertTrue(handled);
|
||||
assertTrue(resources.hasOverrideDisplayAdjustments());
|
||||
assertEquals(overrideDisplayDensity,
|
||||
resources.getDisplayAdjustments().getConfiguration().densityDpi);
|
||||
|
||||
// Clear the override.
|
||||
handled = mResourcesManager.overrideTokenDisplayAdjustments(token, null /* override */);
|
||||
|
||||
assertTrue(handled);
|
||||
assertFalse(resources.hasOverrideDisplayAdjustments());
|
||||
assertEquals(originalOverrideDensity,
|
||||
resources.getDisplayAdjustments().getConfiguration().densityDpi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ package android.view;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
@@ -67,4 +70,38 @@ public class DisplayAdjustmentsTests {
|
||||
|
||||
assertEquals(configuration, newAdjustments.getConfiguration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedRotationAdjustments() {
|
||||
final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
|
||||
final int realRotation = Surface.ROTATION_0;
|
||||
final int fixedRotation = Surface.ROTATION_90;
|
||||
|
||||
mDisplayAdjustments.setFixedRotationAdjustments(
|
||||
new FixedRotationAdjustments(fixedRotation, null /* cutout */));
|
||||
|
||||
final int w = 1000;
|
||||
final int h = 2000;
|
||||
final Point size = new Point(w, h);
|
||||
mDisplayAdjustments.adjustSize(size, realRotation);
|
||||
|
||||
assertEquals(fixedRotation, mDisplayAdjustments.getRotation(realRotation));
|
||||
assertEquals(new Point(h, w), size);
|
||||
|
||||
final DisplayMetrics metrics = new DisplayMetrics();
|
||||
metrics.xdpi = metrics.noncompatXdpi = w;
|
||||
metrics.widthPixels = metrics.noncompatWidthPixels = w;
|
||||
metrics.ydpi = metrics.noncompatYdpi = h;
|
||||
metrics.heightPixels = metrics.noncompatHeightPixels = h;
|
||||
|
||||
final DisplayMetrics flippedMetrics = new DisplayMetrics();
|
||||
flippedMetrics.xdpi = flippedMetrics.noncompatXdpi = h;
|
||||
flippedMetrics.widthPixels = flippedMetrics.noncompatWidthPixels = h;
|
||||
flippedMetrics.ydpi = flippedMetrics.noncompatYdpi = w;
|
||||
flippedMetrics.heightPixels = flippedMetrics.noncompatHeightPixels = w;
|
||||
|
||||
mDisplayAdjustments.adjustMetrics(metrics, realRotation);
|
||||
|
||||
assertEquals(flippedMetrics, metrics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,8 @@ public class ActivityThreadClientTest {
|
||||
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* referrer */,
|
||||
null /* voiceInteractor */, null /* state */, null /* persistentState */,
|
||||
null /* pendingResults */, null /* pendingNewIntents */, true /* isForward */,
|
||||
null /* profilerInfo */, mThread /* client */, null /* asssitToken */);
|
||||
null /* profilerInfo */, mThread /* client */, null /* asssitToken */,
|
||||
null /* fixedRotationAdjustments */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -842,7 +842,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
|
||||
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
|
||||
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
|
||||
r.assistToken));
|
||||
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
|
||||
|
||||
// Set desired final state.
|
||||
final ActivityLifecycleItem lifecycleItem;
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.wm;
|
||||
import static android.os.Process.INVALID_UID;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
|
||||
|
||||
@@ -40,6 +41,7 @@ import static com.android.server.wm.WindowTokenProto.WINDOW_CONTAINER;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.app.IWindowToken;
|
||||
import android.app.servertransaction.FixedRotationAdjustmentsItem;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
@@ -47,6 +49,7 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.DisplayAdjustments.FixedRotationAdjustments;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.InsetsState;
|
||||
import android.view.SurfaceControl;
|
||||
@@ -529,6 +532,7 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
|
||||
insetsState, new Configuration(config), mDisplayContent.getRotation());
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
notifyFixedRotationTransform(true /* enabled */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,6 +550,7 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
mFixedRotationTransformState = fixedRotationState;
|
||||
fixedRotationState.mAssociatedTokens.add(this);
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
notifyFixedRotationTransform(true /* enabled */);
|
||||
}
|
||||
|
||||
void finishFixedRotationTransform() {
|
||||
@@ -578,9 +583,52 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
// The state is cleared at the end, because it is used to indicate that other windows can
|
||||
// use seamless rotation when applying rotation to display.
|
||||
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
|
||||
state.mAssociatedTokens.get(i).mFixedRotationTransformState = null;
|
||||
state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState();
|
||||
}
|
||||
cleanUpFixedRotationTransformState();
|
||||
}
|
||||
|
||||
private void cleanUpFixedRotationTransformState() {
|
||||
mFixedRotationTransformState = null;
|
||||
notifyFixedRotationTransform(false /* enabled */);
|
||||
}
|
||||
|
||||
/** Notifies application side to enable or disable the rotation adjustment of display info. */
|
||||
private void notifyFixedRotationTransform(boolean enabled) {
|
||||
FixedRotationAdjustments adjustments = null;
|
||||
// A token may contain windows of the same processes or different processes. The list is
|
||||
// used to avoid sending the same adjustments to a process multiple times.
|
||||
ArrayList<WindowProcessController> notifiedProcesses = null;
|
||||
for (int i = mChildren.size() - 1; i >= 0; i--) {
|
||||
final WindowState w = mChildren.get(i);
|
||||
final WindowProcessController app;
|
||||
if (w.mAttrs.type == TYPE_APPLICATION_STARTING) {
|
||||
// Use the host activity because starting window is controlled by window manager.
|
||||
final ActivityRecord r = asActivityRecord();
|
||||
if (r == null) {
|
||||
continue;
|
||||
}
|
||||
app = r.app;
|
||||
} else {
|
||||
app = mWmService.mAtmService.mProcessMap.getProcess(w.mSession.mPid);
|
||||
}
|
||||
if (app == null || !app.hasThread()) {
|
||||
continue;
|
||||
}
|
||||
if (notifiedProcesses == null) {
|
||||
notifiedProcesses = new ArrayList<>(2);
|
||||
adjustments = enabled ? createFixedRotationAdjustmentsIfNeeded() : null;
|
||||
} else if (notifiedProcesses.contains(app)) {
|
||||
continue;
|
||||
}
|
||||
notifiedProcesses.add(app);
|
||||
try {
|
||||
mWmService.mAtmService.getLifecycleManager().scheduleTransaction(
|
||||
app.getThread(), FixedRotationAdjustmentsItem.obtain(token, adjustments));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Failed to schedule DisplayAdjustmentsItem to " + app, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Restores the changes that applies to this container. */
|
||||
@@ -590,6 +638,7 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
// The window may be detached or detaching.
|
||||
return;
|
||||
}
|
||||
notifyFixedRotationTransform(false /* enabled */);
|
||||
final int originalRotation = getWindowConfiguration().getRotation();
|
||||
onConfigurationChanged(parent.getConfiguration());
|
||||
onCancelFixedRotationTransform(originalRotation);
|
||||
@@ -603,6 +652,14 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
void onCancelFixedRotationTransform(int originalDisplayRotation) {
|
||||
}
|
||||
|
||||
FixedRotationAdjustments createFixedRotationAdjustmentsIfNeeded() {
|
||||
if (!isFixedRotationTransforming()) {
|
||||
return null;
|
||||
}
|
||||
return new FixedRotationAdjustments(mFixedRotationTransformState.mDisplayInfo.rotation,
|
||||
mFixedRotationTransformState.mDisplayInfo.displayCutout);
|
||||
}
|
||||
|
||||
@Override
|
||||
void resolveOverrideConfiguration(Configuration newParentConfig) {
|
||||
super.resolveOverrideConfiguration(newParentConfig);
|
||||
|
||||
Reference in New Issue
Block a user