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
- 下一篇: 分拣外观残缺的机器人_一款分拣搬运机器人