Android(安卓)系统对permision的检测过程
16lz
2021-12-04
Android 系统对permision的检测过程
RK3288 5.1 中以太网设置静态IP 对permission的检测
简略的调用过程如下:
frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetServiceImpl.java
public void setConfiguration(IpConfiguration config) { if (!mStarted.get()) { Log.w(TAG, "System isn't ready enough to change ethernet configuration"); } enforceChangePermission(); enforceConnectivityInternalPermission(); synchronized (mIpConfiguration) { mEthernetConfigStore.writeIpAndProxyConfigurations(config); // TODO: this does not check proxy settings, gateways, etc. // Fix this by making IpConfiguration a complete representation of static configuration. if (!config.equals(mIpConfiguration)) { mIpConfiguration = new IpConfiguration(config); mTracker.stop(); mTracker.start(mContext, mHandler); } } } private void enforceConnectivityInternalPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService"); }
frameworks\base\core\java\android\app\ContextImpl.java
public void enforceCallingOrSelfPermission( String permission, String message) { enforce(permission, checkCallingOrSelfPermission(permission), true, Binder.getCallingUid(), message);
通过Binder这个类,可以获得调用服务的应用的ID,通过这个ID,可以获得应用的相关信息;
@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; } }
frameworks\base\services\core\java\com\android\server\ActivityManagerService.java
@Override public int checkPermission(String permission, int pid, int uid) { if (permission == null) { return PackageManager.PERMISSION_DENIED; } return checkComponentPermission(permission, pid, UserHandle.getAppId(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); }
frameworks\base\core\java\android\app\ActivityManager.java
/** @hide */ public static int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { // Root, system server get to do everything. if (uid == 0 || uid == Process.SYSTEM_UID) { return PackageManager.PERMISSION_GRANTED; } // Isolated processes don't get any permissions. if (UserHandle.isIsolated(uid)) { return PackageManager.PERMISSION_DENIED; } // 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 && UserHandle.isSameApp(uid, owningUid)) { return PackageManager.PERMISSION_GRANTED; } // If the target is not exported, then nobody else can get to it. if (!exported) { /* RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid, here); */ 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; }
对于普通应用将通过PackageManagerService中保持的信息进行判断是否具有相应的权限;
base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override public int checkUidPermission(String permName, int uid) { synchronized (mPackages) { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); if (obj != null) { GrantedPermissions gp = (GrantedPermissions)obj; if (gp.grantedPermissions.contains(permName)) { return PackageManager.PERMISSION_GRANTED; } } else { ArraySet perms = mSystemPermissions.get(uid); if (perms != null && perms.contains(permName)) { return PackageManager.PERMISSION_GRANTED; } } } return PackageManager.PERMISSION_DENIED; }
每次开机系统PackageManagerService都会还原现有app的安装信息,这些信息被放在/data/system/packages.xml里,由mSettings管理。另外/data/system/packages.list记录了app的uid和数据路径等信息。
更多相关文章
- android:configChanges="orientation|keyboardHidden"的使用
- 介绍GLSurfaceView
- android 自动拨打含“#”如:*1234#的电话
- 如何发布android应用程序
- android闹钟
- Android(安卓)访问权限设置
- Basic4android:多功能的Android应用软件快速开发平台
- Android(安卓)Touch事件
- Android中日志信息的打印方式