android OEM unlocking分析
在測試CTS Verifier測試的時候,有一項為開發者選項"OEM unlocking"功能,測試的時候需要人為進行判斷是否成功。
測試此項前,需要執行如下動作:
然后進入開發者選項,查看OEM unlocking選項后面,是否會彈出一個“!”的圖標,點擊會彈出一個動畫框,能否彈出對話框是根據設備是否已lock來判斷的。在bootloader中執行fastboot flashing lock后,此項就可以通過了。
查看lock和unlocked時的系統屬性,
$ getprop |grep lock
[cache_key.is_user_unlocked]: [8110559973390150548]
[ro.boot.flash.locked]: [1]
[ro.boot.vbmeta.device_state]: [locked]
[ro.frp.pst]: [/dev/block/bootdevice/by-name/frp]
[ro.oem_unlock_supported]: [1]
[sys.oem_unlock_allowed]: [1]
$ getprop |grep lock
[cache_key.is_user_unlocked]: [8110559973390150548]
[ro.boot.flash.locked]: [1]
[ro.boot.vbmeta.device_state]: [locked]
[ro.frp.pst]: [/dev/block/bootdevice/by-name/frp]
[ro.oem_unlock_supported]: [1]
[sys.oem_unlock_allowed]: [0]
帶著這個問題,我們看一下OEM unlocking的內容,主要是根據opengrok跟一下代碼的調用過程,內容如下:
settings層=== EnableOemUnlockSettingWarningDialog.java onClick host.onOemUnlockDialogConfirmed(); |DevelopmentDashboardFragment.java onOemUnlockDialogConfirmed() @Override public void onOemUnlockDialogConfirmed() {final OemUnlockPreferenceController controller = getDevelopmentOptionsController(OemUnlockPreferenceController.class);controller.onOemUnlockConfirmed(); } |OemUnlockPreferenceController.java onOemUnlockConfirmed() public void onOemUnlockConfirmed() {mOemLockManager.setOemUnlockAllowedByUser(true); } |framework層=== OemLockManager.java setOemUnlockAllowedByUser mService.setOemUnlockAllowedByUser | IOemLockService.aidl setOemUnlockAllowedByUser(boolean allowed) | OemLockService.java setOemUnlockAllowedByUser(boolean allowedByUser)@Overridepublic void setOemUnlockAllowedByUser(boolean allowedByUser) {if (ActivityManager.isUserAMonkey()) {// Prevent a monkey from changing thisreturn;}enforceManageUserOemUnlockPermission();enforceUserIsAdmin();final long token = Binder.clearCallingIdentity();try {if (!isOemUnlockAllowedByAdmin()) {throw new SecurityException("Admin does not allow OEM unlock");}if (!mOemLock.isOemUnlockAllowedByCarrier()) {throw new SecurityException("Carrier does not allow OEM unlock");}mOemLock.setOemUnlockAllowedByDevice(allowedByUser);setPersistentDataBlockOemUnlockAllowedBit(allowedByUser);} finally {Binder.restoreCallingIdentity(token);}}/*** Always synchronize the OemUnlockAllowed bit to the FRP partition, which* is used to erase FRP information on a unlockable device.*/private void setPersistentDataBlockOemUnlockAllowedBit(boolean allowed) {final PersistentDataBlockManagerInternal pdbmi= LocalServices.getService(PersistentDataBlockManagerInternal.class);// if mOemLock is PersistentDataBlockLock, then the bit should have already been setif (pdbmi != null && !(mOemLock instanceof PersistentDataBlockLock)) {Slog.i(TAG, "Update OEM Unlock bit in pst partition to " + allowed);pdbmi.forceOemUnlockEnabled(allowed);}}|HW層=== android\hardware\interfaces\oemlock\1.0\IOemLock.hal setOemUnlockAllowedByDevice(bool allowed) generates (OemLockStatus status) | android/external/libese/esed/OemLock.cpp OemLock::setOemUnlockAllowedByDevice(bool allowed)看代碼實現,此項應該是留給oem廠商進行定制使用的,開關打開和關閉主要是操作FRP分區,這個分區一般是GMS包版本會用到,比如GMS開機向導中輸入的用戶賬號等信息,都是存在FRP分區中。
當用戶在設置中手動執行恢復出廠設置時,在Recovery中一般會清除掉FRP分區信息。用戶執行這個恢復出廠設置動作是“可信的”,可以清除FRP分區。
但是當其他形為,比如直接通過命令如adb reboot recovery等或其他途徑進入到recovery,是不會清除掉FRP分區的,開機進入到GMS開機向導界面,還是需要用戶輸入賬號等信息的。而且我們這里的oem lock上鎖仍然是有效的,數據沒有被清除掉。
那么oem unlocking數據是存在哪了呢?
看代碼是存在了FRP分區的最后一個block的最后一個BIT比特位上,那是否真是如此呢?
我們可以將FRP分區通過dd命令導出來看一下,命令如下:
在lock和unlock的狀態下,分別去dd一下,看下兩者有什么不同,下面是我的dd后的效果圖:
而且下面兩句都是往FRP分區的最后一個bit位操作,只是一個是hal對象的方式,一個是通過PersistentDataBlockManagerInternal API接口去操作的;hal的方式留出來是為了將來廠商進行定制使用。
我的理解大概就是這樣,僅供參考。
總結
以上是生活随笔為你收集整理的android OEM unlocking分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「新闻」Google Science F
- 下一篇: sphinx在window下和linux