簡述
DisplayManagerService
用來管理顯示的生命周期,它決定如何根據當前連接的物理顯示設備控制其邏輯顯示,并且在狀態更改時,向系統和應用程序發送通知,等等。一次多種顯示類型的多顯示器鏡像顯示,包括內建的顯示類型(本地)、HDMI顯示類型以及支持WIFI Display協議(MIRACAST),實現本地設備在遠程顯示器的鏡像顯示;
DisplayAdapter
是DisplayManagerService
所依賴的集合組件,其為系統顯示,收集并發現物理顯示設備提供了適配器的作用。
目前有以下兩種方式的適配器供使用
- 一、為本地顯示設備提供適配器。
- 二、為開發者提供的模擬顯示適配器。
DisplayAdapter
與 DisplayManagerService
是弱耦合關系。DisplayAdapter
通過注冊在 DisplayManagerService
類中的 DisplayAdapter.Listener
實現異步通信。
這樣做有兩個原因
- 一、巧妙地封裝了這兩個類的職責,
DisplayAdapter
:處理各個顯示設備
DisplayManagerService
:處理全局顯示狀態。 - 二、消除異步顯示設備發現導致死鎖的可能性
Synchronization(同步鎖)
因為顯示管理器可能被多個線程訪問,所以同步鎖就會變得有點復雜。 特別是當窗口管理器( window manager
)在保持繪制事務的同時調用顯示管理器(display manager
),窗口管理器期望它可以立即應用并更改。 但不幸的是,顯示管理器(display manager
)不能異步地做所有事情。
為了解決這個問題,顯示管理器的所有對象必須持有相同的鎖。 我們將此鎖稱為同步鎖,它具有唯一性。
通過DisplayManager提供對外接口
提供接口包括如下:
- 1.
getDisplay(int displayId)
根據displayId
參數獲得一個邏輯顯示器的信息 - 2.
getDisplays()
獲得當前所有有效的邏輯顯示器列表 - 3.
registerDisplayListener()
登記一個顯示監聽對象,用來監聽顯示器的新增、去除或改變通知事件。 - 4.
unregisterDisplayListener()
取消先前登記的一個顯示監聽對象 - 5.
createVirtualDisplay()
創建一個虛擬顯示器,虛擬顯示的內容被渲染到提供的Surface
中,當進程終止時虛擬顯示器會被自動的釋放,并且所有的Window都會被強制移除。當不再使用他時,你應該調用release()
方法來釋放資源。
相關類
- 1.
DisplayPowerController
控制屏幕顯示相關的電源狀態,包括距離傳感器和光線傳感器等。 - 2.
DisplayPowerState
控制顯示狀態。當屬性改變的時候,該組件以統一的順序發生一個回調以應用這些改變。
一、初始化
跟其他系統服務一樣, DisplayManagerService
也是繼承于SystemService
并通過SystemServer
啟動。
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
private void startBootstrapServices() {
......
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
......
}
}
DisplayManagerService
繼承 SystemService
, 由 SystemServer
啟動。
構造函數
public final class DisplayManagerService extends SystemService {
...
public DisplayManagerService(Context context) {
this(context, new Injector());
}
@VisibleForTesting
DisplayManagerService(Context context, Injector injector) {
super(context);
mInjector = injector;
mContext = context;
//Step:1
mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
mUiHandler = UiThread.getHandler();
//Step:2
mDisplayAdapterListener = new DisplayAdapterListener();
//Step:3
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
//Step:4
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
}
...
}
- 1.創建Handler接收消息并處理
- 2.創建適配器監聽器,用于監聽設備的添加、改變、異常
- 3.用于開發模式
- 4.獲取電源管理
onStart方法
@Override
public void onStart() {
//Step 1
mPersistentDataStore.loadIfNeeded();
//Step 2
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
//Step 3
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);
//Step 4
publishLocalService(DisplayManagerInternal.class, new LocalService());
//Step 5
publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
}
- 加載本地持久化數據
- 2.發送消息注冊默認適配器
- 3.對其他
services
或者app應用
公開BinderService
AIDL遠程服務 - 4.對系統進程公開
LocalService
和DisplayTransformManager
加載本地持久數據
/frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java
public void loadIfNeeded() {
if (!mLoaded) {
load();
mLoaded = true;
}
}
private void load() {
clearState();
final InputStream is;
try {
is = mAtomicFile.openRead();
} catch (FileNotFoundException ex) {
return;
}
XmlPullParser parser;
try {
parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
clearState();
} catch (XmlPullParserException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
clearState();
} finally {
IoUtils.closeQuietly(is);
}
}
注冊默認顯示器
主要功能是將顯示設備添加注冊到mDisplayAdapters
集合中
private void registerDefaultDisplayAdapter() {
// Register default display adapter.
synchronized (mSyncRoot) {
registerDisplayAdapterLocked(new LocalDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
}
}
private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
mDisplayAdapters.add(adapter);
adapter.registerLocked();
}
onBootPhase()方法
等待默認顯示器
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
synchronized (mSyncRoot) {
long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
......
try {
mSyncRoot.wait(delay);
} catch (InterruptedException ex) {
}
}
}
}
}
systemReady()方法
服務就緒
public void systemReady(boolean safeMode, boolean onlyCore) {
synchronized (mSyncRoot) {
mSafeMode = safeMode;
mOnlyCore = onlyCore;
}
//注冊調價適配器類型
mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
}
private void registerAdditionalDisplayAdapters() {
synchronized (mSyncRoot) {
if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
//開發模式用
registerOverlayDisplayAdapterLocked();
//wifi 遠程顯示器用
registerWifiDisplayAdapterLocked();
//虛擬顯示用
registerVirtualDisplayAdapterLocked();
}
}
}