上回分析到了/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>
