# PackageManagerService架构

PackageManagerService（PMS）是Android包管理系统的核心服务，负责应用的安装、卸载、更新和权限管理。本文深入分析PMS的架构设计、工作原理和关键实现。

## PMS系统架构概览

```mermaid
graph TB
    subgraph "客户端层"
        A1[PackageManager] --> A2[IPackageManager]
        A2 --> A3[Binder通信]
    end
    
    subgraph "服务端层"
        B1[PackageManagerService] --> B2[PackageParser]
        B2 --> B3[PackageSettings]
        B3 --> B4[Installer]
        
        B1 --> B5[UserManagerService]
        B1 --> B6[ActivityManagerService]
        B1 --> B7[StorageManagerService]
    end
    
    subgraph "数据层"
        C1[Package数据库] --> C2[Settings.xml]
        C2 --> C3[包目录结构]
        C3 --> C4[APK文件]
    end
    
    A3 --> B1
    B4 --> C4
```

## 1. PMS核心组件

### 1.1 PackageManagerService
- **包管理**：管理所有应用的安装、卸载和更新
- **权限管理**：管理应用权限的授予和撤销
- **组件管理**：管理Activity、Service等组件信息
- **包扫描**：扫描系统和应用目录中的APK文件

### 1.2 PackageParser
- **APK解析**：解析APK文件的AndroidManifest.xml
- **组件提取**：提取Activity、Service等组件信息
- **资源解析**：解析APK中的资源信息
- **签名验证**：验证APK的签名信息

### 1.3 PackageSettings
- **包设置**：存储包的安装信息和设置
- **用户管理**：管理多用户下的包状态
- **权限状态**：存储权限授予状态
- **包状态**：存储包的启用/禁用状态

## 2. 包安装流程

### 2.1 安装流程概览
```java
// PMS安装应用的关键流程
public void installPackageAsUser(Uri packageUri, ...) {
    // 1. 权限检查
    enforcePermission(...);
    
    // 2. 创建安装会话
    int sessionId = createInstallSession(...);
    
    // 3. 写入APK文件
    writeApkToSession(sessionId, packageUri);
    
    // 4. 提交安装
    commitSession(sessionId);
    
    // 5. 解析APK
    PackageParser.Package pkg = parsePackage(...);
    
    // 6. 验证签名
    verifySignatures(pkg);
    
    // 7. 执行安装
    installPackageTracedLI(pkg, ...);
    
    // 8. 发送广播
    sendPackageBroadcast(...);
}
```

### 2.2 APK解析过程
```java
// PackageParser解析APK
public Package parsePackage(File apkFile, int flags) {
    // 1. 创建解析器
    PackageParser parser = new PackageParser();
    
    // 2. 解析APK
    Package pkg = parser.parsePackage(apkFile, flags);
    
    // 3. 收集组件信息
    collectCertificates(pkg);
    collectManifestDigest(pkg);
    
    // 4. 提取四大组件
    extractActivities(pkg);
    extractServices(pkg);
    extractReceivers(pkg);
    extractProviders(pkg);
    
    // 5. 提取权限信息
    extractPermissions(pkg);
    
    return pkg;
}
```

## 3. 包扫描机制

### 3.1 系统扫描
- **系统目录扫描**：扫描/system/app、/system/priv-app等目录
- **厂商目录扫描**：扫描/vendor/app等厂商目录
- **OEM目录扫描**：扫描/oem/app等OEM目录

### 3.2 用户数据扫描
- **用户安装目录**：扫描/data/app等用户安装目录
- **用户数据目录**：扫描/data/user等用户数据目录
- **外部存储扫描**：扫描外部存储中的APK文件

### 3.3 扫描优化
```java
// PMS包扫描优化策略
class PackageManagerService {
    // 增量扫描：只扫描变化的目录
    void scanPackagesTracedLI(File scanDir, int scanFlags, ...) {
        // 1. 检查目录修改时间
        long lastModified = getLastModifiedTime(scanDir);
        if (lastModified <= mLastScanTime) {
            return; // 目录未修改，跳过扫描
        }
        
        // 2. 增量扫描
        List<File> changedFiles = getChangedFiles(scanDir, mLastScanTime);
        for (File file : changedFiles) {
            scanPackageTracedLI(file, scanFlags, ...);
        }
        
        // 3. 更新扫描时间
        mLastScanTime = System.currentTimeMillis();
    }
    
    // 并行扫描：多线程并行扫描
    void parallelScanPackages(List<File> scanDirs) {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        List<Future<Package>> futures = new ArrayList<>();
        
        for (File dir : scanDirs) {
            futures.add(executor.submit(() -> scanPackage(dir)));
        }
        
        // 等待所有扫描完成
        for (Future<Package> future : futures) {
            Package pkg = future.get();
            addPackage(pkg);
        }
    }
}
```

