Android 5.1 SystemUIのSttus Barロードフロー


Soは、前回に続き、アイコンの記載のxmlレイアウトを大まかに見ましたが、誰かに聞いてみました.これは吊り用ですか? はい、私も自分に聞いたことがありますが、ちょっと吊るしています.これで問題を解決してくれました.
偽のイメージを分析したいです.levelはどうして充電する時やっと表示して、私達は今レイアウトの中で対応するIDを探し当てて、そんなに簡単に文脈を探し当てません. 
OKです.今日はスターバーのアイコンがどうやってレイアウトに読み込まれているかを見ます.もちろんもっと詳しくなります.
それともその話ですか?巨人のJJに立ちがちです.Android 4.0 ICS SystemUIを参考にしました.SttusBarロードの流れを分析します.
System Server.java->main()->run()
  if (!disableSystemUI) {
                try {
                    Slog.i(TAG, "Status Bar");
                    statusBar = new StatusBarManagerService(context, wm);
                    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                } catch (Throwable e) {
                    reportWtf("starting StatusBarManagerService", e);
                }
    }
私たちはStatus BarManager Serviceを取得したのを見ました.そしてそれをServiceManagerに入れました.ここでContactxt.STATUS_で.BAR_SERVIERをマークとして、
後からの入手が便利になりました.
今StutsBarManagerServiceを見てみます.何をくわえて遊んでいますか?
Status BarManager Service.java
StatusBarManagerService.java			
    public StatusBarManagerService(Context context, WindowManagerService windowManager) {
        mContext = context;
        mWindowManager = windowManager;
		
        final Resources res = context.getResources();
		//private StatusBarIconList mIcons = new StatusBarIconList();
		//   com.android.internal.R.array.config_statusBarIcons      
        mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.config_statusBarIcons));

        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);

        /// M: DM Lock Feature.
        registerDMLock();
    }
Status BarManagerService extens IStatus BarService.StubはIBinderの対象であり、Android AIDLはこれに対して詳しく説明しています.これはプロセス伝達に用いられて、プロセス間の通信を実現します.詳しくないなら、Android aidl Binderフレームワークを紹介します.
mIcons=new Storts BarIconList()このStatus BarIconListは、Parcembleインターフェース、すなわち、データを逐次的に記憶し、転送するためのプログレッシブデータを実現します.
JavaのSerializableとある場合は効率的に、AndroidのParcerbaleインターフェースの使い方を紹介します.
ここでStatus BarIconListの外部コードを貼りません.つまりデータを記憶して読み取ります.Javaのプログレッシブ化を知っていれば分かります.
今はcomp.android.internal.R.array.co nfigを見ます.status BarIcons
<string-array name="config_statusBarIcons">
       <item><xliff:g id="id">ime</xliff:g></item>
       <item><xliff:g id="id">sync_failing</xliff:g></item>
       <item><xliff:g id="id">sync_active</xliff:g></item>
       <item><xliff:g id="id">cast</xliff:g></item>
       <item><xliff:g id="id">hotspot</xliff:g></item>
       <item><xliff:g id="id">location</xliff:g></item>
       <item><xliff:g id="id">bluetooth</xliff:g></item>
       <item><xliff:g id="id">nfc</xliff:g></item>
       <!-- M: Support "SystemUI Headset icon" feature. -->
       <item><xliff:g id="id">headset</xliff:g></item>
       <item><xliff:g id="id">tty</xliff:g></item>
       <item><xliff:g id="id">speakerphone</xliff:g></item>
       <item><xliff:g id="id">zen</xliff:g></item>
       <item><xliff:g id="id">mute</xliff:g></item>
       <item><xliff:g id="id">volume</xliff:g></item>
       <item><xliff:g id="id">wifi</xliff:g></item>
       <item><xliff:g id="id">cdma_eri</xliff:g></item>
       <item><xliff:g id="id">data_connection</xliff:g></item>
       <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
       <item><xliff:g id="id">phone_signal</xliff:g></item>
       <item><xliff:g id="id">battery</xliff:g></item>
       <item><xliff:g id="id">alarm_clock</xliff:g></item>
       <item><xliff:g id="id">secure</xliff:g></item>
       <item><xliff:g id="id">clock</xliff:g></item>
    </string-array>
