# 权限管理框架

## 概述

Android权限管理框架是Android系统安全的核心机制之一，用于控制应用对系统资源和用户数据的访问。

## 权限系统架构

### 1. 权限类型

#### 普通权限（Normal Permissions）
- **特点**: 不涉及用户隐私，系统自动授予
- **示例**: INTERNET, ACCESS_NETWORK_STATE
- **授予方式**: 安装时自动授予

#### 危险权限（Dangerous Permissions）
- **特点**: 涉及用户隐私或系统安全
- **示例**: CAMERA, READ_CONTACTS, WRITE_EXTERNAL_STORAGE
- **授予方式**: 运行时动态申请

#### 签名权限（Signature Permissions）
- **特点**: 只有与定义权限的应用使用相同签名才能获得
- **示例**: 系统级权限
- **授予方式**: 签名匹配时自动授予

#### 特殊权限（Special Permissions）
- **特点**: 需要用户手动在设置中授予
- **示例**: SYSTEM_ALERT_WINDOW, WRITE_SETTINGS
- **授予方式**: 跳转到设置页面授予

### 2. 权限声明

#### AndroidManifest.xml声明
```xml
<manifest>
    <!-- 声明权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    
    <!-- 定义自定义权限 -->
    <permission
        android:name="com.example.CUSTOM_PERMISSION"
        android:label="自定义权限"
        android:description="权限描述"
        android:protectionLevel="dangerous" />
</manifest>
```

#### 保护级别（Protection Level）
- **normal**: 普通权限
- **dangerous**: 危险权限
- **signature**: 签名权限
- **signatureOrSystem**: 签名或系统权限

### 3. 权限组

#### 权限组概念
- 相关权限归为一组
- 授予组内一个权限，组内其他权限自动授予
- 撤销组内一个权限，组内其他权限自动撤销

#### 常见权限组
- **CALENDAR**: 日历相关权限
- **CAMERA**: 相机权限
- **CONTACTS**: 联系人权限
- **LOCATION**: 位置权限
- **MICROPHONE**: 麦克风权限
- **PHONE**: 电话权限
- **SENSORS**: 传感器权限
- **SMS**: 短信权限
- **STORAGE**: 存储权限

## 权限申请流程

### 1. 运行时权限申请（Android 6.0+）

#### 检查权限
```java
// 检查权限是否已授予
if (ContextCompat.checkSelfPermission(context, 
        Manifest.permission.CAMERA) 
        != PackageManager.PERMISSION_GRANTED) {
    // 权限未授予，需要申请
}
```

#### 申请权限
```java
// 申请权限
ActivityCompat.requestPermissions(activity,
    new String[]{Manifest.permission.CAMERA},
    REQUEST_CODE_CAMERA);
```

#### 处理权限结果
```java
@Override
public void onRequestPermissionsResult(int requestCode,
        @NonNull String[] permissions,
        @NonNull int[] grantResults) {
    if (requestCode == REQUEST_CODE_CAMERA) {
        if (grantResults.length > 0 && 
            grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 权限已授予
            useCamera();
        } else {
            // 权限被拒绝
            handlePermissionDenied();
        }
    }
}
```

### 2. 权限申请最佳实践

#### 解释权限用途
```java
// 如果用户之前拒绝过权限，解释为什么需要权限
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
        Manifest.permission.CAMERA)) {
    // 显示解释对话框
    showExplanationDialog();
} else {
    // 直接申请权限
    requestPermission();
}
```

#### 处理永久拒绝
```java
// 检查是否永久拒绝（不再询问）
if (!ActivityCompat.shouldShowRequestPermissionRationale(activity,
        Manifest.permission.CAMERA) &&
    !isPermissionGranted()) {
    // 引导用户到设置页面
    openAppSettings();
}
```

## 权限管理实现

### 1. PackageManagerService

