use*_*010 4 android android-source android-framework
有人能指出我与Android应用程序框架开发相关的教程吗?在这里,我特别谈论"应用程序框架"(Android架构顶部的第二层)而不是App开发.
我感兴趣的是:在任何应用程序调用系统/框架API后会发生什么?操作系统如何检查该应用程序是否具有该特定权限?"应用程序框架"中的哪个组件处理此检查?哪个java类负责呢?
我想玩这些java类并做一些观察.
PS:我假设权限模型是在"应用程序框架"层中实现的.如果我错了,请纠正我.
BMB*_*BMB 10
据我所知,框架开发的资源有限,大部分可用资源分布在不同的博客和邮件列表中.要开始,我会推荐开源项目站点source.android.com.它包含有关如何执行操作的有限文档,但至少提供了使用开源项目的设置.然后是与平台和框架级开发相关的官方邮件列表.不同的ROM项目也可能在Cyanogenmod wiki等网站上提供有用的信息.
然后回答有关如何在框架中实现权限的特定问题.没有处理检查的特定组件,框架中的每个服务提供者都需要在允许服务调用之前执行权限检查.这种检查涉及两个重要部分,系统服务器中的包管理器和Binder IPC机制.包管理器是处理应用程序安装的OS组件.这将在安装时解析AndroidManifest.xml文件,提示用户输入权限并维护特定应用程序拥有的权限的注册表.这是基于每个应用程序使用自己的Linux用户ID运行的想法.对于每个uid,都有一个权限列表.
第二部分是Binder进程间通信机制.Binder是一种面向对象的执行IPC的方式,但它也实现了一些安全功能.与权限相关的最重要的一个是它使得IPC调用的接收端可以检查调用者的uid.受权限保护的服务将具有Binder接口,并将为其收到的每个请求执行两项操作.首先,它将调用绑定器来获取调用者的uid然后它将调用提供uid的系统服务器以及检查它是否已被授予的权限.如果检查没问题,它将继续执行服务调用,否则会引发安全异常.
如果我们看一下源代码,首先要简单地调用振动器服务.(以下所有代码均为Apache 2.0许可下的Android开源项目版权所有).
public void vibrate(long milliseconds, IBinder token) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires VIBRATE permission");
}
Run Code Online (Sandbox Code Playgroud)
框架级别权限检查的实现属于Context类,更具体地说,我们将ContextImpl.java文件放在其中
@Override
public int checkCallingOrSelfPermission(String permission) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
return checkPermission(permission, Binder.getCallingPid(),
Binder.getCallingUid());
}
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
try {
return ActivityManagerNative.getDefault().checkPermission(
permission, pid, uid);
} catch (RemoteException e) {
return PackageManager.PERMISSION_DENIED;
}
}
Run Code Online (Sandbox Code Playgroud)
这是通过Binder调用ActivityManagerService,我们最终将在:
/**
* As the only public entry point for permissions checking, this method
* can enforce the semantic that requesting a check on a null global
* permission is automatically denied. (Internally a null permission
* string is used when calling {@link #checkComponentPermission} in cases
* when only uid-based security is needed.)
*
* This can be called with or without the global lock held.
*/
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
return checkComponentPermission(permission, pid, uid, -1, true);
}
/**
* This can be called with or without the global lock held.
*/
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
// We might be performing an operation on behalf of an indirect binder
// invocation, e.g. via {@link #openContentUri}. Check and adjust the
// client identity accordingly before proceeding.
Identity tlsIdentity = sCallerIdentity.get();
if (tlsIdentity != null) {
Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
+ tlsIdentity.pid + "," + tlsIdentity.uid + "}");
uid = tlsIdentity.uid;
pid = tlsIdentity.pid;
}
// Root, system server and our own process get to do everything.
if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
// If there is a uid that owns whatever is being accessed, it has
// blanket access to it regardless of the permissions it requires.
if (owningUid >= 0 && uid == owningUid) {
return PackageManager.PERMISSION_GRANTED;
}
// If the target is not exported, then nobody else can get to it.
if (!exported) {
Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
return PackageManager.PERMISSION_DENIED;
}
if (permission == null) {
return PackageManager.PERMISSION_GRANTED;
}
try {
return AppGlobals.getPackageManager()
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
// Should never happen, but if it does... deny!
Slog.e(TAG, "PackageManager is dead?!?", e);
}
return PackageManager.PERMISSION_DENIED;
}
Run Code Online (Sandbox Code Playgroud)
对包管理器checkUidPermission的调用将执行查找以使uid与已授予权限的表匹配.如果要继续跟踪源,则相关文件为PackageManagerService.java.
如果您正在进行研究,请随意深入研究开源项目中框架/ base /中的代码.上面提到的所有文件都在那里.按照构建说明操作,您应该能够使用模拟器测试更改.如果您不想自己修改核心框架文件,请查看/ device/sample中有关如何进行框架扩展的示例.也就是说,大多数与权限相关的API都可以从应用程序级别获得,因此您可以成功地拥有一个提供服务的应用程序并自行检查该权限.
| 归档时间: |
|
| 查看次数: |
2350 次 |
| 最近记录: |