Android 12 system source code_system bar management service (1) StatusBarManagerService service introduction

foreword

In the Android system, if other modules want to interact with the SystemUI module, they are basically inseparable from the service StatusBarManagerService. As the name suggests, StatusBarManagerService is a status bar management service, but in fact this service can not only manage the system status bar. It can manage most of the system bar components of the SystemUI module, such as the status bar, navigation bar, recent tasks, etc. In this article, let's first briefly understand this service.

1. SystemServer creates StatusBarManagerService service

1. Like most system services, the StatusBarManagerService service is also created in SystemServer:

frameworks/base/service/java/com/android/server/SystemServer.java

public final class SystemServer {
    
    
    
    public static void main(String[] args) {
    
    
        new SystemServer().run();
    }
    
   private void run() {
    
    
    	...代码省略...
        try {
    
    
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//启动引导服务
            startCoreServices();//启动核心服务
            startOtherServices();//启动其他服务
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
    
    
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
    
    
            traceEnd();
        }
    	...代码省略...
    }
}

2. The code related to startOtherServices method and WindowManagerService service startup is as follows.

public final class SystemServer {
    
    
  
  private ActivityManagerService mActivityManagerService;
  private boolean mOnlyCore;
  private boolean mFirstBoot;

  private void startOtherServices() {
    
    
          ...代码省略...
       	StatusBarManagerService statusBar = null;
          ...代码省略...
        boolean isWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
          ...代码省略...    
        if (!isWatch) {
    
    
          traceBeginAndSlog("StartStatusBarManagerService");
           try {
    
    
                //系统栏管理服务
                statusBar = new StatusBarManagerService(context, wm);
                ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
            } catch (Throwable e) {
    
    
                reportWtf("starting StatusBarManagerService", e);
            }
            traceEnd();
        }
        ...代码省略...            
    }
}     

Two, StatusBarManagerService class definition

2.1 Construction method

frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
    
    
    /**
     * 构造方法
     */
    public StatusBarManagerService(Context context) {
    
    
        mContext = context;

        LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
        LocalServices.addService(GlobalActionsProvider.class, mGlobalActionsProvider);

        // We always have a default display.
        final UiState state = new UiState();
        mDisplayUiState.put(DEFAULT_DISPLAY, state);

        final DisplayManager displayManager =
                (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
        displayManager.registerDisplayListener(this, mHandler);
        mActivityTaskManager = LocalServices.getService(ActivityTaskManagerInternal.class);
    }

}

2.2 Inherited parent class

StatusBarManagerService inherits from IStatusBarService.Stub, and the IStatusBarService.aidl file is shown below.

frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl

