blob: 7c0f8fd526b0316886ba40f7cf4d86cd68950f17 [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;
22import android.hardware.display.IDisplayManager;
23import android.os.Binder;
24import android.os.SystemProperties;
25import android.view.Display;
26import android.view.DisplayInfo;
27import android.view.Surface;
28
29import java.io.FileDescriptor;
30import java.io.PrintWriter;
31import java.util.ArrayList;
32
33/**
34 * Manages the properties, media routing and power state of attached displays.
35 * <p>
36 * The display manager service does not own or directly control the displays.
37 * Instead, other components in the system register their display adapters with the
38 * display manager service which acts as a central controller.
39 * </p>
40 */
41public final class DisplayManagerService extends IDisplayManager.Stub {
42 private static final String TAG = "DisplayManagerService";
43
44 private static final String SYSTEM_HEADLESS = "ro.config.headless";
45
46 private final Object mLock = new Object();
47
Jeff Brown848c2dc2012-08-19 20:18:08 -070048 private final Context mContext;
Jeff Brownfa25bf52012-07-23 19:26:30 -070049 private final boolean mHeadless;
Craig Mautner4f67ba62012-08-02 11:23:00 -070050
Jeff Brownfa25bf52012-07-23 19:26:30 -070051 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
Jeff Brown848c2dc2012-08-19 20:18:08 -070052 private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
Jeff Brownfa25bf52012-07-23 19:26:30 -070053
Jeff Brown848c2dc2012-08-19 20:18:08 -070054 public DisplayManagerService(Context context) {
55 mContext = context;
Jeff Brownfa25bf52012-07-23 19:26:30 -070056 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
Jeff Brown848c2dc2012-08-19 20:18:08 -070057
Craig Mautner4f67ba62012-08-02 11:23:00 -070058 registerDefaultDisplayAdapter();
59 }
60
61 private void registerDefaultDisplayAdapter() {
62 if (mHeadless) {
Jeff Brown848c2dc2012-08-19 20:18:08 -070063 registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
Craig Mautner4f67ba62012-08-02 11:23:00 -070064 } else {
Jeff Brown848c2dc2012-08-19 20:18:08 -070065 registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext));
Craig Mautner4f67ba62012-08-02 11:23:00 -070066 }
Jeff Brownfa25bf52012-07-23 19:26:30 -070067 }
68
Jeff Brownfa25bf52012-07-23 19:26:30 -070069 // FIXME: this isn't the right API for the long term
Jeff Brownfa25bf52012-07-23 19:26:30 -070070 public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
71 // hardcoded assuming 720p touch screen plugged into HDMI and USB
72 // need to redesign this
73 info.width = 1280;
74 info.height = 720;
75 }
76
Jeff Brown848c2dc2012-08-19 20:18:08 -070077 /**
78 * Returns true if the device is headless.
79 *
80 * @return True if the device is headless.
81 */
Jeff Brownfa25bf52012-07-23 19:26:30 -070082 public boolean isHeadless() {
83 return mHeadless;
84 }
85
Craig Mautner4f67ba62012-08-02 11:23:00 -070086 /**
87 * Save away new DisplayInfo data.
88 * @param displayId The local DisplayInfo to store the new data in.
89 * @param info The new data to be stored.
90 */
91 public void setDisplayInfo(int displayId, DisplayInfo info) {
92 synchronized (mLock) {
Jeff Brown848c2dc2012-08-19 20:18:08 -070093 if (displayId != Display.DEFAULT_DISPLAY) {
94 throw new UnsupportedOperationException();
Craig Mautner4f67ba62012-08-02 11:23:00 -070095 }
Jeff Brown848c2dc2012-08-19 20:18:08 -070096 mDefaultDisplayInfo.copyFrom(info);
Craig Mautner4f67ba62012-08-02 11:23:00 -070097 }
98 }
99
100 /**
101 * Return requested DisplayInfo.
102 * @param displayId The data to retrieve.
103 * @param outInfo The structure to receive the data.
104 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700105 @Override // Binder call
106 public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
107 synchronized (mLock) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700108 if (displayId != Display.DEFAULT_DISPLAY) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700109 return false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700110 }
Jeff Brown848c2dc2012-08-19 20:18:08 -0700111 outInfo.copyFrom(mDefaultDisplayInfo);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700112 return true;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700113 }
114 }
115
Jeff Brown848c2dc2012-08-19 20:18:08 -0700116 private void registerDisplayAdapter(DisplayAdapter adapter) {
117 mDisplayAdapters.add(adapter);
118 adapter.register(new DisplayAdapter.Listener() {
119 @Override
120 public void onDisplayDeviceAdded(DisplayDevice device) {
121 DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
122 device.getInfo(deviceInfo);
123 copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700124 }
125
Jeff Brown848c2dc2012-08-19 20:18:08 -0700126 @Override
127 public void onDisplayDeviceRemoved(DisplayDevice device) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700128 }
Jeff Brown848c2dc2012-08-19 20:18:08 -0700129 });
Craig Mautner4f67ba62012-08-02 11:23:00 -0700130 }
131
Jeff Brown848c2dc2012-08-19 20:18:08 -0700132 private void copyDisplayInfoFromDeviceInfo(
133 DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
Craig Mautner4f67ba62012-08-02 11:23:00 -0700134 // Bootstrap the logical display using the physical display.
135 displayInfo.appWidth = deviceInfo.width;
136 displayInfo.appHeight = deviceInfo.height;
137 displayInfo.logicalWidth = deviceInfo.width;
138 displayInfo.logicalHeight = deviceInfo.height;
139 displayInfo.rotation = Surface.ROTATION_0;
140 displayInfo.refreshRate = deviceInfo.refreshRate;
141 displayInfo.logicalDensityDpi = deviceInfo.densityDpi;
142 displayInfo.physicalXDpi = deviceInfo.xDpi;
143 displayInfo.physicalYDpi = deviceInfo.yDpi;
144 displayInfo.smallestNominalAppWidth = deviceInfo.width;
145 displayInfo.smallestNominalAppHeight = deviceInfo.height;
146 displayInfo.largestNominalAppWidth = deviceInfo.width;
147 displayInfo.largestNominalAppHeight = deviceInfo.height;
148 }
149
Jeff Brownfa25bf52012-07-23 19:26:30 -0700150 @Override // Binder call
151 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
152 if (mContext == null
153 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
154 != PackageManager.PERMISSION_GRANTED) {
155 pw.println("Permission Denial: can't dump DisplayManager from from pid="
156 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
157 return;
158 }
159
160 pw.println("DISPLAY MANAGER (dumpsys display)\n");
161
162 pw.println("Headless: " + mHeadless);
163
Jeff Brown848c2dc2012-08-19 20:18:08 -0700164 synchronized (mLock) {
165 for (DisplayAdapter adapter : mDisplayAdapters) {
166 pw.println("Adapter: " + adapter.getName());
167 }
Craig Mautner9de49362012-08-02 14:30:30 -0700168
Jeff Brown848c2dc2012-08-19 20:18:08 -0700169 pw.println("Default display: " + mDefaultDisplayInfo);
170 }
Craig Mautner9de49362012-08-02 14:30:30 -0700171 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700172}