Android4.4-屬性的使用總結
https://www.jianshu.com/p/69e6b34475ff
DD_Dog關注
2019.08.02 11:06:02字數 1,575閱讀 152
一、Android4.4屬性系統系列文章
Android4.4屬性系統-初始化
Android4.4屬性系統-系統服務
Android4.4屬性系統-內存空間共享
Android4.4屬性系統-屬性獲取
Android4.4屬性系統-屬性設置
Android4.4-屬性的使用總結
二、屬性的使用總結
前面的幾篇文章都是分析了屬性系統的運作流程,但是日常開發中用到最多的還是對屬性的獲取和設置,以及不同類型的屬性有什麼特點,可讀可寫的權限問題,這篇文章就很接地氣,總結了如何在安卓系統開發中獲取、設置和添加屬性。
2.1 屬性的獲取
屬性的獲取可以從java層接口和C接口進行分類,當然對於framework和APP開發者來說,用得最多的自然是java/JNI的接口,而對於JNI開發或者c庫的開發來說,用的最多的應該是c接口。
2.1.1 java獲取屬性接口
獲取屬性並不需要額外的權限,對於是否是系統應用也沒有要求。
使用示例
import android.os.SystemProperties;
//獲取自定義的屬性"persist.flyscale.wifi",默認值爲-1
//獲取int值
int wifiInt = SystemProperties.getInt("persist.flyscale.wifi.int", -1);
//獲取long值
int wifiLong = SystemProperties.getLong("persist.flyscale.wifi.long", -1);
//獲取bool值
boolean wifiBool = SystemProperties.getBoolean("persist.flyscale.wifi", false);
//獲取string,如果沒有則返回空字符串""
String wifiStr1 = SystemProperties.getInt("persist.flyscale.wifi");
//獲取string,如果沒有則返回指定默認值"def"
String wifiStr2 = SystemProperties.getInt("persist.flyscale.wifi", "def");
如果需要使用到c接口獲取屬性,請參考Android4.4屬性系統-屬性獲取。
2.2 安卓屬性的設置
如果看過前面的Android4.4屬性系統-屬性設置,就容易得出結論:屬性設置是有權限要求的,對於uid爲root是絕對允許的,而對於其它用戶則是禁止的,除非通過了白名單的權限檢查。
2.2.1 property權限檢查
在說明如何進行設置之前,必須首先了解property的權限檢查機制,否則只能是雲裏霧裏,不知所云。
看過Android4.4屬性系統-屬性設置的讀者應該瞭解了,屬性是有幾種分類的:
2.2.1.1 控制類屬性ctl.*
ctl.開頭的,例如ctl.start=property_service
表示啓動名爲"property_service"的服務,也即屬性服務,這樣就明白了,ctl.開頭的屬性表示控制服務的屬性,需要AID_ROOT和AID_SYSTEM權限,除此之外在control_perms白名單中的也可以通過權限檢查,如下:
/*
* White list of UID that are allowed to start/stop services.
* Currently there are no user apps that require.
*/
struct {
const char *service;
unsigned int uid;
unsigned int gid;
} control_perms[] = {
{ "dumpstate",AID_SHELL, AID_LOG }, //表示允許AID_SHELL用戶控制 "dumpstate"服務
{ "ril-daemon",AID_RADIO, AID_RADIO }, //表示允許AID_RADIO用戶控制 "ril-daemon"服務
{NULL, 0, 0 }
};
除了白名單中的兩種服務可以被ROOT和SYSTEM之外的AID_SHELL和AID_RADIO用戶控制之外,其它的一概拒絕!!!
2.2.1.2 其它的屬性
除了控制屬性之外的屬性也需要通過權限檢查,一般來說ROOT用戶是絕對是被允許的,但是系統中除了少數核心進程之外,大部分不是ROOT用戶,它們是通過另外一個白名單property_perms來控制的,如下:
/* White list of permissions for setting property services. */
struct {
const char *prefix;
unsigned int uid;
unsigned int gid;
} property_perms[] = {
{ "net.rmnet0.", AID_RADIO, 0 }, //
{ "net.gprs.", AID_RADIO, 0 },
{ "net.ppp", AID_RADIO, 0 },
{ "net.qmi", AID_RADIO, 0 },
{ "net.lte", AID_RADIO, 0 },
{ "net.cdma", AID_RADIO, 0 },
{ "ril.", AID_RADIO, 0 },
{ "gsm.", AID_RADIO, 0 },
{ "persist.radio", AID_RADIO, 0 },
{ "persist.radio", AID_SYSTEM, 0 },
{ "net.dns", AID_RADIO, 0 },
{ "sys.usb.config", AID_RADIO, 0 },
{ "net.", AID_SYSTEM, 0 },
{ "dev.", AID_SYSTEM, 0 },
{ "runtime.", AID_SYSTEM, 0 },
{ "hw.", AID_SYSTEM, 0 },
{ "sys.", AID_SYSTEM, 0 },
{ "sys.powerctl", AID_SHELL, 0 },
{ "service.", AID_SYSTEM, 0 },
{ "wlan.", AID_SYSTEM, 0 },
{ "bluetooth.", AID_BLUETOOTH, 0 },
{ "dhcp.", AID_SYSTEM, 0 },
{ "dhcp.", AID_DHCP, 0 },
{ "debug.", AID_SYSTEM, 0 },
{ "debug.", AID_SHELL, 0 },
{ "log.", AID_SHELL, 0 },
{ "service.adb.root", AID_SHELL, 0 },
{ "service.adb.tcp.port", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 }, //系統類屬性
{ "persist.msms.", AID_RADIO, 0 },//SPRD: add for dsds
{ "persist.msms.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ "media.", AID_MEDIA, 0 },
{ "persist.service.bdroid.", AID_BLUETOOTH, 0 },
{ "selinux." , AID_SYSTEM, 0 },
{ "persist.modem.", AID_RADIO, 0 },//SPRD: add for lte
{ NULL, 0, 0 }
};
看着很多,其實很好理解 ,就拿 { "persist.sys.", AID_SYSTEM, 0 },
來說吧,它表示以"persist.sys."開頭的屬性是允許AID_SYSTEM用戶修改的,其它的類同。
還有很重要的一點,以ro.開頭的表示只讀屬性,即使是AID_ROOT用戶也是不允許修改的。
做一個小總結:如果需要修改/添加屬性,那麼修改屬性的代碼運行的進程必須要通過權限檢查,否則會失敗,權限檢查的細節也已經分析過了,很簡單吧,立即推==》一切難題都是紙老虎。
2.2.2 java接口設置屬性
java層的設置接口API只有一個SystemProperties.set(String key, String value),也就是說所有的屬性value值要轉爲字符串被設置進去。
2.2.2.1uid(權限)配置爲system
首先要想成功設置你的APP uid爲system,就需要做一些配置了。
- 在AndroidManifest.xml中,以系統應用的Settings爲例,配置android:sharedUserId屬性
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settings"
coreApp="true"
android:sharedUserId="android.uid.system">
- 另外在對應的Android.mk中使用系統平臺簽名:
如果你有源碼編譯環境,對mk做如下配置
LOCAL_CERTIFICATE := platform
在模塊目錄下執行mm編譯即可。
當然如果你沒有源碼環境,也是可以進行平臺簽名的,請參考的另一篇文章Android4.4-APP系統簽名的實現方案,其最終目的是一樣的
2.2.2.2 調用java接口
只是簡單的接口調用,很簡單了
import android.os.SystemProperties;
SystemProperties.set("persist.sys.volte.enable", "1");
2.2.3 案例分析
我預置的一個測試應用,測試代碼如下,按上鍵獲取"persist.sys.volte.enable",默認爲false
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
Log.i("HomeActivity", "persist.sys.volte.enable=" + SystemProperties.getBoolean("persist.sys.volte. enable", false));
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
SystemProperties.set("persist.sys.volte.enable", "false");
Log.i("HomeActivity", "persist.sys.volte.enable=" + SystemProperties.getBoolean("persist.sys.volte. enable", true));
break;
此時用戶uid爲radio,因爲AndroidManifest.xml中配置了android:sharedUserId="android.uid.phone"
:
USER PID PPID VSIZE RSS WCHAN PC NAME
radio 845 145 222304 9032 ffffffff 00000000 S com.flyscale.launcher
先獲取一次,再設置爲1,再獲取,輸出結果如下:
com.flyscale.launcher I/HomeActivity: persist.sys.volte.enable=true //設置爲false前
com.flyscale.launcher I/HomeActivity: persist.sys.volte.enable=true //設置爲false後仍然爲true
在設置屬性的時候報錯如下:
init: sys_prop: permission denied uid:1001 name:persist.sys.volte.enable=true
顯然權限未通過啊。在經過之前兩步配置uid後:
system 864 142 222796 11388 ffffffff 00000000 S com.flyscale.launcher
再次運行結果
com.flyscale.launcher I/HomeActivity: persist.sys.volte.enable=true //修改前
com.flyscale.launcher I/HomeActivity: persist.sys.volte.enable=false //修改後
修改成功!
2.3屬性的添加
在代碼中添加屬性與設置屬性的接口是一樣的,也需要注意權限檢查。如果該屬性存在就會更新,如果不存在就會創建,但是要注意,屬性是不能被刪除的。
另外我們經常在安卓源碼中預置一些屬性配置,那麼都在哪些地方可以配置屬性呢,要注意些什麼呢?
-
注意權限檢查
例如我要添加一個屬性persist.flyscale.wifi=0
,那麼它肯定是無法通過權限檢查的,因爲它不在白名單中,那麼怎麼辦呢?可以改成persist.sys.flyscale.wifi=0
,這樣就可以了,因爲白名單中有persist.sys.
開頭的屬性,是可以被AID_SYSTEM修改的。 -
可以在源碼中默認配置的文件
首先工程目錄下的system.prop是可以直接添加的,如下:device/***/scx35l/sp9820w_poc_780/system.prop
#add for test
persist.sys.flyscale.wifi=0
另外在工程編譯的mk文件中也可以配置,但是要使用PRODUCT_PROPERTY_OVERRIDES語句
PRODUCT_PROPERTY_OVERRIDES += persist.sys.volte.enable=true
以上爲本人使用中的總結,歡迎指正和補充,謝謝大家!