• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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