第五章:DisplayManagerService

簡述

DisplayManagerService用來管理顯示的生命周期,它決定如何根據當前連接的物理顯示設備控制其邏輯顯示,并且在狀態更改時,向系統和應用程序發送通知,等等。一次多種顯示類型的多顯示器鏡像顯示,包括內建的顯示類型(本地)、HDMI顯示類型以及支持WIFI Display協議(MIRACAST),實現本地設備在遠程顯示器的鏡像顯示;

DisplayAdapterDisplayManagerService所依賴的集合組件,其為系統顯示,收集并發現物理顯示設備提供了適配器的作用。
目前有以下兩種方式的適配器供使用

  • 一、為本地顯示設備提供適配器。
  • 二、為開發者提供的模擬顯示適配器。

DisplayAdapterDisplayManagerService 是弱耦合關系。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());
    }
    1. 加載本地持久化數據
  • 2.發送消息注冊默認適配器
  • 3.對其他services或者app應用公開BinderServiceAIDL遠程服務
  • 4.對系統進程公開LocalServiceDisplayTransformManager

加載本地持久數據
/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();
            }
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。