interface IStatusBarService
{
    
    
    @UnsupportedAppUsage
    void expandNotificationsPanel();
    @UnsupportedAppUsage
    void collapsePanels();
    void togglePanel();
    @UnsupportedAppUsage
    void disable(int what, IBinder token, String pkg);
    void disableForUser(int what, IBinder token, String pkg, int userId);
    void disable2(int what, IBinder token, String pkg);
    void disable2ForUser(int what, IBinder token, String pkg, int userId);
    int[] getDisableFlags(IBinder token, int userId);
    void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
    @UnsupportedAppUsage
    void setIconVisibility(String slot, boolean visible);
    @UnsupportedAppUsage
    void removeIcon(String slot);
    void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
            boolean showImeSwitcher, boolean isMultiClientImeEnabled);
    void expandSettingsPanel(String subPanel);

    // ---- Methods below are for use by the status bar policy services ----
    // You need the STATUS_BAR_SERVICE permission
    RegisterStatusBarResult registerStatusBar(IStatusBar callbacks);
    void onPanelRevealed(boolean clearNotificationEffects, int numItems);
    void onPanelHidden();
    // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
    void clearNotificationEffects();
    void onNotificationClick(String key, in NotificationVisibility nv);
    void onNotificationActionClick(String key, int actionIndex, in Notification.Action action, in NotificationVisibility nv, boolean generatedByAssistant);
    void onNotificationError(String pkg, String tag, int id,
            int uid, int initialPid, String message, int userId);
    void onClearAllNotifications(int userId);
    void onNotificationClear(String pkg, int userId, String key,
            int dismissalSurface, int dismissalSentiment, in NotificationVisibility nv);
    void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys,
            in NotificationVisibility[] noLongerVisibleKeys);
    void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded, in int notificationLocation);
    void onNotificationDirectReplied(String key);
    void onNotificationSmartSuggestionsAdded(String key, int smartReplyCount, int smartActionCount,
            boolean generatedByAsssistant, boolean editBeforeSending);
    void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply,
            in int notificationLocation, boolean modifiedBeforeSending);
    void onNotificationSettingsViewed(String key);
    void onNotificationBubbleChanged(String key, boolean isBubble, int flags);
    void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed, boolean isBubbleSuppressed);
    void hideCurrentInputMethodForBubbles();
    void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
    void clearInlineReplyUriPermissions(String key);
    void onNotificationFeedbackReceived(String key, in Bundle feedback);

    void onGlobalActionsShown();
    void onGlobalActionsHidden();

    /**
     * These methods are needed for global actions control which the UI is shown in sysui.
     */
    void shutdown();
    void reboot(boolean safeMode);

    void addTile(in ComponentName tile);
    void remTile(in ComponentName tile);
    void clickTile(in ComponentName tile);
    @UnsupportedAppUsage
    void handleSystemKey(in int key);

    /**
     * Methods to show toast messages for screen pinning
     */
    void showPinningEnterExitToast(boolean entering);
    void showPinningEscapeToast();

    // Used to show the authentication dialog (Biometrics, Device Credential)
    void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
            in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
            int userId, long operationId, String opPackageName, long requestId,
            int multiSensorConfig);

    // Used to notify the authentication dialog that a biometric has been authenticated
    void onBiometricAuthenticated();
    // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
    void onBiometricHelp(int modality, String message);
    // Used to show an error - the dialog will dismiss after a certain amount of time
    void onBiometricError(int modality, int error, int vendorCode);
    // Used to hide the authentication dialog, e.g. when the application cancels authentication
    void hideAuthenticationDialog();

    /**
     * Sets an instance of IUdfpsHbmListener for UdfpsController.
     */
    void setUdfpsHbmListener(in IUdfpsHbmListener listener);

    /**
     * Show a warning that the device is about to go to sleep due to user inactivity.
     */
    void showInattentiveSleepWarning();

    /**
     * Dismiss the warning that the device is about to go to sleep due to user inactivity.
     */
    void dismissInattentiveSleepWarning(boolean animated);

    /**
     * Notifies SystemUI to start tracing.
     */
    void startTracing();

    /**
     * Notifies SystemUI to stop tracing.
     */
    void stopTracing();

    /**
     * Returns whether SystemUI tracing is enabled.
     */
    boolean isTracing();

    /**
     * If true, suppresses the ambient display from showing. If false, re-enables the ambient
     * display.
     */
    void suppressAmbientDisplay(boolean suppress);

}

2.3 Implemented interface

StatusBarManagerService implements DisplayListener, the interface is shown below.

frameworks/base/core/java/android/hardware/display/DisplayManager.java

public final class DisplayManager {
    
    
    /**
     * Listens for changes in available display devices.
     */
    public interface DisplayListener {
    
    
        /**
         * Called whenever a logical display has been added to the system.
         * Use {@link DisplayManager#getDisplay} to get more information about
         * the display.
         *
         * @param displayId The id of the logical display that was added.
         */
        void onDisplayAdded(int displayId);

        /**
         * Called whenever a logical display has been removed from the system.
         *
         * @param displayId The id of the logical display that was removed.
         */
        void onDisplayRemoved(int displayId);

