在测试CTS Verifier测试的时候,有一项为开发者选项"OEM unlocking"功能,测试的时候需要人为进行判断是否成功。
测试此项前,需要执行如下动作:

adb shell settings put global hidden_api_policy 1adb install -r -g  CtsVerifier.apkadb install -r -t CtsEmptyDeviceOwner.apkadb shell dpm set-device-owner com.android.cts.emptydeviceowner/.EmptyDeviceAdmin

然后进入开发者选项,查看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命令导出来看一下,命令如下:

dd if=/dev/block/bootdevice/by-name/frp of=/data/data/1.data

在lock和unlock的状态下,分别去dd一下,看下两者有什么不同,下面是我的dd后的效果图:

而且下面两句都是往FRP分区的最后一个bit位操作,只是一个是hal对象的方式,一个是通过PersistentDataBlockManagerInternal API接口去操作的;hal的方式留出来是为了将来厂商进行定制使用。

OemLockService.java setOemUnlockAllowedByUser(boolean allowedByUser)@Overridepublic void setOemUnlockAllowedByUser(boolean allowedByUser) {...mOemLock.setOemUnlockAllowedByDevice(allowedByUser);setPersistentDataBlockOemUnlockAllowedBit(allowedByUser);}

我的理解大概就是这样,仅供参考。

android OEM unlocking分析相关推荐

  1. android释放acitity内存,Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  2. android挂载usb设备,android usb挂载分析---MountService启动

    在android usb挂载分析----vold启动,我们的vold模块已经启动了,通信的机制也已经建立起来了,接下来我们分析一下MountService的启动,也就是我们FrameWork层的启动, ...

  3. Android源码分析-全面理解Context

    前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...

  4. Android Studio +MAT 分析内存泄漏实战

    点击打开链接 对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的. 首先什么是内存泄漏? 内存泄漏就是一些 ...

  5. Android源码分析--MediaServer源码分析(二)

    在上一篇博客中Android源码分析–MediaServer源码分析(一),我们知道了ProcessState和defaultServiceManager,在分析源码的过程中,我们被Android的B ...

  6. Android系统启动流程分析之安装应用

    2016六月 21 原 Android系统启动流程分析之安装应用 分类:Android系统源码研究 (295)  (0)  举报  收藏 跟随上一篇博客Android系统的启动流程简要分析继续分析an ...

  7. android settings源代码分析(2)

    通过前一篇文章  Android settings源代码分析(1)  分析,大概知道了Settings主页面是如何显示,今天主要分析"应用"这一块google是如何实现的. 应用对 ...

  8. Android `AsyncTask`简要分析

    Android `AsyncTask`简要分析 AsyncTask简要分析 经典异步任务:AsyncTask,使用场景有:批量下载,批量拷贝等.官方文档就直接给出了一个批量下载的示例. private ...

  9. 转 android anr 分析示例,[摘]Android ANR日志分析指南之实例解析

    前文<[摘]Android ANR日志分析指南>也摘抄了如何分析,接下来通过实例解析. 一.主线程被其他线程lock,导致死锁 waiting on <0x1cd570> (a ...

最新文章

  1. github上手实践教程
  2. 为什么说在KMP算法中文本串中的每个字符都是需要进行比较操作的?
  3. Axiso解决跨域访问 !!!!
  4. binary - 从(向)二进制串插入和提取字段 / BINARY FORMAT BINARY SCAN
  5. spring-data-jpa 查询视图
  6. 开源IP代理池续——整体重构
  7. 7-5-无向图生成树-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版
  8. Linux内核跟踪eBPF:bpftrace 参考指南
  9. 关于Eclipse在servlet中连接数据库时出现驱动加载失败的解决
  10. 四级恋练有词课程 (10课时-朱伟)1.Unit1A单词识记(上)
  11. 如何使用 Java 将 PDF 转换为文本 (TXT)
  12. matlab分段函数的表达_【MATLAB】06_分段函数的多种表示方法
  13. 基于51单片机的心形流水灯
  14. 自制COCO 实例分割dataset并测试效果(从采集到测试)
  15. CSS 水平居中、垂直居中、水平垂直居中
  16. 刷脸支付潮酷在年轻化的场景中颇受欢迎
  17. 蚂蚁金服开源地理可视化引擎 L7 2.0 正式版来了,让地图动起来
  18. 项目经理如何召开既高效又快速的会议?
  19. 电信显示isp服务器超时连不上,wifi连接超时怎么解决,网络能连上但连接超时-
  20. _IO(), _IOR(), _IOW(), _IOWR() 宏的用法与解析

热门文章

  1. Widnwos 2000 命令集合
  2. 30岁程序员吐槽:一分钟只能赚3.3元,混得太差!算出月薪后我服了
  3. 为什么不给面试不过的人发通知,很难吗?
  4. python django做网页论文_基于PythonDjango框架的多媒体发布系统
  5. 大数据之Hive教程
  6. java reducebykey_Spark入门(五)--Spark的reduce和reduceByKey
  7. python命令窗口中怎么导入numpy_科学网—windows7下python3.6如何导入numpy,Astropy - 杨涛只的博文...
  8. 腐蚀和膨胀(erode and dilate)
  9. 监督学习 | 决策树之Sklearn实现
  10. BIC/ImageGP稳定性问题