## 4. 权限管理系统

### 4.1 权限分类
- **普通权限**：不影响用户隐私的权限
- **危险权限**：涉及用户隐私的权限
- **签名权限**：需要相同签名的权限
- **特殊权限**：系统特殊权限

### 4.2 权限授予流程
```java
// PMS权限授予流程
public void grantRuntimePermission(String packageName, String permName, int userId) {
    // 1. 检查权限是否存在
    BasePermission bp = mSettings.mPermissions.get(permName);
    if (bp == null) {
        throw new SecurityException("Unknown permission: " + permName);
    }
    
    // 2. 检查调用者权限
    enforceGrantRevokeRuntimePermissionPermissions(...);
    
    // 3. 检查目标应用是否申请该权限
    PackageParser.Package pkg = getPackage(packageName);
    if (!pkg.requestedPermissions.contains(permName)) {
        throw new SecurityException("Package " + packageName + " has not requested permission " + permName);
    }
    
    // 4. 授予权限
    PermissionState permState = mSettings.getPermissionState(permName, packageName, userId);
    permState.granted = true;
    permState.grantedFlags = flags;
    
    // 5. 更新权限状态
    updatePermissions(packageName, pkg);
    
    // 6. 发送广播通知
    sendPackageChangedBroadcast(packageName, userId);
}
```

## 5. 多用户支持

### 5.1 用户隔离
- **用户ID**：每个用户有唯一的用户ID
- **数据隔离**：不同用户的数据完全隔离
- **权限隔离**：不同用户的权限状态独立

### 5.2 用户管理
```java
// PMS多用户管理
class PackageManagerService {
    // 用户包状态管理
    final SparseArray<PackageSetting> mSettingsByUser = new SparseArray<>();
    
    // 为用户安装包
    void installPackageAsUser(String packageName, int userId) {
        // 1. 获取主用户包信息
        PackageSetting ps = getPackageSetting(packageName, UserHandle.USER_SYSTEM);
        
        // 2. 为用户创建包状态
        PackageSetting userPs = createPackageSettingForUser(ps, userId);
        
        // 3. 设置用户包状态
        mSettingsByUser.put(userId, userPs);
        
        // 4. 创建用户数据目录
        createUserDataIfNeeded(packageName, userId);
    }
    
    // 删除用户包
    void removePackageAsUser(String packageName, int userId) {
        // 1. 删除用户包状态
        mSettingsByUser.remove(userId);
        
        // 2. 删除用户数据目录
        deleteUserData(packageName, userId);
        
        // 3. 清理缓存
        clearPackagePreferredActivities(packageName, userId);
    }
}
```

## 6. 性能优化

### 6.1 启动优化
- **延迟扫描**：非关键目录延迟扫描
- **并行解析**：多APK并行解析
- **缓存机制**：缓存已解析的包信息

### 6.2 内存优化
- **对象复用**：复用PackageParser等对象
- **懒加载**：按需加载包信息
- **资源释放**：及时释放不再使用的资源

### 6.3 存储优化
- **增量更新**：只更新变化的包信息
- **压缩存储**：压缩存储包元数据
- **索引优化**：优化包查询索引

## 7. 调试与问题排查

### 7.1 调试工具
```bash
# 查看包信息
adb shell dumpsys package <package_name>

# 查看权限信息
adb shell dumpsys package permissions

# 查看安装会话
adb shell dumpsys package sessions

# 查看包管理器状态
adb shell dumpsys package

# 性能分析
adb shell dumpsys package --timing
```

### 7.2 常见问题
- **安装失败**：签名验证失败、存储空间不足等
- **权限问题**：权限未正确授予或撤销
- **包冲突**：相同包名或签名的包冲突
- **扫描问题**：APK文件损坏或格式错误
- **性能问题**：包扫描或解析耗时过长

### 7.3 问题排查步骤
1. **收集日志**：查看logcat中的PMS相关日志
2. **检查状态**：使用dumpsys命令检查包状态
3. **验证APK**：检查APK文件完整性和签名
4. **分析配置**：检查系统配置和权限设置
5. **性能分析**：使用性能分析工具定位瓶颈

## 总结

PackageManagerService是Android系统的核心服务：
- **应用管理**：统一管理所有应用的安装和卸载
- **权限控制**：严格控制应用权限的授予和使用
- **组件管理**：管理应用组件的注册和发现
- **多用户支持**：支持多用户环境下的应用隔离
- **系统稳定**：确保应用安装和运行的稳定性

深入理解PackageManagerService架构，对于优化应用安装体验、排查包管理问题和设计系统级功能具有重要意义。