DisplayManagerService(一)

Androidの開発は非常に大きな要約記事をお勧めします:お気に入りへようこそ
非常にアンドロイドをお勧めプログラマ、Androidの開発者は、必要不可欠なスキルを必要とします

この資料に記載されているAndroidこの記事を読んで知識の開発の一部を、次のことを刈り取ります。

開始1.DisplayManagerService
2.DisplayManagerService役割
3.DisplayManagerService継承
のコンストラクタ4.DisplayManagerService
ONSTART方法の5.DisplayManagerService
onBootPhase(INT相)方法の6.DisplayManagerServiceを

はじめに
、後続のコードを含む、コードのクラスパスとここでは、以下のディレクトリを参照してください。


frameworks\base\services\java\com\android\server\SystemServer.java

frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java

1.DisplayManagerService開始

DisplayManagerServiceがあるSystemServer
startBootstrapServicesガイドステージを介してstartServiceブート・コードは次の通りであります:

public final class SystemServer {
    ...

    private void startBootstrapServices() {
        ...
        // Display manager is needed to provide display metrics before package manager
        // starts up.
        traceBeginAndSlog("StartDisplayManager");
        //1.启动 DisplayManagerService
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
        traceEnd();
        ...
     }
    ...

}

2.DisplayManagerServiceの役割

DisplayManagerServiceは現在、物理的なディスプレイに接続された制御装置は、ロジックを表示する方法を決定し、ディスプレイのライフサイクルを管理するために使用される、とするとき、状態変化通知がシステムとアプリケーション、等に送られます。

DisplayAdapterはDisplayManagerServiceのコンポーネントのセットは、表示システムであり、依存する、表示装置を回収し、アダプタの物理的な効果をもたらすことが見出されました。
用のアダプタを使用する2つの方法があります
ローカル表示装置の提供アダプター。
第二に、シミュレーションは、ディスプレイアダプタを開発者に提供します。

DisplayAdapterDisplayManagerService弱い結合関係。DisplayAdapter登録することによりDisplayManagerService、クラスDisplayAdapter.Listener非同期通信を。

そうするには二つの理由がある
巧みな機能のこれら2つのクラスをカプセル化するには、
DisplayAdapter:各表示装置の処理
DisplayManagerServiceグローバル表示状態を処理します:
第二に、非同期表示装置の発見の可能性を排除するデッドロックにつながりました

同期(ゲンロック)

ディスプレイマネージャが複数のスレッドによってアクセスすることができるので、同期ロックので、少し複雑になります。場合は特にウィンドウマネージャ(window manager)ドロートランザクションコールディスプレイマネージャを(維持しながらdisplay manager)、ウィンドウマネージャは、それがすぐに適用され、変更することを期待しています。残念ながら、ディスプレイマネージャは、( display manager非同期にすべてを行うことはできません。
この問題を解決するために、すべてのオブジェクトマネージャを示すことは同じロックを保持しなければなりません。私たちは、それがユニークなこのロック同期ロックと呼ばれます。

3.DisplayManagerServiceの継承

DisplayManagerService継承されてSystemServiceからSystemServerスタート。

public final class DisplayManagerService extends SystemService {
   ... 
}

エコプリンティングは、(onBootPhase(int型、コンストラクタ、ONSTART()は、次の方法のライフサイクルを書き換えるためにそれを使用して、基本クラスのシステム・サービスおよび関連するカテゴリである ))、 およびすべてのライフサイクル本土の方法があることができsystem server、メインスレッド・サイクル・コール。
施工方法
、システムの初期化中にはSystemService、時間と呼ばれています。
ONSTART()メソッドの
Services実行時間が呼び出され、今回は発表するために必要なBinderインタフェース
publishBinderService(文字列、IBinderに)メソッドを
、時には同時にローカルサービスを発表しましたpublishLocalService共同システムが呼び出しを処理します。
onBootPhase(int)メソッド
まで、スタートアップ段階では、複数回呼び出されるPHASE_BOOT_COMPLETED
以下のDisplayManagerService使用方法が来て、このプロセスに従ったものです。

4.DisplayManagerServiceコンストラクタ

DisplayManagerService 次のようにコンストラクタのコードは次のとおりです。

    public DisplayManagerService(Context context) {
        this(context, new Injector());
    }

    @VisibleForTesting
    DisplayManagerService(Context context, Injector injector) {
        super(context);
        mInjector = injector;
        mContext = context;
        // mHandler 用来发送 display 消息
        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
        mUiHandler = UiThread.getHandler();
        mDisplayAdapterListener = new DisplayAdapterListener();
        mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
        mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
            com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);

        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
    }

ONSTARTの5.DisplayManagerService方法

