1 /*
2  * Copyright (C) 2013 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 android.support.v4.hardware.display;
18 
19 import android.content.Context;
20 import android.hardware.display.DisplayManager;
21 import android.os.Build;
22 import android.support.annotation.RequiresApi;
23 import android.view.Display;
24 import android.view.WindowManager;
25 
26 import java.util.WeakHashMap;
27 
28 /**
29  * Helper for accessing features in {@link android.hardware.display.DisplayManager}
30  * in a backwards compatible fashion.
31  */
32 public abstract class DisplayManagerCompat {
33     private static final WeakHashMap<Context, DisplayManagerCompat> sInstances =
34             new WeakHashMap<Context, DisplayManagerCompat>();
35 
36     /**
37      * Display category: Presentation displays.
38      * <p>
39      * This category can be used to identify secondary displays that are suitable for
40      * use as presentation displays.
41      * </p>
42      *
43      * @see android.app.Presentation for information about presenting content
44      * on secondary displays.
45      * @see #getDisplays(String)
46      */
47     public static final String DISPLAY_CATEGORY_PRESENTATION =
48             "android.hardware.display.category.PRESENTATION";
49 
DisplayManagerCompat()50     DisplayManagerCompat() {
51     }
52 
53     /**
54      * Gets an instance of the display manager given the context.
55      */
getInstance(Context context)56     public static DisplayManagerCompat getInstance(Context context) {
57         synchronized (sInstances) {
58             DisplayManagerCompat instance = sInstances.get(context);
59             if (instance == null) {
60                 if (Build.VERSION.SDK_INT >= 17) {
61                     instance = new DisplayManagerCompatApi17Impl(context);
62                 } else {
63                     instance = new DisplayManagerCompatApi14Impl(context);
64                 }
65                 sInstances.put(context, instance);
66             }
67             return instance;
68         }
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      */
getDisplay(int displayId)80     public abstract Display getDisplay(int displayId);
81 
82     /**
83      * Gets all currently valid logical displays.
84      *
85      * @return An array containing all displays.
86      */
getDisplays()87     public abstract Display[] getDisplays();
88 
89     /**
90      * Gets all currently valid logical displays of the specified category.
91      * <p>
92      * When there are multiple displays in a category the returned displays are sorted
93      * of preference.  For example, if the requested category is
94      * {@link #DISPLAY_CATEGORY_PRESENTATION} and there are multiple presentation displays
95      * then the displays are sorted so that the first display in the returned array
96      * is the most preferred presentation display.  The application may simply
97      * use the first display or allow the user to choose.
98      * </p>
99      *
100      * @param category The requested display category or null to return all displays.
101      * @return An array containing all displays sorted by order of preference.
102      *
103      * @see #DISPLAY_CATEGORY_PRESENTATION
104      */
getDisplays(String category)105     public abstract Display[] getDisplays(String category);
106 
107     private static class DisplayManagerCompatApi14Impl extends DisplayManagerCompat {
108         private final WindowManager mWindowManager;
109 
DisplayManagerCompatApi14Impl(Context context)110         DisplayManagerCompatApi14Impl(Context context) {
111             mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
112         }
113 
114         @Override
getDisplay(int displayId)115         public Display getDisplay(int displayId) {
116             Display display = mWindowManager.getDefaultDisplay();
117             if (display.getDisplayId() == displayId) {
118                 return display;
119             }
120             return null;
121         }
122 
123         @Override
getDisplays()124         public Display[] getDisplays() {
125             return new Display[] { mWindowManager.getDefaultDisplay() };
126         }
127 
128         @Override
getDisplays(String category)129         public Display[] getDisplays(String category) {
130             return category == null ? getDisplays() : new Display[0];
131         }
132     }
133 
134     @RequiresApi(17)
135     private static class DisplayManagerCompatApi17Impl extends DisplayManagerCompat {
136         private final DisplayManager mDisplayManager;
137 
DisplayManagerCompatApi17Impl(Context context)138         DisplayManagerCompatApi17Impl(Context context) {
139             mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
140         }
141 
142         @Override
getDisplay(int displayId)143         public Display getDisplay(int displayId) {
144             return mDisplayManager.getDisplay(displayId);
145         }
146 
147         @Override
getDisplays()148         public Display[] getDisplays() {
149             return mDisplayManager.getDisplays();
150         }
151 
152         @Override
getDisplays(String category)153         public Display[] getDisplays(String category) {
154             return mDisplayManager.getDisplays(category);
155         }
156     }
157 }
158