まとめてみます.SystemServerプロセスでは、Status BarManagerServiceオブジェクトstatus Barを維持しています.statusBarオブジェクトはStuts BarIconListオブジェクトmIconsを維持しています.これによりSystemServerはmIconsを維持しています.
前の記事では、status barをロードする入り口がPhone Status Bar.javaです.
Phone Status Bar.java
    @Override
    public void start() {
	//...
	super.start(); // calls createAndAddWindows()
	//...
	addNavigationBar();

        // Lastly, call to the icon policy to install/update all the icons.
	//    ,      PhoneStatusBarPolicy.java       Icon
        mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController);

	}
まず第一歩を見て、super.start()はBaseStatusBar.javaを呼び出します.
    public void start() {
		//...
		mBarService = IStatusBarService.Stub.asInterface(
        ServiceManager.getService(Context.STATUS_BAR_SERVICE));
		//..
		// Connect in to the status bar manager service
        StatusBarIconList iconList = new StatusBarIconList();
		//   this,                
        mCommandQueue = new CommandQueue(this, iconList);

        int[] switches = new int[8];
        ArrayList<IBinder> binders = new ArrayList<IBinder>();
        try {
            mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
        } catch (RemoteException ex) {
            // If the system process isn't there we're doomed anyway.
        }
		//...
		// Set up the initial icon state
        int N = iconList.size();
        int viewIndex = 0;
        for (int i=0; i<N; i++) {
            StatusBarIcon icon = iconList.getIcon(i);
            if (icon != null) {
                addIcon(iconList.getSlot(i), i, viewIndex, icon);
                viewIndex++;
            }
        }
				
		
	}
mCommundQue=new CommundQue(this、iconList)
CommundQue extens IStatusBar.StubはIBinderオブジェクトであり、その中でもインターフェースを定義していますが、インターフェースの実現はPhone Status Bar.javaにあります.
Command Que.java
public interface Callbacks {
        public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
        public void updateIcon(String slot, int index, int viewIndex,
                StatusBarIcon old, StatusBarIcon icon);
        public void removeIcon(String slot, int index, int viewIndex);
        public void disable(int state, boolean animate);
        public void animateExpandNotificationsPanel();
        public void animateCollapsePanels(int flags);
        public void animateExpandSettingsPanel();
        public void setSystemUiVisibility(int vis, int mask);
        public void topAppWindowChanged(boolean visible);
        public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
                boolean showImeSwitcher);
        public void showRecentApps(boolean triggeredFromAltTab);
        public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
        public void toggleRecentApps();
        public void preloadRecentApps();
        public void cancelPreloadRecentApps();
        public void showSearchPanel();
        public void hideSearchPanel();
        public void setWindowState(int window, int state);
        public void buzzBeepBlinked();
        public void notificationLightOff();
        public void notificationLightPulse(int argb, int onMillis, int offMillis);
        public void showScreenPinningRequest();
        /// M: [SystemUI] Support "SIM indicator". @{
        public void showSimIndicator(String businessType);
        public void hideSimIndicator();
        /// @}
        /// M: [SystemUI] Support Smartbook Feature. @{
        public void dispatchStatusBarKeyEvent(KeyEvent event);
        /// @}
        ///M:BMW
        public void showRestoreButton(boolean flag);
    }

    public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
        mCallbacks = callbacks;
        mList = list;
    }
mBarService.register StutsBar(mCommmandQue、iconList、switch、binders);このmBarServiceはStatus BarManager Serviceの対象です.
Status BarManager Service.java
    @Override
    public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
            int switches[], List<IBinder> binders) {
        enforceStatusBarService();

        Slog.i(TAG, "registerStatusBar bar=" + bar);
        mBar = bar;
        synchronized (mIcons) {
	    // mIcons index icon   iconList 
            iconList.copyFrom(mIcons);
        }
        synchronized (mLock) {
            switches[0] = gatherDisableActionsLocked(mCurrentUserId);
            switches[1] = mSystemUiVisibility;
            switches[2] = mMenuVisible ? 1 : 0;
            switches[3] = mImeWindowVis;
            switches[4] = mImeBackDisposition;
            switches[5] = mShowImeSwitcher ? 1 : 0;
            binders.add(mImeToken);
        }
    }
