1c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown/*
2c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * Copyright (C) 2013 The Android Open Source Project
3c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown *
4c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * you may not use this file except in compliance with the License.
6c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * You may obtain a copy of the License at
7c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown *
8c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown *
10c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * Unless required by applicable law or agreed to in writing, software
11c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * See the License for the specific language governing permissions and
14c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * limitations under the License.
15c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown */
16c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
17c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownpackage android.support.v4.hardware.display;
18c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
19c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownimport android.content.Context;
20c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownimport android.view.Display;
21c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownimport android.view.WindowManager;
22c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
23c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownimport java.util.WeakHashMap;
24c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
25c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown/**
26c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * Helper for accessing features in {@link android.hardware.display.DisplayManager}
27c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown * introduced after API level 4 in a backwards compatible fashion.
28c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown */
29c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brownpublic abstract class DisplayManagerCompat {
30c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    private static final WeakHashMap<Context, DisplayManagerCompat> sInstances =
31c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            new WeakHashMap<Context, DisplayManagerCompat>();
32c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
33c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    /**
34c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * Display category: Presentation displays.
35c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * <p>
36c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * This category can be used to identify secondary displays that are suitable for
37c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * use as presentation displays.
38c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * </p>
39c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
40c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @see android.app.Presentation for information about presenting content
41c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * on secondary displays.
42c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @see #getDisplays(String)
43c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     */
44c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    public static final String DISPLAY_CATEGORY_PRESENTATION =
45c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            "android.hardware.display.category.PRESENTATION";
46c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
47c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    DisplayManagerCompat() {
48c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    }
49c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
50c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    /**
51c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * Gets an instance of the display manager given the context.
52c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     */
53c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    public static DisplayManagerCompat getInstance(Context context) {
54c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        synchronized (sInstances) {
55c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            DisplayManagerCompat instance = sInstances.get(context);
56c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            if (instance == null) {
57c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                final int version = android.os.Build.VERSION.SDK_INT;
58c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                if (version >= 17) {
59c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                    instance = new JellybeanMr1Impl(context);
60c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                } else {
61c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                    instance = new LegacyImpl(context);
62c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                }
63c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                sInstances.put(context, instance);
64c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            }
65c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return instance;
66c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
67c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    }
68c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
69c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    /**
70c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * Gets information about a logical display.
71c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
72c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * The display metrics may be adjusted to provide compatibility
73c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * for legacy applications.
74c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
75c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @param displayId The logical display id.
76c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @return The display object, or null if there is no valid display with the given id.
77c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     */
78c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    public abstract Display getDisplay(int displayId);
79c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
80c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    /**
81c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * Gets all currently valid logical displays.
82c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
83c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @return An array containing all displays.
84c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     */
85c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    public abstract Display[] getDisplays();
86c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
87c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    /**
88c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * Gets all currently valid logical displays of the specified category.
89c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * <p>
90c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * When there are multiple displays in a category the returned displays are sorted
91c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * of preference.  For example, if the requested category is
92c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * {@link #DISPLAY_CATEGORY_PRESENTATION} and there are multiple presentation displays
93c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * then the displays are sorted so that the first display in the returned array
94c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * is the most preferred presentation display.  The application may simply
95c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * use the first display or allow the user to choose.
96c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * </p>
97c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
98c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @param category The requested display category or null to return all displays.
99c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @return An array containing all displays sorted by order of preference.
100c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     *
101c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     * @see #DISPLAY_CATEGORY_PRESENTATION
102c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown     */
103c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    public abstract Display[] getDisplays(String category);
104c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
105c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    private static class LegacyImpl extends DisplayManagerCompat {
106c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        private final WindowManager mWindowManager;
107c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
108c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public LegacyImpl(Context context) {
109c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
110c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
111c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
112c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
113c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display getDisplay(int displayId) {
114c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            Display display = mWindowManager.getDefaultDisplay();
115c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            if (display.getDisplayId() == displayId) {
116c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown                return display;
117c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            }
118c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return null;
119c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
120c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
121c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
122c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display[] getDisplays() {
123c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return new Display[] { mWindowManager.getDefaultDisplay() };
124c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
125c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
126c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
127c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display[] getDisplays(String category) {
128c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return category == null ? getDisplays() : new Display[0];
129c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
130c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    }
131c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
132c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    private static class JellybeanMr1Impl extends DisplayManagerCompat {
133c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        private final Object mDisplayManagerObj;
134c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
135c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public JellybeanMr1Impl(Context context) {
136c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            mDisplayManagerObj = DisplayManagerJellybeanMr1.getDisplayManager(context);
137c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
138c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
139c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
140c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display getDisplay(int displayId) {
141c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return DisplayManagerJellybeanMr1.getDisplay(mDisplayManagerObj, displayId);
142c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
143c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
144c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
145c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display[] getDisplays() {
146c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return DisplayManagerJellybeanMr1.getDisplays(mDisplayManagerObj);
147c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
148c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown
149c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        @Override
150c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        public Display[] getDisplays(String category) {
151c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown            return DisplayManagerJellybeanMr1.getDisplays(mDisplayManagerObj, category);
152c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown        }
153c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown    }
154c21f57ed68b81a77167f1df000b0e272e1598bc0Jeff Brown}
155