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