1 /*
2  * Copyright (C) 2019 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.content.res.Configuration;
20 import android.os.RemoteCallbackList;
21 import android.os.RemoteException;
22 import android.util.IntArray;
23 import android.view.IDisplayWindowListener;
24 
25 /**
26  * Manages dispatch of relevant hierarchy changes to interested listeners. Listeners are assumed
27  * to be remote.
28  */
29 class DisplayWindowListenerController {
30     RemoteCallbackList<IDisplayWindowListener> mDisplayListeners = new RemoteCallbackList<>();
31 
32     private final WindowManagerService mService;
33 
DisplayWindowListenerController(WindowManagerService service)34     DisplayWindowListenerController(WindowManagerService service) {
35         mService = service;
36     }
37 
registerListener(IDisplayWindowListener listener)38     int[] registerListener(IDisplayWindowListener listener) {
39         synchronized (mService.mGlobalLock) {
40             mDisplayListeners.register(listener);
41             final IntArray displayIds = new IntArray();
42             mService.mAtmService.mRootWindowContainer.forAllDisplays((displayContent) -> {
43                 displayIds.add(displayContent.mDisplayId);
44             });
45             return displayIds.toArray();
46         }
47     }
48 
unregisterListener(IDisplayWindowListener listener)49     void unregisterListener(IDisplayWindowListener listener) {
50         mDisplayListeners.unregister(listener);
51     }
52 
dispatchDisplayAdded(DisplayContent display)53     void dispatchDisplayAdded(DisplayContent display) {
54         int count = mDisplayListeners.beginBroadcast();
55         for (int i = 0; i < count; ++i) {
56             try {
57                 mDisplayListeners.getBroadcastItem(i).onDisplayAdded(display.mDisplayId);
58             } catch (RemoteException e) {
59             }
60         }
61         mDisplayListeners.finishBroadcast();
62     }
63 
dispatchDisplayChanged(DisplayContent display, Configuration newConfig)64     void dispatchDisplayChanged(DisplayContent display, Configuration newConfig) {
65         // Only report changed if this has actually been added to the hierarchy already.
66         boolean isInHierarchy = false;
67         for (int i = 0; i < display.getParent().getChildCount(); ++i) {
68             if (display.getParent().getChildAt(i) == display) {
69                 isInHierarchy = true;
70             }
71         }
72         if (!isInHierarchy) {
73             return;
74         }
75         int count = mDisplayListeners.beginBroadcast();
76         for (int i = 0; i < count; ++i) {
77             try {
78                 mDisplayListeners.getBroadcastItem(i).onDisplayConfigurationChanged(
79                         display.getDisplayId(), newConfig);
80             } catch (RemoteException e) {
81             }
82         }
83         mDisplayListeners.finishBroadcast();
84     }
85 
dispatchDisplayRemoved(DisplayContent display)86     void dispatchDisplayRemoved(DisplayContent display) {
87         int count = mDisplayListeners.beginBroadcast();
88         for (int i = 0; i < count; ++i) {
89             try {
90                 mDisplayListeners.getBroadcastItem(i).onDisplayRemoved(display.mDisplayId);
91             } catch (RemoteException e) {
92             }
93         }
94         mDisplayListeners.finishBroadcast();
95     }
96 
dispatchFixedRotationStarted(DisplayContent display, int newRotation)97     void dispatchFixedRotationStarted(DisplayContent display, int newRotation) {
98         int count = mDisplayListeners.beginBroadcast();
99         for (int i = 0; i < count; ++i) {
100             try {
101                 mDisplayListeners.getBroadcastItem(i).onFixedRotationStarted(
102                         display.mDisplayId, newRotation);
103             } catch (RemoteException e) {
104             }
105         }
106         mDisplayListeners.finishBroadcast();
107     }
108 
dispatchFixedRotationFinished(DisplayContent display)109     void dispatchFixedRotationFinished(DisplayContent display) {
110         int count = mDisplayListeners.beginBroadcast();
111         for (int i = 0; i < count; ++i) {
112             try {
113                 mDisplayListeners.getBroadcastItem(i).onFixedRotationFinished(display.mDisplayId);
114             } catch (RemoteException e) {
115             }
116         }
117         mDisplayListeners.finishBroadcast();
118     }
119 }
120