DisplayManager.java revision e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9
1/*
2 * Copyright (C) 2012 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
17package android.hardware.display;
18
19import android.content.Context;
20import android.os.Handler;
21import android.util.SparseArray;
22import android.view.Display;
23
24/**
25 * Manages the properties of attached displays.
26 * <p>
27 * Get an instance of this class by calling
28 * {@link android.content.Context#getSystemService(java.lang.String)
29 * Context.getSystemService()} with the argument
30 * {@link android.content.Context#DISPLAY_SERVICE}.
31 * </p>
32 */
33public final class DisplayManager {
34    private static final String TAG = "DisplayManager";
35    private static final boolean DEBUG = false;
36
37    private final Context mContext;
38    private final DisplayManagerGlobal mGlobal;
39
40    private final Object mLock = new Object();
41    private final SparseArray<Display> mDisplays = new SparseArray<Display>();
42
43    /**
44     * Broadcast receiver that indicates when the Wifi display status changes.
45     * <p>
46     * The status is provided as a {@link WifiDisplayStatus} object in the
47     * {@link #EXTRA_WIFI_DISPLAY_STATUS} extra.
48     * </p><p>
49     * This broadcast is only sent to registered receivers with the
50     * {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} permission and can
51     * only be sent by the system.
52     * </p>
53     * @hide
54     */
55    public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED =
56            "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED";
57
58    /**
59     * Contains a {@link WifiDisplayStatus} object.
60     * @hide
61     */
62    public static final String EXTRA_WIFI_DISPLAY_STATUS =
63            "android.hardware.display.extra.WIFI_DISPLAY_STATUS";
64
65    /** @hide */
66    public DisplayManager(Context context) {
67        mContext = context;
68        mGlobal = DisplayManagerGlobal.getInstance();
69    }
70
71    /**
72     * Gets information about a logical display.
73     *
74     * The display metrics may be adjusted to provide compatibility
75     * for legacy applications.
76     *
77     * @param displayId The logical display id.
78     * @return The display object, or null if there is no valid display with the given id.
79     */
80    public Display getDisplay(int displayId) {
81        synchronized (mLock) {
82            return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
83        }
84    }
85
86    /**
87     * Gets all currently valid logical displays.
88     *
89     * @return An array containing all displays.
90     */
91    public Display[] getDisplays() {
92        int[] displayIds = mGlobal.getDisplayIds();
93        int expectedCount = displayIds.length;
94        Display[] displays = new Display[expectedCount];
95        synchronized (mLock) {
96            int actualCount = 0;
97            for (int i = 0; i < expectedCount; i++) {
98                Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
99                if (display != null) {
100                    displays[actualCount++] = display;
101                }
102            }
103            if (actualCount != expectedCount) {
104                Display[] oldDisplays = displays;
105                displays = new Display[actualCount];
106                System.arraycopy(oldDisplays, 0, displays, 0, actualCount);
107            }
108        }
109        return displays;
110    }
111
112    private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
113        Display display = mDisplays.get(displayId);
114        if (display == null) {
115            display = mGlobal.getCompatibleDisplay(displayId,
116                    mContext.getCompatibilityInfo(displayId));
117            if (display != null) {
118                mDisplays.put(displayId, display);
119            }
120        } else if (!assumeValid && !display.isValid()) {
121            display = null;
122        }
123        return display;
124    }
125
126    /**
127     * Registers an display listener to receive notifications about when
128     * displays are added, removed or changed.
129     *
130     * @param listener The listener to register.
131     * @param handler The handler on which the listener should be invoked, or null
132     * if the listener should be invoked on the calling thread's looper.
133     *
134     * @see #unregisterDisplayListener
135     */
136    public void registerDisplayListener(DisplayListener listener, Handler handler) {
137        mGlobal.registerDisplayListener(listener, handler);
138    }
139
140    /**
141     * Unregisters an input device listener.
142     *
143     * @param listener The listener to unregister.
144     *
145     * @see #registerDisplayListener
146     */
147    public void unregisterDisplayListener(DisplayListener listener) {
148        mGlobal.unregisterDisplayListener(listener);
149    }
150
151    /**
152     * Initiates a fresh scan of availble Wifi displays.
153     * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
154     * @hide
155     */
156    public void scanWifiDisplays() {
157        mGlobal.scanWifiDisplays();
158    }
159
160    /**
161     * Connects to a Wifi display.
162     * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
163     *
164     * @param deviceAddress The MAC address of the device to which we should connect.
165     * @hide
166     */
167    public void connectWifiDisplay(String deviceAddress) {
168        mGlobal.connectWifiDisplay(deviceAddress);
169    }
170
171    /**
172     * Disconnects from the current Wifi display.
173     * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
174     * @hide
175     */
176    public void disconnectWifiDisplay() {
177        mGlobal.disconnectWifiDisplay();
178    }
179
180    /**
181     * Gets the current Wifi display status.
182     * Watch for changes in the status by registering a broadcast receiver for
183     * {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED}.
184     *
185     * @return The current Wifi display status.
186     * @hide
187     */
188    public WifiDisplayStatus getWifiDisplayStatus() {
189        return mGlobal.getWifiDisplayStatus();
190    }
191
192    /**
193     * Listens for changes in available display devices.
194     */
195    public interface DisplayListener {
196        /**
197         * Called whenever a logical display has been added to the system.
198         * Use {@link DisplayManager#getDisplay} to get more information about
199         * the display.
200         *
201         * @param displayId The id of the logical display that was added.
202         */
203        void onDisplayAdded(int displayId);
204
205        /**
206         * Called whenever a logical display has been removed from the system.
207         *
208         * @param displayId The id of the logical display that was removed.
209         */
210        void onDisplayRemoved(int displayId);
211
212        /**
213         * Called whenever the properties of a logical display have changed.
214         *
215         * @param displayId The id of the logical display that changed.
216         */
217        void onDisplayChanged(int displayId);
218    }
219}
220