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和数据路径等信息。

更多相关文章

  1. android:configChanges="orientation|keyboardHidden"的使用
  2. 介绍GLSurfaceView
  3. android 自动拨打含“#”如:*1234#的电话
  4. 如何发布android应用程序
  5. android闹钟
  6. Android(安卓)访问权限设置
  7. Basic4android:多功能的Android应用软件快速开发平台
  8. Android(安卓)Touch事件
  9. Android中日志信息的打印方式

随机推荐

  1. adb设备连接以及文件拷贝
  2. Android与HTML JavaScript交互
  3. Android 游戏开发的一些基础和经验
  4. android sqlite 介绍
  5. Android模拟器
  6. Android如何使布局中图(ImageButton)和文字
  7. Android实现2D翻转动画
  8. Android开发入门
  9. Android(安卓)WebView 开发详解(二)
  10. 【博客园客户端】博客园Android客户端更