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