iconList.co pyFrom(mIcons)ここでStatus BarManagerServiceで維持されているStuts BarIconListオブジェクトmIconsを、転送されたiconListにコピーします.
ここではmBarだけ注意してください.これはいったい何のために使われていますか?mBarはIStatusBarの対象、つまりCommmand Queだと知っています.
CommundQueのインターフェースの実現方法はPhone StatusBar.java(StatusBarをロードするインターフェース)で実現され、
だから、インタフェースをコントロールするのにいいです.Status BarManagerServiceというIBinderの対応するBinderドライバを取得したら、命令を送ります. 
Status BarManager Service extens IStatus BarService.Stub Command Que extens IStatusBar.Stubのインターフェースを呼び出します.
->Phone Status Bar.java(Status Barをロードするインターフェース)で実現すれば、コントロールインターフェースの目的を達成することができます.
だからこのmBarは大切です.後は使います. 
続いて見ます.BaseStartsBar.javaの中のStartの中の
// Set up the initial icon state
        int N = iconList.size();
        int viewIndex = 0;
        for (int i=0; i<N; i++) {
            StatusBarIcon icon = iconList.getIcon(i);
            if (icon != null) {
                addIcon(iconList.getSlot(i), i, viewIndex, icon);
                viewIndex++;
            }
        }
コメントを見てください.ここは初期化されたIcon stateに対してだけです.なぜですか?まだiconを設定していません.アイコンの名前だけ設定していますが、対応する画像はまだ設定されていません.ここでは初期化されたローディングと分かりさえすればいいです.
この部分は私の分析にあまり影響しないからです.
BaseStatus Bar implements CommandQue.calBacksですが、実現はサブタイプPhone Status Bar.javaの中にあります.
Phone Status Bar.javaで呼び出し
はい、super.start()の分析が終わりました.まとめて各アイコンのロードを初期化してレイアウトにします.しかし、名前をロードしただけで、写真がありません.
今は引き続きPhone Status Bar.javaの中の
 mIconPolicy=new Phone Status BarPolicy(mContect、mCastController、mHot spotController);
このクラスは実はBroadcastReceiverを受信することによってIconを更新することができます.
Phone Status Bar.java
public class PhoneStatusBarPolicy {
	private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Xlog.d(TAG, "onReceive:" + action);
            if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
                updateAlarm();
            }
            else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
                updateSyncState(intent);
            }
            else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
                    action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
                updateBluetooth();
            }
            else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
                    action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
                updateVolumeZen();
            }
            else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
                updateSimState(intent);
            }
            else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
                int currentTtyMode = intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
                    TelecomManager.TTY_MODE_OFF);
                updateTTY(currentTtyMode);
            }
            else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                updateAlarm();
                /// M: [Multi-User] register Alarm intent by user @{
                int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                registerAlarmClockChanged(newUserId, true);
                /// M: [Multi-User] register Alarm intent by user @}
            }
            /// M: [SystemUI] Support "Headset icon". @{
            else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
                updateHeadSet(intent);
            }
            /// @}
        }
    };
	
