FW SystemUI Keyguard解析(二)

文章目錄

      • CTS之Keyguard Menu事件處理

CTS之Keyguard Menu事件處理

事件觸發點:
NotificationShadeWindowViewController.dispatchKeyEvent
設置setInteractionEventHandler回調之后通過NotificationShadeWindowView 觸發
調用到return mService.onMenuPressed();

public class NotificationShadeWindowViewController {public void setupExpandedStatusBar() {mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {//省略代碼@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {boolean down = event.getAction() == KeyEvent.ACTION_DOWN;switch (event.getKeyCode()) {case KeyEvent.KEYCODE_BACK:if (!down) {mService.onBackPressed();}return true;case KeyEvent.KEYCODE_MENU:if (!down) {return mService.onMenuPressed();//☆☆☆☆}break;case KeyEvent.KEYCODE_SPACE:if (!down) {return mService.onSpacePressed();}break;case KeyEvent.KEYCODE_VOLUME_DOWN:case KeyEvent.KEYCODE_VOLUME_UP:if (mStatusBarStateController.isDozing()) {MediaSessionLegacyHelper.getHelper(mView.getContext()).sendVolumeKeyEvent(event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);return true;}break;}return false;}});}
}public class NotificationShadeWindowView extends FrameLayout {@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {if (mInteractionEventHandler.interceptMediaKey(event)) {return true;}if (super.dispatchKeyEvent(event)) {return true;}return mInteractionEventHandler.dispatchKeyEvent(event);//☆☆☆☆}
}

以上通過接口會調用到
StatusBar類中去

public class StatusBar{public boolean onMenuPressed() {if (shouldUnlockOnMenuPressed()) {mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL /* flags */, true /* force */);//☆☆☆☆return true;}return false;}}public class ShadeControllerImpl implements ShadeController {@Overridepublic void animateCollapsePanels(int flags, boolean force) {animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);//☆☆☆☆}@Overridepublic 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=" + getStatusBar().isExpandedVisible()+ " flags=" + flags);}if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {getStatusBar().postHideRecentApps();}// TODO(b/62444020): remove when this bug is fixedLog.v(TAG, "NotificationShadeWindow: " + getNotificationShadeWindowView()+ " canPanelBeCollapsed(): "+ getNotificationPanelViewController().canPanelBeCollapsed());if (getNotificationShadeWindowView() != null&& getNotificationPanelViewController().canPanelBeCollapsed()) {// release focus immediately to kick off focus change transitionmNotificationShadeWindowController.setNotificationShadeFocusable(false);getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();getStatusBarView().collapsePanel(true /* animate */, delayed, speedUpFactor);//☆☆☆☆} else {mBubbleControllerLazy.get().collapseStack();}}}public abstract class PanelBar extends FrameLayout {public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) {boolean waiting = false;PanelViewController pv = mPanel;if (animate && !pv.isFullyCollapsed()) {pv.collapse(delayed, speedUpFactor);waiting = true;} else {pv.resetViews(false /* animate */);pv.setExpandedFraction(0); // just in casepv.cancelPeek();}if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);if (!waiting && mState != STATE_CLOSED) {// it's possible that nothing animated, so we replicate the termination// conditions of panelExpansionChanged herego(STATE_CLOSED);onPanelCollapsed();//☆☆☆☆}}
}public class PhoneStatusBarView extends PanelBar {private Runnable mHideExpandedRunnable = new Runnable() {@Overridepublic void run() {if (mPanelFraction == 0.0f) {mBar.makeExpandedInvisible();//☆☆☆☆}}};@Overridepublic void onPanelCollapsed() {super.onPanelCollapsed();// Close the status bar in the next frame so we can show the end of the animation.post(mHideExpandedRunnable);//☆☆☆☆mIsFullyOpenedPanel = false;}
}public class StatusBar extends SystemUI {void makeExpandedInvisible() {if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible+ " mExpandedVisible=" + mExpandedVisible);if (!mExpandedVisible || mNotificationShadeWindowView == null) {return;}// Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)mStatusBarView.collapsePanel(/*animate=*/ false, false /* delayed*/,1.0f /* speedUpFactor */);mNotificationPanelViewController.closeQs();mExpandedVisible = false;visibilityChanged(false);// Update the visibility of notification shade and status bar window.mNotificationShadeWindowController.setPanelVisible(false);mStatusBarWindowController.setForceStatusBarVisible(false);// Close any guts that might be visiblemGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);mShadeController.runPostCollapseRunnables();setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) {showBouncerIfKeyguard();//☆☆☆☆} else if (DEBUG) {Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");}mCommandQueue.recomputeDisableFlags(mDisplayId,mNotificationPanelViewController.hideStatusBarIconsWhenExpanded() /* animate */);// Trimming will happen later if Keyguard is showing - doing it here might cause a jank in// the bouncer appear animation.if (!mStatusBarKeyguardViewManager.isShowing()) {WindowManagerGlobal.getInstance().trimMemory(ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);}}private void showBouncerIfKeyguard() {if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)&& !mKeyguardViewMediator.isHiding()) {mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); //☆☆☆☆}}}public class StatusBarKeyguardViewManager {public void showBouncer(boolean scrimmed) {if (mShowing && !mBouncer.isShowing()) {mBouncer.show(false /* resetSecuritySelection */, scrimmed);//☆☆☆☆}updateStates();}
}public class KeyguardBouncer {private final Runnable mShowRunnable = new Runnable() {@Overridepublic void run() {mRoot.setVisibility(View.VISIBLE);showPromptReason(mBouncerPromptReason);final CharSequence customMessage = mCallback.consumeCustomMessage();if (customMessage != null) {mKeyguardView.showErrorMessage(customMessage);}// We might still be collapsed and the view didn't have time to layout yet or still// be small, let's wait on the predraw to do the animation in that case.if (mKeyguardView.getHeight() != 0 && mKeyguardView.getHeight() != mStatusBarHeight) {mKeyguardView.startAppearAnimation();} else {mKeyguardView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {mKeyguardView.getViewTreeObserver().removeOnPreDrawListener(this);mKeyguardView.startAppearAnimation();//☆☆☆☆return true;}});mKeyguardView.requestLayout();}mShowingSoon = false;if (mExpansion == EXPANSION_VISIBLE) {mKeyguardView.onResume();mKeyguardView.resetSecurityContainer();showPromptReason(mBouncerPromptReason);}SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN);}};public void show(boolean resetSecuritySelection, boolean isScrimmed) {final int keyguardUserId = KeyguardUpdateMonitor.getCurrentUser();if (keyguardUserId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser()) {// In split system user mode, we never unlock system user.return;}ensureView();mIsScrimmed = isScrimmed;// On the keyguard, we want to show the bouncer when the user drags up, but it's// not correct to end the falsing session. We still need to verify if those touches// are valid.// Later, at the end of the animation, when the bouncer is at the top of the screen,// onFullyShown() will be called and FalsingManager will stop recording touches.if (isScrimmed) {setExpansion(EXPANSION_VISIBLE);}if (resetSecuritySelection) {// showPrimarySecurityScreen() updates the current security method. This is needed in// case we are already showing and the current security method changed.showPrimarySecurityScreen();}if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {return;}final int activeUserId = KeyguardUpdateMonitor.getCurrentUser();final boolean isSystemUser =UserManager.isSplitSystemUser() && activeUserId == UserHandle.USER_SYSTEM;final boolean allowDismissKeyguard = !isSystemUser && activeUserId == keyguardUserId;// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is// set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.if (allowDismissKeyguard && mKeyguardView.dismiss(activeUserId)) {return;}// This condition may indicate an error on Android, so log it.if (!allowDismissKeyguard) {Log.w(TAG, "User can't dismiss keyguard: " + activeUserId + " != " + keyguardUserId);}mShowingSoon = true;// Split up the work over multiple frames.DejankUtils.removeCallbacks(mResetRunnable);if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()&& !mKeyguardUpdateMonitor.userNeedsStrongAuth()&& !mKeyguardBypassController.getBypassEnabled()) {mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);//☆☆☆☆} else {DejankUtils.postAfterTraversal(mShowRunnable);//☆☆☆☆}mCallback.onBouncerVisiblityChanged(true /* shown */);mExpansionCallback.onStartingToShow();}
}public class KeyguardHostView extends FrameLayout implements SecurityCallback {public void startAppearAnimation() {mSecurityContainer.startAppearAnimation();//☆☆☆☆}
}public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {public void startAppearAnimation() {if (mCurrentSecuritySelection != SecurityMode.None) {getSecurityView(mCurrentSecuritySelection).startAppearAnimation();//☆☆☆☆}}
}public class KeyguardPINView extends KeyguardPinBasedInputView {@Overridepublic void startAppearAnimation() {enableClipping(false);setAlpha(1f);//☆☆☆☆setTranslationY(mAppearAnimationUtils.getStartTranslation());AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,0, mAppearAnimationUtils.getInterpolator());mAppearAnimationUtils.startAnimation2d(mViews,new Runnable() {@Overridepublic void run() {enableClipping(true);}});}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40041.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40041.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40041.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

31-Pandas index操作索引

Pandas index操作索引 索引(index)是 Pandas 的重要工具,通過索引可以從 DataFame 中選擇特定的行數和列數,這種選擇數據的方式稱為“子集選擇”。 在 Pandas 中,索引值也被稱為標簽(label)&a…

簡單的text/html無法解析解決記錄

簡單的text/html無法解析解決記錄 1. bug發現 我們所有的服務都是微服務,服務間調用都是使用feign接口進行調用,正常調用都沒有問題,但是某一天發現部分從esb服務調用過來到我們本地的服務,本地服務再使用feign接口調用其他微服…

DPO算法推導

DPO 核心思想:直接使用偏好數據進行策略優化,省去 reward 模型策略優化。 技術背景知識: 首先給定prompt x,生成兩個答案 ( y 1 , y 2 ) Π S F T ( y ∣ x ) (y_1,y_2)~\Pi^{SFT}(y|x) (y1?,y2?) ΠSFT(y∣x) ,并通…

2. Python+Playwright playwright的API

Playwright支持同步和異步兩種API,使用異步API需要導入asyncio庫,它是一個可以用來實現Python協程的庫,更詳細介紹可參考Python協程 。我們可以根據自己的偏好選擇適合的模式。 同步與異步模式原理 同步操作方式:在代碼執行時&am…

c++的const

const在C中是一個非常重要的關鍵字,用于定義不可變的變量、函數參數、成員函數等。它可以提高代碼的可讀性、安全性,并幫助編譯器進行優化。 定義常量 使用const定義不可變的變量: const int MAX_SIZE 100;常量指針 指向常量的指針和常量…

【ARMv8/v9 GIC 系列 5 -- GIC GICD_CTRL 使用詳細介紹】

文章目錄 GICD_CTRLGICD_CTLR 寄存器結構RWP(Register Write Pending)E1NWF(Enable 1 of N Wakeup Functionality)DS(Disable Security) 親和性路由(Affinity Routing)ARE_NSARE_S 中…

【java計算機畢設】服裝生產管理系統java MySQL springboot vue html maven項目設計源代碼+萬字文檔

目錄 1項目功能 2項目介紹 3項目地址 1項目功能 【java計算機畢設】服裝生產管理系統java MySQL springboot vue html maven項目代碼文檔 2項目介紹 系統功能: 服裝生產管理系統包括管理員、用戶兩種角色。 管理員功能包括個人中心模塊用于修改個人信息和密碼&a…

【UE5.3】筆記6-創建可自由控制Pawn類

搭建場景 搭建一個場景:包含地板、圍墻。可以根據喜好加一些自發光的效果。 增加食物 創建食物藍圖類,在場景里放置一些食物以供我們player去吃掉獲取分值。 創建可控制的layer 我們先右鍵創建一個藍圖繼承自pawn類,起名BP_Player&#xf…

Python-算法編程100例-二分法(入門級)-業務負載分配

題目: 現有一個服務器集群(服務器數量為 serverNum),和一批不同類型的任務(用數組 tasks 表示,下標表示任務類型,值為任務數量)。 現需要把這批任務都分配到集群的服務器上&#x…

2024年在WordPress中創建銷售活動的專家級優惠券方法

2024年在WordPress中創建銷售活動的專家級優惠券方法 今天我想和大家分享一些關于如何在WordPress網站上使用專家級優惠券工具來創建銷售活動的經驗。對于已經在電商領域有一定經驗的店主,利用專家級優惠券不僅能吸引顧客,還能顯著增加銷量。在這篇文章…

【Linux】線程封裝與互斥(萬字)

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 目錄 文章目錄 前言 C多線程的用法 對原生線程進行一次封裝 理解pthread線程 Linux線程互斥 進程線程間的互斥相關背景概念 互斥量mutex 操作共享變量會有問題的售票…

[go-zero] goctl 生成api和rpc

文章目錄 1.goctl 概述2.go-zero 需要安裝的組件3.生成 api4.生成 rpc 1.goctl 概述 goctl支持多種rpc,較為流行的是google開源的grpc,這里主要介紹goctl rpc protoc的代碼生成與使用。protoc是grpc的命令,作用是將proto buffer文件轉化為相…

探討命令模式及其應用

目錄 命令模式命令模式結構命令模式適用場景命令模式優缺點練手題目題目描述輸入描述輸出描述題解 命令模式 命令模式是一種行為設計模式, 它可將請求轉換為一個包含與請求相關的所有信息的獨立對象。 該轉換讓你能根據不同的請求將方法參數化、 延遲請求執行或將其…

《亞馬遜搬運亞馬遜產品》配合跟賣采集爬取跟賣店鋪高質量

亞馬遜高質量產品如何搬運?亞馬遜采集亞馬遜。 哈嘍大家好,大家講一下做亞馬遜是發貨、鋪貨這塊的功能。目前這款軟件做跟賣大家都知道,同時也支持做鋪貨。鋪貨可以采集國內的1688、淘寶、京東都可以采,采完之后也可以采速賣通&a…

周周星分享7.3—基于氣象大數據的自動站實況聯合預測

賽題 2024中國高校計算機大賽 — 大數據挑戰賽 經驗分享 大家好,我是掃地僧團隊的隊長,以前參加這樣打榜的比賽比較少,了解的打榜技巧不是太多,所以想從科研的角度給大家一點分享。 這次比賽主要從以下五個步驟進行&#xff1a…

Linux Doxygen快速生成文檔

此前寫過一篇編寫Doxygen格式的注釋以用于生成文檔,點擊以查閱, Doxygen常用語法與字段記錄,但是當時用的windows桌面版的doxygen,最近使用ubuntu編寫代碼想直接使用doxygen生成,故寫下此博客 Doxygen Doxygen是一個用于生成軟件文檔的工具,它可以從代碼中提取注釋…

(四)opengl函數加載和錯誤處理

#include <glad/glad.h>//glad必須在glfw頭文件之前包含 #include <GLFW/glfw3.h> #include <iostream>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);std::cout << width << &qu…

PHP多線程爬蟲:高效解析電商網頁內容

如何使用php多線程編寫高效的網頁爬蟲 隨著互聯網的發展和數據的不斷增長&#xff0c;網頁爬蟲成為了一種非常重要的工具。通過網頁爬蟲&#xff0c;我們可以自動地從各種網站上獲取大量的數據&#xff0c;并進行進一步的處理和分析。而PHP作為一種廣泛使用的編程語言&#xf…

Android高級面試_6_性能優化

Android 高級面試-7&#xff1a;網絡相關的三方庫和網絡協議等 1、網絡框架 問題&#xff1a;HttpUrlConnection, HttpClient, Volley 和 OkHttp 的區別&#xff1f; HttpUrlConnection 的基本使用方式如下&#xff1a; URL url new URL("http://www.baidu.com")…

SwanLinkOS首批實現與HarmonyOS NEXT互聯互通,軟通動力子公司鴻湖萬聯助力鴻蒙生態統一互聯

在剛剛落下帷幕的華為開發者大會2024上&#xff0c;伴隨全場景智能操作系統HarmonyOS Next的盛大發布&#xff0c;作為基于OpenHarmony的同根同源系統生態&#xff0c;軟通動力子公司鴻湖萬聯全域智能操作系統SwanLinkOS首批實現與HarmonyOS NEXT互聯互通&#xff0c;率先攻克基…