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