ONSTART主負荷が(主に高いワイドディスプレイ装置)データを永続化、送信するMSG_REGISTER_DEFAULT_DISPLAY_ADAPTERSメッセージを、発表Binder、Local Serviceなど。onStart()ここに方法は次のとおりです。

   @Override
    public void onStart() {
        // We need to pre-load the persistent data store so it's ready before the default display
        // adapter is up so that we have it's configuration. We could load it lazily, but since
        // we're going to have to read it in eventually we may as well do it here rather than after
        // we've waited for the display to register itself with us.
        synchronized(mSyncRoot) {
                        //1. 加载本地持久化数据
            mPersistentDataStore.loadIfNeeded();
            loadStableDisplayValuesLocked();
        }
 // 2. 发送MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS 消息       mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
        //3.对外公布Binder、Local 服务
        publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                true /*allowIsolated*/);
        publishLocalService(DisplayManagerInternal.class, new LocalService());
        publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
    }
  1. ローカル永続データをロードします
 private 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 | XmlPullParserException ex) {
            Slog.w(TAG, "Failed to load tv input manager persistent store data.", ex);
            clearState();
        } finally {
            IoUtils.closeQuietly(is);
        }
    }

2. MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS次のようにメッセージ処理方法です。

  private final class DisplayManagerHandler extends Handler {
        public DisplayManagerHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
                    // a.注册默认的显示适配器
                    registerDefaultDisplayAdapters();
                    break;

                case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
                    registerAdditionalDisplayAdapters();
                    break;

         ...
    }

registerDefaultDisplayAdapters以下の方法である:
registerDefaultDisplayAdapters主な機能が追加表示装置に登録することであるmDisplayAdaptersアダプタを。

 private void registerDefaultDisplayAdapters() {
        // Register default display adapters.
        synchronized (mSyncRoot) {
            // b. 主要的显示适配器,注册本地适配器lock
            registerDisplayAdapterLocked(new LocalDisplayAdapter(
                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

            ...
        }

B。メインディスプレイアダプタ、アダプタロックローカル登録 registerDisplayAdapterLocked

    private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
        mDisplayAdapters.add(adapter);
        adapter.registerLocked();
    }

LocalDisplayAdapterは継承されたDisplayAdapterを主にローカルディスプレイデバイスアダプタを提供するために、。

final class LocalDisplayAdapter extends DisplayAdapter {

   ...
    // Called with SyncRoot lock held.
    public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
            Context context, Handler handler, Listener listener) {
        super(syncRoot, context, handler, listener, TAG);
    }

    // registerDisplayAdapterLocked 中 调用 adapter.registerLocked();
   @Override
    public void registerLocked() {
        super.registerLocked();
       // 1.创建显示设备热插拔时间的监听器
        mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());

        for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
            //2.连接显示设备
            tryConnectDisplayLocked(builtInDisplayId);
        }
    }
   
    ...
}

1.次のように、コードの一部を表示装置ホットスワップ時間リスナーを作成します。

    private final class HotplugDisplayEventReceiver extends DisplayEventReceiver {
        public HotplugDisplayEventReceiver(Looper looper) {
            super(looper, VSYNC_SOURCE_APP);
        }

        @Override
        public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
            synchronized (getSyncRoot()) {
                if (connected) {
                   //连接显示设备
                    tryConnectDisplayLocked(builtInDisplayId);
                } else {
                    tryDisconnectDisplayLocked(builtInDisplayId);
                }
            }
        }
    }

2.次のように表示装置は、コードの一部に接続されています。

    private void tryConnectDisplayLocked(int builtInDisplayId) {
        IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
        if (displayToken != null) {
            SurfaceControl.PhysicalDisplayInfo[] configs =
                    SurfaceControl.getDisplayConfigs(displayToken);
           
            int activeConfig = SurfaceControl.getActiveConfig(displayToken);
            
            int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);

            int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
            LocalDisplayDevice device = mDevices.get(builtInDisplayId);
            if (device == null) {
                // Display was added.
                device = new LocalDisplayDevice(displayToken, builtInDisplayId,
                        configs, activeConfig, colorModes, activeColorMode);
                mDevices.put(builtInDisplayId, device);
                sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
            } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
                        colorModes, activeColorMode)) {
                // Display properties changed.
                sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
            }
        } else {
            // The display is no longer available. Ignore the attempt to add it.
            // If it was connected but has already been disconnected, we'll get a
            // disconnect event that will remove it from mDevices.
        }
    }

その後他のオンservices、及びアプリオープンpublishBinderServiceインターフェース

    /**
     * Publish the service so it is accessible to other services and apps.
     */
    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }

次いで、システムは、オープン処理publishLocalServiceのインタフェースを

 /**
     * Publish the service so it is only accessible to the system process.
     */
    protected final <T> void publishLocalService(Class<T> type, T service) {
        LocalServices.addService(type, service);
    }

onBootPhase(INT相)法の6.DisplayManagerService

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
            synchronized (mSyncRoot) {
                long timeout = SystemClock.uptimeMillis()
                        + mInjector.



                ();
                while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
                        mVirtualDisplayAdapter == null) {
                    long delay = timeout - SystemClock.uptimeMillis();
                    if (delay <= 0) {
                        throw new RuntimeException("Timeout waiting for default display "
                                + "to be initialized. DefaultDisplay="
                                + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
                                + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
                    }
                    if (DEBUG) {
                        Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
                    }
                    try {
                        mSyncRoot.wait(delay);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }
    }

間違った場所、あなたの提案や修正を歓迎している場合これまでのところ、本明細書に、これは、終了しました。同時に、あなたの注意を楽しみにして、お読みいただきありがとうございました、ありがとうございました!

マイクロチャネル国民の関心番号:プログラマーアンドロイド、福祉を受けます

おすすめ

転載: www.cnblogs.com/wangjie1990/p/11327391.html