写在前面
StatusBarManagerService中API涉及systemui的多个模块;本篇主要介绍StatusBarManagerService中与通知栏相关的API和几个通用API。
因为我对系统UI了解的不全,其他API暂不整理,怕误人子弟。。
通知栏相关函数解析
1.展开通知栏
void animateExpandNotificationsPanel()
// CentralSurfacesCommandQueueCallbacks@Override
public void animateExpandNotificationsPanel() {if (CentralSurfaces.SPEW) {Log.d(CentralSurfaces.TAG,"animateExpand: mExpandedVisible=" + mShadeController.isExpandedVisible());}if (!mCommandQueue.panelsEnabled()) {return;}mShadeViewController.expandToNotifications();
}// NotificationPanelViewController@Override
public void expandToNotifications() {if (mSplitShadeEnabled && (isShadeFullyExpanded() || isExpandingOrCollapsing())) {return;}if (mQsController.getExpanded()) {mQsController.flingQs(0, FLING_COLLAPSE);} else {expand(true /* animate */);}
}
2.关闭通知栏
void animateCollapsePanels(int flags, boolean force)
// CentralSurfacesCommandQueueCallbacks@Override
public void animateCollapsePanels(int flags, boolean force) {mShadeController.animateCollapsePanels(flags, force, false /* delayed */,1.0f /* speedUpFactor */);
}// ShadeControllerImpl@Override
public void animateCollapsePanels(int flags, boolean force, boolean delayed,float speedUpFactor) {if (!force && mStatusBarStateController.getState() != StatusBarState.SHADE) {runPostCollapseRunnables();return;}if (SPEW) {Log.d(TAG,"animateCollapse(): mExpandedVisible=" + mExpandedVisible + "flags=" + flags);}if (getNotificationShadeWindowView() != null&& mNotificationPanelViewController.canBeCollapsed()&& (flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) {// release focus immediately to kick off focus change transitionmNotificationShadeWindowController.setNotificationShadeFocusable(false);mNotificationShadeWindowViewController.cancelExpandHelper();mNotificationPanelViewController.collapse(true, delayed, speedUpFactor);}
}
3.togglePanel
void togglePanel() 如果板子展开,就关闭;如果板子关闭,就展开
@Override
public void togglePanel() {if (mCentralSurfaces.isPanelExpanded()) {mShadeController.animateCollapseShade();} else {animateExpandNotificationsPanel();}
}
4.展开QS
原生通知栏上方区域有header和QS区域,QS(quick settings)区域提供了多个系统设置的快捷开关;
QS区域也可以进行展开和关闭,touch事件在NotificationShadeWindow中统一进行分发。
void animateExpandSettingsPanel(String obj)
@Override
public void animateExpandSettingsPanel(@Nullable String subPanel) {if (CentralSurfaces.SPEW) {Log.d(CentralSurfaces.TAG,"animateExpand: mExpandedVisible=" + mShadeController.isExpandedVisible());}if (!mCommandQueue.panelsEnabled()) {return;}// Settings are not available in setupif (!mDeviceProvisionedController.isCurrentUserSetup()) return;mShadeViewController.expandToQs();
}
5.addQsTile/remQsTile/clickTile
void addQsTile(ComponentName tile)
void remQsTile(ComponentName tile)
void clickTile(ComponentName tile)
Tile为quick settings区域的单个操作按钮;系统提供了三方增加/移除/点击对应tile的API。
@Override
public void addQsTile(ComponentName tile) {mQSHost.addTile(tile);
}// 触发点击tile@Override
public void clickTile(ComponentName tile) {// Can't inject this because it changes with the QS fragmentQSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();if (qsPanelController != null) {qsPanelController.clickTile(tile);}
}
通用相关函数解析
1.setImeWindowStatus
void setImeWindowStatus(int displayId, IBinder token, int vis,@BackDispositionMode int backDisposition, boolean showImeSwitcher)
当前输入法界面是否调起
// NavigationBar@Override
public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,boolean showImeSwitcher) {if (displayId != mDisplayId) {return;}boolean imeShown = mNavBarHelper.isImeShown(vis);showImeSwitcher = imeShown && showImeSwitcher;int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,imeShown, showImeSwitcher);if (hints == mNavigationIconHints) return;setNavigationIconHints(hints);checkBarModes();updateSystemUiStateFlags();
}
2.showToast/hideToast
通过systemui展示toast,供无界面的系统应用使用;弹toast需要context
void showToast(int uid, String packageName, IBinder token, CharSequence text,IBinder windowToken, int duration,@Nullable ITransientNotificationCallback callback, int displayId)
void hideToast(String packageName, IBinder token)
@Override
@MainThread
public void showToast(int uid, String packageName, IBinder token, CharSequence text,IBinder windowToken, int duration, @Nullable ITransientNotificationCallback callback,int displayId) {Runnable showToastRunnable = () -> {UserHandle userHandle = UserHandle.getUserHandleForUid(uid);Context context = mContext.createContextAsUser(userHandle, 0);DisplayManager mDisplayManager = mContext.getSystemService(DisplayManager.class);Display display = mDisplayManager.getDisplay(displayId);Context displayContext = context.createDisplayContext(mDisplayManager.getDisplay(displayId));mToast = mToastFactory.createToast(mContext /* sysuiContext */, text, packageName,userHandle.getIdentifier(), mOrientation);if (mToast.getInAnimation() != null) {mToast.getInAnimation().start();}mCallback = callback;mPresenter = new ToastPresenter(displayContext, mIAccessibilityManager,mNotificationManager, packageName);// Set as trusted overlay so touches can pass through toastsmPresenter.getLayoutParams().setTrustedOverlay();mToastLogger.logOnShowToast(uid, packageName, text.toString(), token.toString());mPresenter.show(mToast.getView(), token, tempWindowToken, duration, mToast.getGravity(),mToast.getXOffset(), mToast.getYOffset(), mToast.getHorizontalMargin(),mToast.getVerticalMargin(), mCallback, mToast.hasCustomAnimation());};if (mToastOutAnimatorListener != null) {// if we're currently animating out a toast, show new toast after prev toast is hiddenmToastOutAnimatorListener.setShowNextToastRunnable(showToastRunnable);} else if (mPresenter != null) {// if there's a toast already showing that we haven't tried hiding yet, hide it and// then show the next toast after its hidden animation is donehideCurrentToast(showToastRunnable);} else {// else, show this next toast immediatelyshowToastRunnable.run();}
}@Override
@MainThread
public void hideToast(String packageName, IBinder token) {if (mPresenter == null || !Objects.equals(mPresenter.getPackageName(), packageName)|| !Objects.equals(mPresenter.getToken(), token)) {Log.w(TAG, "Attempt to hide non-current toast from package " + packageName);return;}mToastLogger.logOnHideToast(packageName, token.toString());hideCurrentToast(null);
}
写在后面
如果文章中有错误的地方,希望各位大佬们批评指正~
If you like this article, it is written by Johnny Deng.
If not, I don’t know who wrote it.