DisplayManagerService.java revision bf5740e75efd87ae0213486e78e029403804c6f0
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 com.android.server.display;
18
19import android.Manifest;
20import android.content.Context;
21import android.content.pm.PackageManager;
22import android.hardware.display.DisplayManager;
23import android.hardware.display.IDisplayManager;
24import android.os.Binder;
25import android.os.SystemProperties;
26import android.view.Display;
27import android.view.DisplayInfo;
28import android.view.Surface;
29
30import java.io.FileDescriptor;
31import java.io.PrintWriter;
32import java.util.ArrayList;
33
34/**
35 * Manages the properties, media routing and power state of attached displays.
36 * <p>
37 * The display manager service does not own or directly control the displays.
38 * Instead, other components in the system register their display adapters with the
39 * display manager service which acts as a central controller.
40 * </p>
41 */
42public final class DisplayManagerService extends IDisplayManager.Stub {
43    private static final String TAG = "DisplayManagerService";
44
45    private static final String SYSTEM_HEADLESS = "ro.config.headless";
46
47    private final Object mLock = new Object();
48
49    private final Context mContext;
50    private final boolean mHeadless;
51
52    private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
53    private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
54
55    public DisplayManagerService(Context context) {
56        mContext = context;
57        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
58
59        registerDefaultDisplayAdapter();
60    }
61
62    private void registerDefaultDisplayAdapter() {
63        if (mHeadless) {
64            registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
65        } else {
66            registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext));
67        }
68    }
69
70    // FIXME: this isn't the right API for the long term
71    public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
72        // hardcoded assuming 720p touch screen plugged into HDMI and USB
73        // need to redesign this
74        info.width = 1280;
75        info.height = 720;
76    }
77
78    /**
79     * Returns true if the device is headless.
80     *
81     * @return True if the device is headless.
82     */
83    public boolean isHeadless() {
84        return mHeadless;
85    }
86
87    /**
88     * Save away new DisplayInfo data.
89     * @param displayId The local DisplayInfo to store the new data in.
90     * @param info The new data to be stored.
91     */
92    public void setDisplayInfo(int displayId, DisplayInfo info) {
93        synchronized (mLock) {
94            if (displayId != Display.DEFAULT_DISPLAY) {
95                throw new UnsupportedOperationException();
96            }
97            mDefaultDisplayInfo.copyFrom(info);
98        }
99    }
100
101    /**
102     * Return requested DisplayInfo.
103     * @param displayId The data to retrieve.
104     * @param outInfo The structure to receive the data.
105     */
106    @Override // Binder call
107    public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
108        synchronized (mLock) {
109            if (displayId != Display.DEFAULT_DISPLAY) {
110                return false;
111            }
112            outInfo.copyFrom(mDefaultDisplayInfo);
113            return true;
114        }
115    }
116
117    private void registerDisplayAdapter(DisplayAdapter adapter) {
118        mDisplayAdapters.add(adapter);
119        adapter.register(new DisplayAdapter.Listener() {
120            @Override
121            public void onDisplayDeviceAdded(DisplayDevice device) {
122                DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
123                device.getInfo(deviceInfo);
124                copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
125            }
126
127            @Override
128            public void onDisplayDeviceRemoved(DisplayDevice device) {
129            }
130        });
131    }
132
133    private void copyDisplayInfoFromDeviceInfo(
134            DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
135        // Bootstrap the logical display using the physical display.
136        displayInfo.appWidth = deviceInfo.width;
137        displayInfo.appHeight = deviceInfo.height;
138        displayInfo.logicalWidth = deviceInfo.width;
139        displayInfo.logicalHeight = deviceInfo.height;
140        displayInfo.rotation = Surface.ROTATION_0;
141        displayInfo.refreshRate = deviceInfo.refreshRate;
142        displayInfo.logicalDensityDpi = deviceInfo.densityDpi;
143        displayInfo.physicalXDpi = deviceInfo.xDpi;
144        displayInfo.physicalYDpi = deviceInfo.yDpi;
145        displayInfo.smallestNominalAppWidth = deviceInfo.width;
146        displayInfo.smallestNominalAppHeight = deviceInfo.height;
147        displayInfo.largestNominalAppWidth = deviceInfo.width;
148        displayInfo.largestNominalAppHeight = deviceInfo.height;
149    }
150
151    @Override // Binder call
152    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
153        if (mContext == null
154                || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
155                        != PackageManager.PERMISSION_GRANTED) {
156            pw.println("Permission Denial: can't dump DisplayManager from from pid="
157                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
158            return;
159        }
160
161        pw.println("DISPLAY MANAGER (dumpsys display)\n");
162
163        pw.println("Headless: " + mHeadless);
164
165        synchronized (mLock) {
166            for (DisplayAdapter adapter : mDisplayAdapters) {
167                pw.println("Adapter: " + adapter.getName());
168            }
169
170            pw.println("Default display info: " + mDefaultDisplayInfo);
171        }
172
173        pw.println("Default display: "
174                + DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY));
175    }
176}
177