/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware.display; import android.content.Context; import android.os.Handler; import android.util.SparseArray; import android.view.Display; /** * Manages the properties of attached displays. *

* Get an instance of this class by calling * {@link android.content.Context#getSystemService(java.lang.String) * Context.getSystemService()} with the argument * {@link android.content.Context#DISPLAY_SERVICE}. *

*/ public final class DisplayManager { private static final String TAG = "DisplayManager"; private static final boolean DEBUG = false; private final Context mContext; private final DisplayManagerGlobal mGlobal; private final Object mLock = new Object(); private final SparseArray mDisplays = new SparseArray(); /** * Broadcast receiver that indicates when the Wifi display status changes. *

* The status is provided as a {@link WifiDisplayStatus} object in the * {@link #EXTRA_WIFI_DISPLAY_STATUS} extra. *

* This broadcast is only sent to registered receivers and can only be sent by the system. *

* @hide */ public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED = "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED"; /** * Contains a {@link WifiDisplayStatus} object. * @hide */ public static final String EXTRA_WIFI_DISPLAY_STATUS = "android.hardware.display.extra.WIFI_DISPLAY_STATUS"; /** @hide */ public DisplayManager(Context context) { mContext = context; mGlobal = DisplayManagerGlobal.getInstance(); } /** * Gets information about a logical display. * * The display metrics may be adjusted to provide compatibility * for legacy applications. * * @param displayId The logical display id. * @return The display object, or null if there is no valid display with the given id. */ public Display getDisplay(int displayId) { synchronized (mLock) { return getOrCreateDisplayLocked(displayId, false /*assumeValid*/); } } /** * Gets all currently valid logical displays. * * @return An array containing all displays. */ public Display[] getDisplays() { int[] displayIds = mGlobal.getDisplayIds(); int expectedCount = displayIds.length; Display[] displays = new Display[expectedCount]; synchronized (mLock) { int actualCount = 0; for (int i = 0; i < expectedCount; i++) { Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/); if (display != null) { displays[actualCount++] = display; } } if (actualCount != expectedCount) { Display[] oldDisplays = displays; displays = new Display[actualCount]; System.arraycopy(oldDisplays, 0, displays, 0, actualCount); } } return displays; } private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) { Display display = mDisplays.get(displayId); if (display == null) { display = mGlobal.getCompatibleDisplay(displayId, mContext.getCompatibilityInfo(displayId)); if (display != null) { mDisplays.put(displayId, display); } } else if (!assumeValid && !display.isValid()) { display = null; } return display; } /** * Registers an display listener to receive notifications about when * displays are added, removed or changed. * * @param listener The listener to register. * @param handler The handler on which the listener should be invoked, or null * if the listener should be invoked on the calling thread's looper. * * @see #unregisterDisplayListener */ public void registerDisplayListener(DisplayListener listener, Handler handler) { mGlobal.registerDisplayListener(listener, handler); } /** * Unregisters an input device listener. * * @param listener The listener to unregister. * * @see #registerDisplayListener */ public void unregisterDisplayListener(DisplayListener listener) { mGlobal.unregisterDisplayListener(listener); } /** * Initiates a fresh scan of availble Wifi displays. * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast. * @hide */ public void scanWifiDisplays() { mGlobal.scanWifiDisplays(); } /** * Connects to a Wifi display. * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast. *

* Automatically remembers the display after a successful connection, if not * already remembered. *

* Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} to connect * to unknown displays. No permissions are required to connect to already known displays. *

* * @param deviceAddress The MAC address of the device to which we should connect. * @hide */ public void connectWifiDisplay(String deviceAddress) { mGlobal.connectWifiDisplay(deviceAddress); } /** * Disconnects from the current Wifi display. * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast. * @hide */ public void disconnectWifiDisplay() { mGlobal.disconnectWifiDisplay(); } /** * Renames a Wifi display. *

* The display must already be remembered for this call to succeed. In other words, * we must already have successfully connected to the display at least once and then * not forgotten it. *

* Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}. *

* * @param deviceAddress The MAC address of the device to rename. * @param alias The alias name by which to remember the device, or null * or empty if no alias should be used. * @hide */ public void renameWifiDisplay(String deviceAddress, String alias) { mGlobal.renameWifiDisplay(deviceAddress, alias); } /** * Forgets a previously remembered Wifi display. *

* Automatically disconnects from the display if currently connected to it. *

* Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}. *

* * @param deviceAddress The MAC address of the device to forget. * @hide */ public void forgetWifiDisplay(String deviceAddress) { mGlobal.forgetWifiDisplay(deviceAddress); } /** * Gets the current Wifi display status. * Watch for changes in the status by registering a broadcast receiver for * {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED}. * * @return The current Wifi display status. * @hide */ public WifiDisplayStatus getWifiDisplayStatus() { return mGlobal.getWifiDisplayStatus(); } /** * Listens for changes in available display devices. */ public interface DisplayListener { /** * Called whenever a logical display has been added to the system. * Use {@link DisplayManager#getDisplay} to get more information about * the display. * * @param displayId The id of the logical display that was added. */ void onDisplayAdded(int displayId); /** * Called whenever a logical display has been removed from the system. * * @param displayId The id of the logical display that was removed. */ void onDisplayRemoved(int displayId); /** * Called whenever the properties of a logical display have changed. * * @param displayId The id of the logical display that changed. */ void onDisplayChanged(int displayId); } }