        /**
         * Called whenever the properties of a logical {@link android.view.Display},
         * such as size and density, have changed.
         *
         * @param displayId The id of the logical display that changed.
         */
        void onDisplayChanged(int displayId);
    }
}

2.4 Common attributes

public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
    
    
    private final Context mContext;

    private final Handler mHandler = new Handler();
    private NotificationDelegate mNotificationDelegate;
    private volatile IStatusBar mBar;
    private final ArrayMap<String, StatusBarIcon> mIcons = new ArrayMap<>();

    // for disabling the status bar
    private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
    private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
    private final IBinder mSysUiVisToken = new Binder();

    private final Object mLock = new Object();
    private final DeathRecipient mDeathRecipient = new DeathRecipient();
    private final ActivityTaskManagerInternal mActivityTaskManager;
    private int mCurrentUserId;
    private boolean mTracingEnabled;

    private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
    @GuardedBy("mLock")
    private IUdfpsHbmListener mUdfpsHbmListener;

    /**
     * Private API used by NotificationManagerService.
     */
    private final StatusBarManagerInternal mInternalService = new StatusBarManagerInternal() {
    
    
        private boolean mNotificationLightOn;

        @Override
        public void setNotificationDelegate(NotificationDelegate delegate) {
    
    
            mNotificationDelegate = delegate;
        }

        @Override
        public void showScreenPinningRequest(int taskId) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showScreenPinningRequest(taskId);
                } catch (RemoteException e) {
    
    
                }
            }
        }

        @Override
        public void showAssistDisclosure() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showAssistDisclosure();
                } catch (RemoteException e) {
    
    
                }
            }
        }

        @Override
        public void startAssist(Bundle args) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.startAssist(args);
                } catch (RemoteException e) {
    
    
                }
            }
        }

        @Override
        public void onCameraLaunchGestureDetected(int source) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.onCameraLaunchGestureDetected(source);
                } catch (RemoteException e) {
    
    
                }
            }
        }

        /**
         * Notifies the status bar that a Emergency Action launch gesture has been detected.
         *
         * TODO (b/169175022) Update method name and docs when feature name is locked.
         */
        @Override
        public void onEmergencyActionLaunchGestureDetected() {
    
    
            if (SPEW) Slog.d(TAG, "Launching emergency action");
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.onEmergencyActionLaunchGestureDetected();
                } catch (RemoteException e) {
    
    
                    if (SPEW) Slog.d(TAG, "Failed to launch emergency action");
                }
            }
        }

        @Override
        public void setDisableFlags(int displayId, int flags, String cause) {
    
    
            StatusBarManagerService.this.setDisableFlags(displayId, flags, cause);
        }

        @Override
        public void toggleSplitScreen() {
    
    
            enforceStatusBarService();
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.toggleSplitScreen();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void appTransitionFinished(int displayId) {
    
    
            enforceStatusBarService();
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.appTransitionFinished(displayId);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void toggleRecentApps() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.toggleRecentApps();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void setCurrentUser(int newUserId) {
    
    
            if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
            mCurrentUserId = newUserId;
        }


        @Override
        public void preloadRecentApps() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.preloadRecentApps();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void cancelPreloadRecentApps() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.cancelPreloadRecentApps();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void showRecentApps(boolean triggeredFromAltTab) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showRecentApps(triggeredFromAltTab);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.hideRecentApps(triggeredFromAltTab, triggeredFromHomeKey);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void collapsePanels() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.animateCollapsePanels();
                } catch (RemoteException ex) {
    
    
                }
            }
        }

        @Override
        public void dismissKeyboardShortcutsMenu() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.dismissKeyboardShortcutsMenu();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void toggleKeyboardShortcutsMenu(int deviceId) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.toggleKeyboardShortcutsMenu(deviceId);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void showChargingAnimation(int batteryLevel) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showWirelessChargingAnimation(batteryLevel);
                } catch (RemoteException ex){
    
    
                }
            }
        }

        @Override
        public void showPictureInPictureMenu() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showPictureInPictureMenu();
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void setWindowState(int displayId, int window, int state) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.setWindowState(displayId, window, state);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void appTransitionPending(int displayId) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.appTransitionPending(displayId);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void appTransitionCancelled(int displayId) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.appTransitionCancelled(displayId);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
                long statusBarAnimationsDuration) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.appTransitionStarting(
                            displayId, statusBarAnimationsStartTime, statusBarAnimationsDuration);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void setTopAppHidesStatusBar(boolean hidesStatusBar) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.setTopAppHidesStatusBar(hidesStatusBar);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public boolean showShutdownUi(boolean isReboot, String reason) {
    
    
            if (!mContext.getResources().getBoolean(R.bool.config_showSysuiShutdown)) {
    
    
                return false;
            }
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showShutdownUi(isReboot, reason);
                    return true;
                } catch (RemoteException ex) {
    
    }
            }
            return false;
        }

        // TODO(b/118592525): support it per display if necessary.
        @Override
        public void onProposedRotationChanged(int rotation, boolean isValid) {
    
    
            if (mBar != null){
    
    
                try {
    
    
                    mBar.onProposedRotationChanged(rotation, isValid);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void onDisplayReady(int displayId) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.onDisplayReady(displayId);
                } catch (RemoteException ex) {
    
    }
            }
        }

        @Override
        public void onRecentsAnimationStateChanged(boolean running) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.onRecentsAnimationStateChanged(running);
                } catch (RemoteException ex) {
    
    }
            }

        }

        @Override
        public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
                AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
                @Behavior int behavior, InsetsVisibilities requestedVisibilities,
                String packageName) {
    
    
            getUiState(displayId).setBarAttributes(appearance, appearanceRegions,
                    navbarColorManagedByIme, behavior, requestedVisibilities, packageName);
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.onSystemBarAttributesChanged(displayId, appearance, appearanceRegions,
                            navbarColorManagedByIme, behavior, requestedVisibilities, packageName);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void showTransient(int displayId, @InternalInsetsType int[] types,
                boolean isGestureOnSystemBar) {
    
    
            getUiState(displayId).showTransient(types);
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showTransient(displayId, types, isGestureOnSystemBar);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void abortTransient(int displayId, @InternalInsetsType int[] types) {
    
    
            getUiState(displayId).clearTransient(types);
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.abortTransient(displayId, types);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void showToast(int uid, String packageName, IBinder token, CharSequence text,
                IBinder windowToken, int duration,
                @Nullable ITransientNotificationCallback callback) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showToast(uid, packageName, token, text, windowToken, duration, callback);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void hideToast(String packageName, IBinder token) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.hideToast(packageName, token);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void requestWindowMagnificationConnection(boolean request) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.requestWindowMagnificationConnection(request);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.handleWindowManagerLoggingCommand(args, outFd);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.setNavigationBarLumaSamplingEnabled(displayId, enable);
                } catch (RemoteException ex) {
    
     }
            }
        }

        @Override
        public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
    
    
            synchronized (mLock) {
    
    
                mUdfpsHbmListener = listener;
            }
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.setUdfpsHbmListener(listener);
                } catch (RemoteException ex) {
    
     }
            }
        }
    };

    private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
    
    
        @Override
        public boolean isGlobalActionsDisabled() {
    
    
            // TODO(b/118592525): support global actions for multi-display.
            final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
            return (disabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
        }

        @Override
        public void setGlobalActionsListener(GlobalActionsProvider.GlobalActionsListener listener) {
    
    
            mGlobalActionListener = listener;
            mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
        }

        @Override
        public void showGlobalActions() {
    
    
            if (mBar != null) {
    
    
                try {
    
    
                    mBar.showGlobalActionsMenu();
                } catch (RemoteException ex) {
    
    }
            }
        }
    };

}

Guess you like

Origin blog.csdn.net/abc6368765/article/details/131003772