#### 权限检查
```java
// PackageManagerService.java
public int checkPermission(String permName, String pkgName, int userId) {
    // 检查权限是否授予
    // 返回PERMISSION_GRANTED或PERMISSION_DENIED
}
```

#### 权限授予
```java
public void grantRuntimePermission(String packageName, 
        String permissionName, int userId) {
    // 授予运行时权限
    // 更新权限状态
    // 通知相关组件
}
```

### 2. PermissionController

#### 权限管理界面
- 系统权限管理应用
- 用户权限设置界面
- 权限使用统计

#### 权限策略
- 自动撤销未使用权限
- 权限使用提醒
- 权限使用统计

## 权限最佳实践

### 1. 最小权限原则
```java
// ❌ 错误：申请过多权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

// ✅ 正确：只申请必要的权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
```

### 2. 运行时权限检查
```java
// 每次使用前都检查权限
if (checkPermission()) {
    useFeature();
} else {
    requestPermission();
}
```

### 3. 权限使用说明
```java
// 向用户解释为什么需要权限
private void showPermissionExplanation() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("需要相机权限");
    builder.setMessage("我们需要相机权限来拍摄照片");
    builder.setPositiveButton("确定", (dialog, which) -> {
        requestPermission();
    });
    builder.show();
}
```

### 4. 权限撤销处理
```java
// 监听权限变化
private BroadcastReceiver permissionReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(
                PackageManager.ACTION_PERMISSION_REVOKED)) {
            // 权限被撤销，处理逻辑
            handlePermissionRevoked();
        }
    }
};
```

## 自定义权限

### 1. 定义自定义权限
```xml
<!-- AndroidManifest.xml -->
<permission
    android:name="com.example.CUSTOM_PERMISSION"
    android:label="自定义权限"
    android:description="这是自定义权限的描述"
    android:protectionLevel="dangerous"
    android:permissionGroup="com.example.PERMISSION_GROUP" />
```

### 2. 使用自定义权限
```xml
<!-- 在需要保护的组件上使用 -->
<activity
    android:name=".ProtectedActivity"
    android:permission="com.example.CUSTOM_PERMISSION" />
```

### 3. 检查自定义权限
```java
// 检查自定义权限
if (checkSelfPermission("com.example.CUSTOM_PERMISSION") 
        == PackageManager.PERMISSION_GRANTED) {
    // 权限已授予
}
```

## 系统权限

### 1. 系统级权限
- **SYSTEM_ALERT_WINDOW**: 悬浮窗权限
- **WRITE_SETTINGS**: 系统设置权限
- **REQUEST_IGNORE_BATTERY_OPTIMIZATIONS**: 忽略电池优化

### 2. 系统权限申请
```java
// 申请系统权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.canDrawOverlays(this)) {
        Intent intent = new Intent(
            Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }
}
```

## 权限调试

### 1. 查看权限状态
```bash
# 查看应用权限
adb shell dumpsys package com.example.app | grep permission

# 查看所有权限
adb shell pm list permissions

# 查看权限组
adb shell pm list permission-groups
```

### 2. 授予/撤销权限
```bash
# 授予权限
adb shell pm grant com.example.app android.permission.CAMERA

# 撤销权限
adb shell pm revoke com.example.app android.permission.CAMERA
```

### 3. 权限测试
```bash
# 重置权限
adb shell pm reset-permissions

# 清除应用数据（会清除权限）
adb shell pm clear com.example.app
```

## 安全考虑

### 1. 权限滥用防护
- 检查权限使用合理性
- 监控权限使用情况
- 及时撤销未使用权限

### 2. 权限泄露防护
- 避免权限泄露
- 安全存储权限信息
- 防止权限被恶意利用

### 3. 权限升级攻击防护
- 防止权限升级攻击
- 验证权限授予来源
- 监控异常权限授予

## 相关链接

- [[README]]
- [[04-资源与包管理/PackageManagerService]]
- [[漏洞案例库]]