鎖屏設定:
1. 初始值 : <integer name="def_screen_off_timeout">60000</integer>
2. 資料庫/data/data/com.android.providers.settings/databases/settings.db中
system 表 screen_off_timeout.
3. 開機鎖屏, 在frameworks/policies/base/phone/com/android/internal/policy/impl/KeyguardViewMediator.java 檔案中修改 mExternallyEnabled 值為false即可. 或者調用setKeyguardEnabled來解鎖.
4. 程式禁止鎖屏:
方法一:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
方法二:
mWakeLock = pManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, TAG);
mWakeLock.acquire();
相關參數:
screen_brightness_mode : 鎖屏模式,
0 = 手動鎖屏
1 = 自動鎖屏
private static final int SCREEN_ON_BIT = 0x00000001;
螢幕亮
private static final int SCREEN_BRIGHT_BIT = 0x00000002;
螢幕背光亮
private static final int BUTTON_BRIGHT_BIT = 0x00000004;
按鈕背光亮
private static final int KEYBOARD_BRIGHT_BIT = 0x00000008;
鍵盤背光亮
private static final intBATTERY_LOW_BIT = 0x00000010;
電池電量低
SCREEN_OFF : 全部滅掉
SCREEN_DIM : 只有螢幕暗色
SCREEN_BRIGHT : 螢幕和螢幕背光亮
SCREEN_BUTTON_BRIGHT : 螢幕和按鈕亮
ALL_BRIGHT : 全部都亮
設定螢幕逾時時間:
PowerManagerService中的 setScreenOffTimeoutsLocked 函數.
螢幕休眠過程:
1.任何輸入事件會調用PowerManagerService的 userActivity函數來設定一段時間內電源的狀態以及螢幕狀態, 改函數會調用 setTimeoutLocked來設定螢幕為SCREEN_BRIGH. setTimeoutLocked會在原來逾時值的基礎上加上螢幕逾時時間(mKeylightDelay), 等待SCREEN_BRIGH逾時後判斷螢幕暗色時間(mDimDelay)是否大於0, 若是則設定螢幕為SCREEN_DIM. 等SCREEN_DIM逾時後設定SCREEN_OFF來關閉整個螢幕亮度.
總的來說螢幕調度過程是:
SCREEN_BRIGH --> SCREEN_DIM --> SCREEN_OFF --> close
mKeylightDelay mDimDelay mScreenOffDelay
當設定POKE_LOCK_SHORT_TIMEOUT標誌時: mKeylightDelay = 6s 其他時間為0
當設定POKE_LOCK_MEDIUM_TIMEOUT標誌時: mKeylightDelay = 15s 其他時間為0
其他時:
mKeylightDelay = 6s,
mDimDelay = screen_off_timeout - mKeylightDelay - LONG_DIM_TIME(7s);
mScreenOffDelay = LONG_DIM_TIME(7);
也就是說系統全亮期間為6s, 大部分都是螢幕和背光亮,暗屏期間為7s.
updateLightsLocked : 最終更新亮度配置, 背光亮度控制裝置有: lcd, 按鈕和鍵盤!
關閉系統屏保:
mKeyguardManager= (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock= mKeyguardManager.newKeyguardLock("");
mKeyguardLock.disableKeyguard();
KeyguardManager只是負責WindowsManager服務中鎖相關的一個介面類.
disableKeyguard需要的許可權: DISABLE_KEYGUARD,DevicePolicyManager中密碼檢查。
==========================================================================
TokenWatcher 輔助類,協助管理IBinder成員引用計數,主要通過acquire 和 release來綁定和釋放IBinder成員, 並且判斷從無到有或者從有到無時調用抽象成員acquire 和 release來通知子類事件的發生。 該類繼承java.lang.Object類, 可使用wait和notify鎖機制。
mKeyguardTokenWatcher 是WindowManagerService.java檔案中的一個TokenWatcher子類對象。當禁用鎖時調用 mPolicy.enableKeyguard(false), 當使能鎖時調用mPolicy.enableKeyguard(true)。 只要有一個IBinder禁止使用鎖的話,android的鎖定畫面就不會出來。 當鎖定畫面在的時候,mKeyguardDisabled=false, 當禁用鎖定畫面時mKeyguardDisabled=true.
WindowManagerService的 disableKeyguard和reenableKeyguard方法就是通過mKeyguardTokenWatcher變數控制鎖屏和解鎖屏的。鎖屏還涉及到裝置策略管理的狀態,接受到裝置狀態變化的廣播(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)時,會鎖屏。
PolicyManager 策略管理抽象類別,靜態函數, 通過"com.android.internal.policy.impl.Policy"類名尋找相應的策略類,對於手機來說路徑為frameworks/policies/base/phone/com/android/internal/policy/impl/Policy.java 中的類。可以建立 PhoneWindow, PhoneLayoutInflater, PhoneWindowManager三個類對象出來。
在WindowManagerService中的 mPolicy.enableKeyguard實際調用到了 PhoneWindowManager中的enableKeyguard, 繼而調用KeyguardViewMediator中的setKeyguardEnabled方法。
輸入事件流程:
preprocessEvent
--> mPolicy.preprocessInputEventTq 處理滑蓋等事件,返回true則終止往下執行
--> mPolicy.interceptKeyTq 返回動作:睡眠,到使用者,到介面,什麼都不幹。
--> 睡眠 mPowerManager.goToSleep, 受mStayOnConditions變數影響
--> 介面 mPowerManager.userActivity
--> 若螢幕關著,則返回
--> setPowerState 和 setTimeoutLocked(time, SCREEN_BRIGHT)
--> mPolicy.userActivity(取消鎖,並等待逾時鎖)
interceptKeyTq: 判斷螢幕是否亮以及鎖是否存在執行不同的操作。
如果屏鎖著並且亮著,則傳遞給使用者
如果屏鎖著但沒亮著,不傳遞給使用者並判斷是否喚醒螢幕。如果能喚醒的話則準備好鎖介面,isWakeKeyWhenKeyguardShowing 這個函數是寫入程式碼排除一些鍵的喚醒螢幕功能。
若果屏不鎖且滅著, 1)電話中並是音量鍵則不傳遞使用者,直接控制音量
2)若是喚醒鍵則傳遞給使用者介面(ACTIVITY)
3)預設傳遞給使用者
如果屏不鎖且亮, 預設傳遞給使用者
==================================繼續往下執行================
如果輸入的是掛機和電源鍵則處理一些通話事件,電源鍵按下時若屏亮則檢測是否為長按事件並且該事件不傳遞給使用者,否則什麼都不做。 若果屏亮著按下電源鍵則進入睡眠狀態(ACTION_GO_TO_SLEEP).
如果輸入的是一些媒體鍵並且不是傳遞給使用者的,則發送廣播!
處理電話介面的一些事件(接聽,響鈴靜音等)
查詢螢幕狀態可使用如下方法:
mPowerManager.isScreenOn();
mPowerManager.isScreenBright();
mKeyguardMediator.isShowingAndNotHidden();// 螢幕亮的話用這個方法
mKeyguardMediator.isShowing()); // 螢幕滅的話用這個方法