blob: 1463780a328928fbc2aa240aff4c45397f4e77a6 [file] [log] [blame]
Jeff Brownfa25bf52012-07-23 19:26:30 -07001/*
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;
Jeff Brownbf5740e2012-08-19 23:20:02 -070022import android.hardware.display.DisplayManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070023import android.hardware.display.IDisplayManager;
24import android.os.Binder;
Jeff Brown64a55af2012-08-26 02:47:39 -070025import android.os.IBinder;
Jeff Brownfa25bf52012-07-23 19:26:30 -070026import android.os.SystemProperties;
27import android.view.Display;
28import android.view.DisplayInfo;
29import android.view.Surface;
30
31import java.io.FileDescriptor;
32import java.io.PrintWriter;
33import java.util.ArrayList;
34
35/**
36 * Manages the properties, media routing and power state of attached displays.
37 * <p>
38 * The display manager service does not own or directly control the displays.
39 * Instead, other components in the system register their display adapters with the
40 * display manager service which acts as a central controller.
41 * </p>
42 */
43public final class DisplayManagerService extends IDisplayManager.Stub {
44 private static final String TAG = "DisplayManagerService";
45
46 private static final String SYSTEM_HEADLESS = "ro.config.headless";
47
48 private final Object mLock = new Object();
49
Jeff Brown848c2dc2012-08-19 20:18:08 -070050 private final Context mContext;
Jeff Brownfa25bf52012-07-23 19:26:30 -070051 private final boolean mHeadless;
Craig Mautner4f67ba62012-08-02 11:23:00 -070052
Jeff Brownfa25bf52012-07-23 19:26:30 -070053 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
Jeff Brown848c2dc2012-08-19 20:18:08 -070054 private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
Jeff Brown64a55af2012-08-26 02:47:39 -070055 private DisplayDevice mDefaultDisplayDevice;
Jeff Brownfa25bf52012-07-23 19:26:30 -070056
Jeff Brown848c2dc2012-08-19 20:18:08 -070057 public DisplayManagerService(Context context) {
58 mContext = context;
Jeff Brownfa25bf52012-07-23 19:26:30 -070059 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
Jeff Brown848c2dc2012-08-19 20:18:08 -070060
Craig Mautner4f67ba62012-08-02 11:23:00 -070061 registerDefaultDisplayAdapter();
62 }
63
64 private void registerDefaultDisplayAdapter() {
65 if (mHeadless) {
Jeff Brown848c2dc2012-08-19 20:18:08 -070066 registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
Craig Mautner4f67ba62012-08-02 11:23:00 -070067 } else {
Jeff Brown64a55af2012-08-26 02:47:39 -070068 registerDisplayAdapter(new LocalDisplayAdapter(mContext));
Craig Mautner4f67ba62012-08-02 11:23:00 -070069 }
Jeff Brownfa25bf52012-07-23 19:26:30 -070070 }
71
Jeff Brownfa25bf52012-07-23 19:26:30 -070072 // FIXME: this isn't the right API for the long term
Jeff Brownfa25bf52012-07-23 19:26:30 -070073 public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
74 // hardcoded assuming 720p touch screen plugged into HDMI and USB
75 // need to redesign this
76 info.width = 1280;
77 info.height = 720;
78 }
79
Jeff Brown848c2dc2012-08-19 20:18:08 -070080 /**
81 * Returns true if the device is headless.
82 *
83 * @return True if the device is headless.
84 */
Jeff Brownfa25bf52012-07-23 19:26:30 -070085 public boolean isHeadless() {
86 return mHeadless;
87 }
88
Craig Mautner4f67ba62012-08-02 11:23:00 -070089 /**
Jeff Brown64a55af2012-08-26 02:47:39 -070090 * Set the new display orientation.
91 * @param displayId The logical display id.
92 * @param orientation One of the Surface.ROTATION_* constants.
93 */
94 public void setDisplayOrientation(int displayId, int orientation) {
95 synchronized (mLock) {
96 if (displayId != Display.DEFAULT_DISPLAY) {
97 throw new UnsupportedOperationException();
98 }
99
100 IBinder displayToken = mDefaultDisplayDevice.getDisplayToken();
101 if (displayToken != null) {
102 Surface.openTransaction();
103 try {
104 Surface.setDisplayOrientation(displayToken, orientation);
105 } finally {
106 Surface.closeTransaction();
107 }
108 }
109 }
110 }
111
112 /**
Craig Mautner4f67ba62012-08-02 11:23:00 -0700113 * Save away new DisplayInfo data.
Jeff Brown64a55af2012-08-26 02:47:39 -0700114 * @param displayId The logical display id.
Craig Mautner4f67ba62012-08-02 11:23:00 -0700115 * @param info The new data to be stored.
116 */
117 public void setDisplayInfo(int displayId, DisplayInfo info) {
118 synchronized (mLock) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700119 if (displayId != Display.DEFAULT_DISPLAY) {
120 throw new UnsupportedOperationException();
Craig Mautner4f67ba62012-08-02 11:23:00 -0700121 }
Jeff Brown848c2dc2012-08-19 20:18:08 -0700122 mDefaultDisplayInfo.copyFrom(info);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700123 }
124 }
125
126 /**
127 * Return requested DisplayInfo.
128 * @param displayId The data to retrieve.
129 * @param outInfo The structure to receive the data.
130 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700131 @Override // Binder call
132 public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
133 synchronized (mLock) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700134 if (displayId != Display.DEFAULT_DISPLAY) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700135 return false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700136 }
Jeff Brown848c2dc2012-08-19 20:18:08 -0700137 outInfo.copyFrom(mDefaultDisplayInfo);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700138 return true;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700139 }
140 }
141
Jeff Brown848c2dc2012-08-19 20:18:08 -0700142 private void registerDisplayAdapter(DisplayAdapter adapter) {
143 mDisplayAdapters.add(adapter);
144 adapter.register(new DisplayAdapter.Listener() {
145 @Override
146 public void onDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700147 mDefaultDisplayDevice = device;
Jeff Brown848c2dc2012-08-19 20:18:08 -0700148 DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
149 device.getInfo(deviceInfo);
150 copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700151 }
152
Jeff Brown848c2dc2012-08-19 20:18:08 -0700153 @Override
154 public void onDisplayDeviceRemoved(DisplayDevice device) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700155 }
Jeff Brown848c2dc2012-08-19 20:18:08 -0700156 });
Craig Mautner4f67ba62012-08-02 11:23:00 -0700157 }
158
Jeff Brown848c2dc2012-08-19 20:18:08 -0700159 private void copyDisplayInfoFromDeviceInfo(
160 DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700161 // Bootstrap the logical display using the physical display.
162 displayInfo.appWidth = deviceInfo.width;
163 displayInfo.appHeight = deviceInfo.height;
164 displayInfo.logicalWidth = deviceInfo.width;
165 displayInfo.logicalHeight = deviceInfo.height;
166 displayInfo.rotation = Surface.ROTATION_0;
167 displayInfo.refreshRate = deviceInfo.refreshRate;
168 displayInfo.logicalDensityDpi = deviceInfo.densityDpi;
169 displayInfo.physicalXDpi = deviceInfo.xDpi;
170 displayInfo.physicalYDpi = deviceInfo.yDpi;
171 displayInfo.smallestNominalAppWidth = deviceInfo.width;
172 displayInfo.smallestNominalAppHeight = deviceInfo.height;
173 displayInfo.largestNominalAppWidth = deviceInfo.width;
174 displayInfo.largestNominalAppHeight = deviceInfo.height;
175 }
176
Jeff Brownfa25bf52012-07-23 19:26:30 -0700177 @Override // Binder call
178 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
179 if (mContext == null
180 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
181 != PackageManager.PERMISSION_GRANTED) {
182 pw.println("Permission Denial: can't dump DisplayManager from from pid="
183 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
184 return;
185 }
186
187 pw.println("DISPLAY MANAGER (dumpsys display)\n");
188
189 pw.println("Headless: " + mHeadless);
190
Jeff Brown848c2dc2012-08-19 20:18:08 -0700191 synchronized (mLock) {
192 for (DisplayAdapter adapter : mDisplayAdapters) {
193 pw.println("Adapter: " + adapter.getName());
194 }
Craig Mautner9de49362012-08-02 14:30:30 -0700195
Jeff Brownbf5740e2012-08-19 23:20:02 -0700196 pw.println("Default display info: " + mDefaultDisplayInfo);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700197 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700198
199 pw.println("Default display: "
200 + DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY));
Craig Mautner9de49362012-08-02 14:30:30 -0700201 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700202}