android p 权限流程,Android native 权限控制流程
關(guān)聯(lián)文章:
前言:
在 Android Runtime Permission 詳解 中詳細(xì)的說明了permission 在Android 6.0 前后的區(qū)別,對于M 以后應(yīng)用可以通過checkPermission 、requestPermission 等一系列的接口控制,但是在M之前的應(yīng)用是看不到這樣的接口,功能的開啟會直接調(diào)用接口,例如Camera,會直接調(diào)用open 的接口。
那我們?nèi)绾蝸砜刂七@些權(quán)限的呢?在M 之后的系統(tǒng)中,native 的接口里會通過checkPermission 的接口,來確認(rèn)是否擁有改功能對應(yīng)的權(quán)限,例如Camera,會check android.permission.CAMERA 這個權(quán)限。
這一篇博文就是分析M 之后系統(tǒng)對于權(quán)限native接口的控制流程。
源碼分析:
首先來看IServiceManager.h:
namespace android {
// ----------------------------------------------------------------------
class IServiceManager : public IInterface
{
...
...
};
sp defaultServiceManager();
template
status_t getService(const String16& name, sp* outService)
{
const sp sm = defaultServiceManager();
if (sm != NULL) {
*outService = interface_cast(sm->getService(name));
if ((*outService) != NULL) return NO_ERROR;
}
return NAME_NOT_FOUND;
}
bool checkCallingPermission(const String16& permission);
bool checkCallingPermission(const String16& permission,
int32_t* outPid, int32_t* outUid);
bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
}; // namespace android
1、首先命名空間是android,所以有的地方通過接口android::checkPermission 來調(diào)用此處的接口
例如,PermissionCache.cpp 中:
bool PermissionCache::checkPermission(
const String16& permission, pid_t pid, uid_t uid) {
if ((uid == 0) || (pid == getpid())) {
// root and ourselves is always okay
return true;
}
PermissionCache& pc(PermissionCache::getInstance());
bool granted = false;
if (pc.check(&granted, permission, uid) != NO_ERROR) {
nsecs_t t = -systemTime();
granted = android::checkPermission(permission, pid, uid);
t += systemTime();
ALOGD("checking %s for uid=%d => %s (%d us)",
String8(permission).string(), uid,
granted?"granted":"denied", (int)ns2us(t));
pc.cache(permission, uid, granted);
}
return granted;
2、之所以首先來看IServiceManager.h,是因?yàn)槠渲刑峁┝撕芏郺ndroid 空間中的公共接口,例如defaultServiceManager()、getService()、checkPermission()
最終checkPermission() 實(shí)現(xiàn)的地方是在IServiceManger.cpp 中:
bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
{
sp pc;
gDefaultServiceManagerLock.lock();
pc = gPermissionController;
gDefaultServiceManagerLock.unlock();
int64_t startTime = 0;
while (true) {
if (pc != NULL) {
bool res = pc->checkPermission(permission, pid, uid);
...
}
...
}
...
}
通過IPermissionController 來調(diào)用checkPermission()
來看下IPermissionController.h:
class IPermissionController : public IInterface
{
public:
DECLARE_META_INTERFACE(PermissionController)
virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0;
virtual void getPackagesForUid(const uid_t uid, Vector &packages) = 0;
virtual bool isRuntimePermission(const String16& permission) = 0;
enum {
CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2
};
};
class BnPermissionController : public BnInterface
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
實(shí)現(xiàn)的地方就看BnPermissionController 的地方了,從整個項(xiàng)目來看,native 會啟動一個permission 的native service,詳細(xì)看framework/native/services/nativeperms/nativeperms.cpp:
class PermissionService : public android::os::BnPermissionController {
public:
::android::binder::Status checkPermission(
const ::android::String16& permission, int32_t pid, int32_t uid,
bool* _aidl_return) {
(void)permission;
(void)pid;
(void)uid;
*_aidl_return = true;
return binder::Status::ok();
}
再來看下Java 中android.os.IPermissionController,首先來看aidl,
package android.os;
/** @hide */
interface IPermissionController {
boolean checkPermission(String permission, int pid, int uid);
String[] getPackagesForUid(int uid);
boolean isRuntimePermission(String permission);
}
跟著這個aidl 來知道它的service 端,在ActivityManagerService.java中,
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));//這里添加permission 的service
ServiceManager.addService("processinfo", new ProcessInfoService(this));
接著就是service 端:
static class PermissionController extends IPermissionController.Stub {
ActivityManagerService mActivityManagerService;
PermissionController(ActivityManagerService activityManagerService) {
mActivityManagerService = activityManagerService;
}
@Override
public boolean checkPermission(String permission, int pid, int uid) {
return mActivityManagerService.checkPermission(permission, pid,
uid) == PackageManager.PERMISSION_GRANTED;
}
接著:
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
return checkComponentPermission(permission, pid, uid, -1, true);
}
接著:
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported);
}
接著:
public static int checkComponentPermission(String permission, int uid,
int owningUid, boolean exported) {
...
...
try {
return AppGlobals.getPackageManager()
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
最終會調(diào)到PMS 中的checkUidPermission,完成最后的確認(rèn)工作。
這里source code 基本都是邏輯問題,不需要詳細(xì)講解,有什么問題可以隨時交流。
checkUidPermission 的source code 這里暫不貼出來,詳細(xì)可以看下 android grantRuntimePermission 詳解
其實(shí),最主要的是PermissionsState 中的mPermissions,如果grant 了,那么里面會有這樣的permission,如果是revoke 的,那么就不會有這樣的permission。當(dāng)然,對于M 之前的app,這里默認(rèn)肯定都是granted的。
這一篇博文主要是分析native 的check 流程,至于CTA 要求M 之前app 同樣需要彈出對話框提示用戶,看另一篇博文。
總結(jié)
以上是生活随笔為你收集整理的android p 权限流程,Android native 权限控制流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 7.0 mi5s,官方回
- 下一篇: iqooz1手机能搭载鸿蒙吗,我最近看中