1bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/* 2bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Copyright (C) 2012 The Android Open Source Project 3bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 4bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * you may not use this file except in compliance with the License. 6bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * You may obtain a copy of the License at 7bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 8bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 10bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Unless required by applicable law or agreed to in writing, software 11bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * See the License for the specific language governing permissions and 14bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * limitations under the License. 15bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 16bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 17bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownpackage android.hardware.display; 18bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 19bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.content.Context; 20bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.DisplayManager.DisplayListener; 21bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Handler; 22bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.IBinder; 23bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Looper; 24bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Message; 25bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.RemoteException; 26bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.ServiceManager; 27bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.Log; 28bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.SparseArray; 29bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.CompatibilityInfoHolder; 30bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Display; 31bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.DisplayInfo; 32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 33bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.ArrayList; 34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 35bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/** 36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Manager communication with the display manager service on behalf of 37bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * an application process. You're probably looking for {@link DisplayManager}. 38bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 39bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @hide 40bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 41bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownpublic final class DisplayManagerGlobal { 42bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static final String TAG = "DisplayManager"; 43bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static final boolean DEBUG = false; 44bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // True if display info and display ids should be cached. 464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // 474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // FIXME: The cache is currently disabled because it's unclear whether we have the 484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // necessary guarantees that the caches will always be flushed before clients 494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // attempt to observe their new state. For example, depending on the order 504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // in which the binder transactions take place, we might have a problem where 514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // an application could start processing a configuration change due to a display 524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // orientation change before the display info cache has actually been invalidated. 534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final boolean USE_CACHE = false; 544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 55bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public static final int EVENT_DISPLAY_ADDED = 1; 56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public static final int EVENT_DISPLAY_CHANGED = 2; 57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public static final int EVENT_DISPLAY_REMOVED = 3; 58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static DisplayManagerGlobal sInstance; 60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private final Object mLock = new Object(); 62bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 63bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private final IDisplayManager mDm; 64bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 65bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private DisplayManagerCallback mCallback; 66bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private final ArrayList<DisplayListenerDelegate> mDisplayListeners = 67bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown new ArrayList<DisplayListenerDelegate>(); 68bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 69bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<DisplayInfo>(); 70bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private int[] mDisplayIdCache; 71bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 72bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private DisplayManagerGlobal(IDisplayManager dm) { 73bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mDm = dm; 74bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 75bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 76bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown /** 77bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Gets an instance of the display manager global singleton. 78bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 79bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @return The display manager instance, may be null early in system startup 80bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * before the display manager has been fully initialized. 81bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 82bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public static DisplayManagerGlobal getInstance() { 83bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (DisplayManagerGlobal.class) { 84bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (sInstance == null) { 85bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE); 86bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (b != null) { 87bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b)); 88bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 89bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 90bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return sInstance; 91bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 92bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 93bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 94bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown /** 95bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Get information about a particular logical display. 96bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 97bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @param displayId The logical display id. 98bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @return Information about the specified display, or null if it does not exist. 99bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * This object belongs to an internal cache and should be treated as if it were immutable. 100bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 101bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public DisplayInfo getDisplayInfo(int displayId) { 102bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown try { 103bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (mLock) { 1044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown DisplayInfo info; 1054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (USE_CACHE) { 1064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown info = mDisplayInfoCache.get(displayId); 1074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (info != null) { 1084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return info; 1094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 110bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 111bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 112bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown info = mDm.getDisplayInfo(displayId); 113bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (info == null) { 114bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return null; 115bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 1164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (USE_CACHE) { 1184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayInfoCache.put(displayId, info); 1194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown registerCallbackIfNeededLocked(); 1214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 122bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (DEBUG) { 123bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info); 124bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 125bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return info; 126bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 127bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } catch (RemoteException ex) { 128bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Log.e(TAG, "Could not get display information from display manager.", ex); 129bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return null; 130bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 131bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 132bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 133bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown /** 134bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Gets all currently valid logical display ids. 135bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 136bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @return An array containing all display ids. 137bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 138bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public int[] getDisplayIds() { 139bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown try { 140bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (mLock) { 1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (USE_CACHE) { 1424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mDisplayIdCache != null) { 1434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return mDisplayIdCache; 1444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int[] displayIds = mDm.getDisplayIds(); 1484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (USE_CACHE) { 1494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayIdCache = displayIds; 150bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 1514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown registerCallbackIfNeededLocked(); 1524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return displayIds; 153bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 154bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } catch (RemoteException ex) { 155bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Log.e(TAG, "Could not get display ids from display manager.", ex); 156bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return new int[] { Display.DEFAULT_DISPLAY }; 157bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 158bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 159bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 160bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown /** 161bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Gets information about a logical display. 162bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 163bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * The display metrics may be adjusted to provide compatibility 164bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for legacy applications. 165bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 166bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @param displayId The logical display id. 167bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @param cih The compatibility info, or null if none is required. 168bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @return The display object, or null if there is no display with the given id. 169bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 170bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) { 171bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown DisplayInfo displayInfo = getDisplayInfo(displayId); 172bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (displayInfo == null) { 173bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return null; 174bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 175bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return new Display(this, displayId, displayInfo, cih); 176bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 177bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 178bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown /** 179bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Gets information about a logical display without applying any compatibility metrics. 180bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * 181bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @param displayId The logical display id. 182bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * @return The display object, or null if there is no display with the given id. 183bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */ 184bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public Display getRealDisplay(int displayId) { 185bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return getCompatibleDisplay(displayId, null); 186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 188bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void registerDisplayListener(DisplayListener listener, Handler handler) { 189bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (listener == null) { 190bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown throw new IllegalArgumentException("listener must not be null"); 191bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 192bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 193bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (mLock) { 194bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown int index = findDisplayListenerLocked(listener); 195bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (index < 0) { 196bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mDisplayListeners.add(new DisplayListenerDelegate(listener, handler)); 197bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown registerCallbackIfNeededLocked(); 198bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 199bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 200bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 201bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 202bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void unregisterDisplayListener(DisplayListener listener) { 203bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (listener == null) { 204bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown throw new IllegalArgumentException("listener must not be null"); 205bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 206bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 207bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (mLock) { 208bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown int index = findDisplayListenerLocked(listener); 209bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (index >= 0) { 210bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown DisplayListenerDelegate d = mDisplayListeners.get(index); 211bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown d.clearEvents(); 212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mDisplayListeners.remove(index); 213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 214bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 215bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 216bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 217bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private int findDisplayListenerLocked(DisplayListener listener) { 218bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown final int numListeners = mDisplayListeners.size(); 219bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown for (int i = 0; i < numListeners; i++) { 220bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (mDisplayListeners.get(i).mListener == listener) { 221bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return i; 222bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 223bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 224bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return -1; 225bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 226bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 227bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private void registerCallbackIfNeededLocked() { 228bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (mCallback == null) { 229bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mCallback = new DisplayManagerCallback(); 230bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown try { 231bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mDm.registerCallback(mCallback); 232bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } catch (RemoteException ex) { 233bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Log.e(TAG, "Failed to register callback with display manager service.", ex); 234bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mCallback = null; 235bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 236bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 237bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 238bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 239bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private void handleDisplayEvent(int displayId, int event) { 240bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown synchronized (mLock) { 2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (USE_CACHE) { 2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayInfoCache.remove(displayId); 243bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (event == EVENT_DISPLAY_ADDED || event == EVENT_DISPLAY_REMOVED) { 2454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayIdCache = null; 2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 247bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 248bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 249bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown final int numListeners = mDisplayListeners.size(); 250bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown for (int i = 0; i < numListeners; i++) { 251bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mDisplayListeners.get(i).sendDisplayEvent(displayId, event); 252bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 253bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 254bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 255bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 256e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void scanWifiDisplays() { 257e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown try { 258e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDm.scanWifiDisplays(); 259e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } catch (RemoteException ex) { 260e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown Log.e(TAG, "Failed to scan for Wifi displays.", ex); 261e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 262e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 263e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 264e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void connectWifiDisplay(String deviceAddress) { 265e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown if (deviceAddress == null) { 266e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown throw new IllegalArgumentException("deviceAddress must not be null"); 267e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 268e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 269e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown try { 270e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDm.connectWifiDisplay(deviceAddress); 271e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } catch (RemoteException ex) { 272e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown Log.e(TAG, "Failed to connect to Wifi display " + deviceAddress + ".", ex); 273e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 274e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 275e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 276e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public void disconnectWifiDisplay() { 277e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown try { 278e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown mDm.disconnectWifiDisplay(); 279e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } catch (RemoteException ex) { 280e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown Log.e(TAG, "Failed to disconnect from Wifi display.", ex); 281e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 282e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 283e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 28489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void renameWifiDisplay(String deviceAddress, String alias) { 28589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (deviceAddress == null) { 28689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown throw new IllegalArgumentException("deviceAddress must not be null"); 28789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 28889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 28989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown try { 29089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mDm.renameWifiDisplay(deviceAddress, alias); 29189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } catch (RemoteException ex) { 29289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown Log.e(TAG, "Failed to rename Wifi display " + deviceAddress 29389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown + " with alias " + alias + ".", ex); 29489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 29589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 29689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 29789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown public void forgetWifiDisplay(String deviceAddress) { 29889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown if (deviceAddress == null) { 29989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown throw new IllegalArgumentException("deviceAddress must not be null"); 30089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 30189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 30289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown try { 30389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown mDm.forgetWifiDisplay(deviceAddress); 30489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } catch (RemoteException ex) { 30589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown Log.e(TAG, "Failed to forget Wifi display.", ex); 30689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 30789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown } 30889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown 309e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown public WifiDisplayStatus getWifiDisplayStatus() { 310e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown try { 311e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown return mDm.getWifiDisplayStatus(); 312e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } catch (RemoteException ex) { 313e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown Log.e(TAG, "Failed to get Wifi display status.", ex); 314e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown return new WifiDisplayStatus(); 315e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 316e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown } 317e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown 318bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub { 319bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown @Override 320bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void onDisplayEvent(int displayId, int event) { 321bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if (DEBUG) { 322bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event); 323bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 324bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown handleDisplayEvent(displayId, event); 325bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 326bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 327bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 328bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static final class DisplayListenerDelegate extends Handler { 329bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public final DisplayListener mListener; 330bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 331bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public DisplayListenerDelegate(DisplayListener listener, Handler handler) { 332bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/); 333bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mListener = listener; 334bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 335bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 336bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void sendDisplayEvent(int displayId, int event) { 337bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown Message msg = obtainMessage(event, displayId, 0); 338bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown sendMessage(msg); 339bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 340bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 341bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void clearEvents() { 342bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown removeCallbacksAndMessages(null); 343bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 344bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 345bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown @Override 346bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public void handleMessage(Message msg) { 347bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown switch (msg.what) { 348bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown case EVENT_DISPLAY_ADDED: 349bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mListener.onDisplayAdded(msg.arg1); 350bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown break; 351bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown case EVENT_DISPLAY_CHANGED: 352bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mListener.onDisplayChanged(msg.arg1); 353bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown break; 354bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown case EVENT_DISPLAY_REMOVED: 355bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown mListener.onDisplayRemoved(msg.arg1); 356bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown break; 357bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 358bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 359bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 360bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown} 361