1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.util.Slog; 22 import android.view.Display; 23 import android.view.Surface; 24 25 import com.android.internal.annotations.VisibleForTesting; 26 27 /** 28 * Singleton for coordinating rotation across multiple displays. Used to notify non-default 29 * displays when the default display rotates. 30 * 31 * Note that this class does not need locking because it is always protected by WindowManagerService 32 * mGlobalLock. 33 */ 34 class DisplayRotationCoordinator { 35 36 private static final String TAG = "DisplayRotationCoordinator"; 37 38 @Surface.Rotation 39 private int mDefaultDisplayDefaultRotation; 40 41 @Nullable 42 @VisibleForTesting 43 Runnable mDefaultDisplayRotationChangedCallback; 44 private int mCallbackDisplayId = Display.INVALID_DISPLAY; 45 46 @Surface.Rotation 47 private int mDefaultDisplayCurrentRotation; 48 49 /** 50 * Notifies clients when the default display rotation changes. 51 */ onDefaultDisplayRotationChanged(@urface.Rotation int rotation)52 void onDefaultDisplayRotationChanged(@Surface.Rotation int rotation) { 53 mDefaultDisplayCurrentRotation = rotation; 54 55 if (mDefaultDisplayRotationChangedCallback != null) { 56 mDefaultDisplayRotationChangedCallback.run(); 57 } 58 } 59 setDefaultDisplayDefaultRotation(@urface.Rotation int rotation)60 void setDefaultDisplayDefaultRotation(@Surface.Rotation int rotation) { 61 mDefaultDisplayDefaultRotation = rotation; 62 } 63 64 @Surface.Rotation getDefaultDisplayCurrentRotation()65 int getDefaultDisplayCurrentRotation() { 66 return mDefaultDisplayCurrentRotation; 67 } 68 69 /** 70 * Register a callback to be notified when the default display's rotation changes. Clients can 71 * query the default display's current rotation via {@link #getDefaultDisplayCurrentRotation()}. 72 */ setDefaultDisplayRotationChangedCallback(int displayId, @NonNull Runnable callback)73 void setDefaultDisplayRotationChangedCallback(int displayId, @NonNull Runnable callback) { 74 if (mDefaultDisplayRotationChangedCallback != null && displayId != mCallbackDisplayId) { 75 throw new UnsupportedOperationException("Multiple clients unsupported" 76 + ". Incoming displayId: " + displayId 77 + ", existing displayId: " + mCallbackDisplayId); 78 } 79 80 mDefaultDisplayRotationChangedCallback = callback; 81 mCallbackDisplayId = displayId; 82 83 if (mDefaultDisplayCurrentRotation != mDefaultDisplayDefaultRotation) { 84 callback.run(); 85 } 86 } 87 88 /** 89 * Removes the callback that was added via 90 * {@link #setDefaultDisplayRotationChangedCallback(int, Runnable)}. 91 */ removeDefaultDisplayRotationChangedCallback(@onNull Runnable callback)92 void removeDefaultDisplayRotationChangedCallback(@NonNull Runnable callback) { 93 if (callback != mDefaultDisplayRotationChangedCallback) { 94 Slog.w(TAG, "Attempted to remove non-matching callback." 95 + " DisplayId: " + mCallbackDisplayId); 96 return; 97 } 98 99 mDefaultDisplayRotationChangedCallback = null; 100 mCallbackDisplayId = Display.INVALID_DISPLAY; 101 } 102 isSecondaryInternalDisplay(@onNull DisplayContent displayContent)103 static boolean isSecondaryInternalDisplay(@NonNull DisplayContent displayContent) { 104 if (displayContent.isDefaultDisplay) { 105 return false; 106 } else if (displayContent.mDisplay == null) { 107 return false; 108 } 109 return displayContent.mDisplay.getType() == Display.TYPE_INTERNAL; 110 } 111 } 112