2012年10月19日金曜日

Runtime.exec权限问题

很多应用程序在调用Runtime.exec的时候或者创建服务的时候都会遇到权限不够的情况。可采用以下解决方案:

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mokoid.LedTest"
android:sharedUserId="android.uid.system">

原来,ServiceManager 会去检查应用程式的权限,Android系统会根据User ID做权限管理,在frmeworks/base/cmds/servicemanager/service_manager.c 里有如下代码:
int svc_can_register(unsigned uid, uint16_t *name)
{
unsigned n;
 
if ((uid == 0) || (uid == AID_SYSTEM))
return 1;
 
for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
return 1;
 
return 0;
}
 
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
void *ptr, unsigned uid)
{
struct svcinfo *si;
LOGI("add_service('%s',%p) uid=%d/n", str8(s), ptr, uid);
 
if (!ptr || (len == 0) || (len > 127))
return -1;
 
if (!svc_can_register(uid, s)) {
LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIED/n",
str8(s), ptr, uid);
return -1;
}
...

涉及到权限管理的两个文件:AndroidManifest.xml 和 Android.mk
AndroidManifest.xml
声明权限:
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
<uses-permission android:name="android.permission.VIBRATE"/>

声明用户组
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.inputmethod.pinyin"
android:sharedUserId="android.uid.system">


Android.mk中通过证书来声明权限。
LOCAL_CERTIFICATE := platform
需要和manifest中的android:sharedUserId="android.uid.system" 对应起来。
platform 权限问题,最好运行在自己编译的系统上,才可以有特权。
如果修改了应用的权限。因为老的应用和数据有关联,因此,重新下载应用并且需要尝试做一个恢复出厂设置或者通过应用管理器删除应用关联的所有数据。 system uid = 1000 是特殊权限进程。

AID_SYSTEM 被定义为1000,即system server的UID。从上述代码可知,ServiceManager 会去检查应用程序的UID,当UID不符合规定时,便无法执行do_add_service()。也就是,当应用程序的UID不是1000时,没有权限新增Android Service的。所以,在AndroidManifest.xml 里加上 android:sharedUserId 属性的目的在于将应用程序的UID定义为android.uid.system 即1000,程式即可具备Android Service的权限。

以Mokoid 所提供的范例为例,因为我们是在Android 应用程式中启动Android Service,因此要特�留意这个部分。典型的新增 Android Service 做法是修改 frameworks/base/services/java/com/android/server/SystemServer.java文件,但是需要修改原始的 Android 代码。所以我们可以采用这种做法。

0 件のコメント:

コメントを投稿