DisplayManagerService.java revision 848c2dc93b6795e171f3dd6f64ea0be65e2762ca
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.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 48 private final Context mContext; 49 private final boolean mHeadless; 50 51 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); 52 private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); 53 54 public DisplayManagerService(Context context) { 55 mContext = context; 56 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1"); 57 58 registerDefaultDisplayAdapter(); 59 } 60 61 private void registerDefaultDisplayAdapter() { 62 if (mHeadless) { 63 registerDisplayAdapter(new HeadlessDisplayAdapter(mContext)); 64 } else { 65 registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext)); 66 } 67 } 68 69 // FIXME: this isn't the right API for the long term 70 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 77 /** 78 * Returns true if the device is headless. 79 * 80 * @return True if the device is headless. 81 */ 82 public boolean isHeadless() { 83 return mHeadless; 84 } 85 86 /** 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) { 93 if (displayId != Display.DEFAULT_DISPLAY) { 94 throw new UnsupportedOperationException(); 95 } 96 mDefaultDisplayInfo.copyFrom(info); 97 } 98 } 99 100 /** 101 * Return requested DisplayInfo. 102 * @param displayId The data to retrieve. 103 * @param outInfo The structure to receive the data. 104 */ 105 @Override // Binder call 106 public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) { 107 synchronized (mLock) { 108 if (displayId != Display.DEFAULT_DISPLAY) { 109 return false; 110 } 111 outInfo.copyFrom(mDefaultDisplayInfo); 112 return true; 113 } 114 } 115 116 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); 124 } 125 126 @Override 127 public void onDisplayDeviceRemoved(DisplayDevice device) { 128 } 129 }); 130 } 131 132 private void copyDisplayInfoFromDeviceInfo( 133 DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) { 134 // 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 150 @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 164 synchronized (mLock) { 165 for (DisplayAdapter adapter : mDisplayAdapters) { 166 pw.println("Adapter: " + adapter.getName()); 167 } 168 169 pw.println("Default display: " + mDefaultDisplayInfo); 170 } 171 } 172} 173