public PhoneStatusBarPolicy(Context context, CastController cast, HotspotController hotspot) {
        mContext = context;
        mCast = cast;
        mHotspot = hotspot;
        mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);

        // listen for broadcasts
        IntentFilter filter = new IntentFilter();
        //filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
        filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
        filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
        filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        /// M: [SystemUI] Support "Headset icon". @{
        filter.addAction(Intent.ACTION_HEADSET_PLUG);
        /// @}
        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
        /// M: [Multi-User] register Alarm intent by user
        registerAlarmClockChanged(UserHandle.USER_OWNER, false);

        // TTY status
        mService.setIcon(SLOT_TTY,  R.drawable.stat_sys_tty_mode, 0, null);
        mService.setIconVisibility(SLOT_TTY, false);
        /// M: [ALPS01870707] Get the TTY status when power on @{
        int settingsTtyMode = Settings.Secure.getInt(context.getContentResolver(),
                        Settings.Secure.TTY_MODE_ENABLED,
                        TelecomManager.TTY_MODE_OFF);
        updateTTY(settingsTtyMode);
        /// M: [ALPS01870707] Get the TTY status when power on @}

        // Cdma Roaming Indicator, ERI
        mService.setIcon(SLOT_CDMA_ERI, R.drawable.stat_sys_roaming_cdma_0, 0, null);
        mService.setIconVisibility(SLOT_CDMA_ERI, false);

        // bluetooth status
        updateBluetooth();

        // Alarm clock
        mService.setIcon(SLOT_ALARM_CLOCK, R.drawable.stat_sys_alarm, 0, null);
        mService.setIconVisibility(SLOT_ALARM_CLOCK, false);

        // Sync state
        mService.setIcon(SLOT_SYNC_ACTIVE, R.drawable.stat_sys_sync, 0, null);
        mService.setIconVisibility(SLOT_SYNC_ACTIVE, false);
        // "sync_failing" is obsolete: b/1297963

        // zen
        mService.setIcon(SLOT_ZEN, R.drawable.stat_sys_zen_important, 0, null);
        mService.setIconVisibility(SLOT_ZEN, false);

        // volume
        mService.setIcon(SLOT_VOLUME, R.drawable.stat_sys_ringer_vibrate, 0, null);
        mService.setIconVisibility(SLOT_VOLUME, false);
        updateVolumeZen();

        // cast
        // M: Remove CastTile when WFD is not support in quicksetting
        if (mCast != null) {
            mService.setIcon(SLOT_CAST, R.drawable.stat_sys_cast, 0, null);
            mService.setIconVisibility(SLOT_CAST, false);
            mCast.addCallback(mCastCallback);
        }

        // hotspot
        mService.setIcon(SLOT_HOTSPOT, R.drawable.stat_sys_hotspot, 0, null);
        mService.setIconVisibility(SLOT_HOTSPOT, mHotspot.isHotspotEnabled());
        mHotspot.addCallback(mHotspotCallback);
        /// M: [SystemUI] Support "Headset icon". @{
        mService.setIcon(SLOT_HEADSET, R.drawable.stat_sys_headset_with_mic, 0, null);
        mService.setIconVisibility(SLOT_HEADSET, false);
        /// @}
    }
	
}
構成方法において、一連の放送を登録し、ラジオによってiconを更新し、構造方法においてicon及び視認性を初期化したことが見られます.
prvate final Sttus BarManager mService;
mService.set IconとmService.set Icon VisibilityはIconとVisibilityを設置しています.ここでiconが現れます.
Status BarManager.java
    public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
        try {
            final IStatusBarService svc = getService();
            if (svc != null) {
                svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
                    contentDescription);
            }
        } catch (RemoteException ex) {
            // system process is dead anyway.
            throw new RuntimeException(ex);
        }
    }
	
	private synchronized IStatusBarService getService() {
        if (mService == null) {
            mService = IStatusBarService.Stub.asInterface(
                    ServiceManager.getService(Context.STATUS_BAR_SERVICE));
            if (mService == null) {
                Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
            }
        }
        return mService;
    }
ここでAIDLに関わるのはただ、具体的に自分の脳を補って、詳しく説明しません.svc.setIconははっきり言っています.Status BarManager Service.javaのsetIconを呼び出します.
	@Override
    public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
            String contentDescription) {
        enforceStatusBar();

        synchronized (mIcons) {
            int index = mIcons.getSlotIndex(slot);
            if (index < 0) {
                throw new SecurityException("invalid status bar icon slot: " + slot);
            }

            StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId,
                    iconLevel, 0,
                    contentDescription);
            //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
            mIcons.setIcon(index, icon);

            if (mBar != null) {
                try {
		   //      
                    mBar.setIcon(index, icon);
                } catch (RemoteException ex) {
                }
            }
        }
    }
Status BarIconList implements Parcellableの対象mIconsは、String slaotを通じて対応するindexを取得した. 
そして、アイコンのindexとiconの値をmIcons.setIconで設定します.
このStatus BarIconもimplements Parcell ableです.
mBar.setIcon(index,icon);このmBarはどこから来ましたか?前にもう入っています.実はCommandQue.javaのsetIconを呼び出しました.最後にmCallbacks.addIconです.
このmCallbacksの実現関数は、Phone StatusBar.javaの中で、CommmandQueの中のコードが貼り出されなくなりました.
Phone Status Bar.java->addIcon
	    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
        if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
                + " icon=" + icon);
        StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
        view.set(icon);
		//add in mStatusIcons
        mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, mIconSize));
        view = new StatusBarIconView(mContext, slot, null);
        view.set(icon);
        mStatusIconsKeyguard.addView(view, viewIndex, new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, mIconSize));
    }
ここのレイアウトはロードしました.iconのDrawable資源もロードしました.完璧ですか?ちょっと遅くなりました.UML図は明日補充します.