上回分析到了/data/system/device_policies.xml這個文件是在package change事件發生的時候變化的。那么來看看它的內容。
依據以往的經驗。在/data/system以下的幾個文件(packages.xml packages.list)都是PackageManager掃面各個package的Manifest文件生成的,預計這文件也差點兒相同吧。
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <policies> <admin name="com.bgsoft.securitycamera/com.bgsoft.securitycamera.AdminReceiver"> <policies flags="2" /> </admin> <active-password quality="65536" length="5" uppercase="0" lowercase="0" letters="0" numeric="0" symbols="0" nonletter="0" /> </policies>
在我安裝了SecurityCamera這個apk以后,這個文件變成了這樣,多出了一個admin的片段,描寫敘述的東西看起來確實是SecurityCamera相關的東西。那再來看看它的Manifest文件吧。
<receiver android:label="@string/labelValue" android:name=".AdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:description="@string/description"> <meta-data android:name="android.app.device_admin" android:resource="@xml/lockourscreen" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>能夠發現有個receiver的段和前文提到的東東是相關的,AdminReceiver 這個東西看來是詳細的實現部分,須要詳細研究。
查看代碼發現它是DeviceAdminReceiver的子類,是一個廣播接收器。可是非常奇怪,做為一個廣播接收器。在Manifest中沒有注冊。也沒有在代碼中動態的注冊,那它是怎么接收到它想要的action事件的。非常奇怪。
僅僅能在代碼中再尋找誰用到了它呢.
this.componentName = new ComponentName(this, AdminReceiver.class);
......
private void startDeviceManager() { Intent localIntent = new Intent("android.app.action.ADD_DEVICE_ADMIN"); localIntent.putExtra("android.app.extra.DEVICE_ADMIN", this.componentName); localIntent.putExtra("android.app.extra.ADD_EXPLANATION", "防盜拍照助手"); startActivityForResult(localIntent, 0); }
OK,就這里了。可是問題來了,挖.. 不是不是。這是在干什么呢? 尋遍Android的源碼。發現Setting能處理這個Intent。
I/ActivityManager( 3138): START u0 {cmp=com.android.settings/.DeviceAdminAdd (has extras)} from pid 24508
BYW:這樣的log看了這么多,才明確原來cmp是component。
不廢話。看DeviceAdminAdd ,代碼較多。不貼了主要分析,就是這個Activity在處理這個Action的是候會彈出一個框,問你是否確認激活這個 設備管理器。
假設ok的話就會調用setActiveAdmin。這個就是前文中提到的那個setActiveAdmin。把這個設置成active的。
那是不是激活了就能收到廣播了呢。還有這個管理器究竟有什么用的問題還是沒解決。
還是得繼續研究。 那線索僅僅能是去分析前文提到的List了。前文僅僅看了假設add,卻沒關注這個list究竟是做什么用的,失誤。
查找出了一堆使用的地方,調個典型的來看看.
void sendAdminCommandLocked(String action, int reqPolicy, int userHandle) { final DevicePolicyData policy = getUserData(userHandle); final int count = policy.mAdminList.size(); if (count > 0) { for (int i = 0; i < count; i++) { ActiveAdmin admin = policy.mAdminList.get(i); if (admin.info.usesPolicy(reqPolicy)) { sendAdminCommandLocked(admin, action); } } } }遍歷這個list,要知道這個list可都是active的admin了,發給他們消息,對了,有門。這就是它收到廣播的方式嗎?看看誰調用了這種方法。
找個典型。發如今keyguard上password輸錯的時候會調用到。 這個設備管理器的作用貌似要能夠猜到了。
從
admin.info.usesPolicy(reqPolicy)
能夠看出有非常多policy能夠被使用。
USES_POLICY_LIMIT_PASSWORD
USES_POLICY_WATCH_LOGIN
。。。。
后來還google原來是與應用的某個xml相應,就是Manifest里面的meta-data
<meta-data android:name="android.app.device_admin" android:resource="@xml/lockourscreen" />
<?Ok,窺豹一斑吧。xml version="1.0" encoding="utf-8"?> <device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <watch-login /> </uses-policies> </device-admin>