Android系统层应用列表过滤实现方案

278 阅读3分钟

1. 需求分析与架构设计

核心需求
在系统级实现应用列表过滤功能,满足以下要求:

  1. 动态维护过滤规则(支持黑白名单)
  2. 多用户隔离策略
  3. 高性能过滤(<5ms延迟)
  4. 兼容主流Android版本(8.0+)

架构设计

plaintext
                +----------------+
                |   SystemUI     |
                +----------------+
                        |+----------------+
                |  PackageManager|
                +----------------+
                        |+----------------+
                |  PMS Extension |
                +----------------+
                        |
           +------------+------------+
           ↓                         ↓
+-------------------+      +-------------------+
|   Filter Config   |      |  Filter Engine    |
| (XML/DB/Settings) |      | (Real-time Filter)|
+-------------------+      +-------------------+

2. 核心功能实现

2.1 过滤规则管理服务
新增系统服务AppFilterManagerService

java
public class AppFilterManagerService extends SystemService {
    private static final String TAG = "AppFilterManager";
    
    // 过滤规则存储路径
    private static final String FILTER_XML = "/data/system/app_filter.xml";
    
    // 内存缓存规则
    private final ArrayMap<Integer, AppFilterPolicy> mUserPolicies = new ArrayMap<>();

    @Override
    public void onStart() {
        publishBinderService(Context.APP_FILTER_SERVICE, new BinderService());
    }

    // 按用户加载过滤规则
    private void loadPolicyForUser(int userId) {
        AppFilterPolicy policy = new AppFilterPolicy();
        File configFile = new File(FILTER_XML);
        if (configFile.exists()) {
            // XML解析实现
            try (FileInputStream fis = new FileInputStream(configFile)) {
                XmlPullParser parser = Xml.newPullParser();
                parser.setInput(fis, StandardCharsets.UTF_8.name());
                // ...解析逻辑
            }
        }
        mUserPolicies.put(userId, policy);
    }

    // Binder接口实现
    private final class BinderService extends IAppFilterManager.Stub {
        @Override
        public void addFilterRule(int userId, AppFilterRule rule) {
            // 权限校验
            enforceManageAppFilterPermission();
            synchronized (mUserPolicies) {
                AppFilterPolicy policy = mUserPolicies.get(userId);
                policy.addRule(rule);
                persistPolicy(userId);
            }
        }

        @Override
        public boolean shouldFilterApp(int userId, String packageName) {
            synchronized (mUserPolicies) {
                AppFilterPolicy policy = mUserPolicies.get(userId);
                return policy != null && policy.matches(packageName);
            }
        }
    }
}

2.2 PMS查询逻辑增强
修改PackageManagerService.queryIntentActivitiesInternal

java
List<ResolveInfo> queryIntentActivitiesInternal(...) {
    List<ResolveInfo> result = /* 原始查询逻辑 */;
    
    // 新增过滤逻辑
    IAppFilterManager filterManager = IAppFilterManager.Stub.asInterface(
        ServiceManager.getService(Context.APP_FILTER_SERVICE));
    
    Iterator<ResolveInfo> iterator = result.iterator();
    while (iterator.hasNext()) {
        ResolveInfo info = iterator.next();
        if (filterManager.shouldFilterApp(userId, info.activityInfo.packageName)) {
            iterator.remove();
        }
    }
    
    return result;
}

3. 过滤规则配置方案

3.1 XML规则格式

xml
<filter-policy user="0">
    <blacklist>
        <item>com.example.hiddenapp1</item>
        <item>com.example.hiddenapp2</item>
    </blacklist>
    <whitelist>
        <item>com.example.essentialapp</item>
    </whitelist>
</filter-policy>

3.2 动态配置接口
通过cmd命令实现实时更新:

bash
adb shell cmd app_filter add --user 0 --pkg com.example.hiddenapp
adb shell cmd app_filter remove --user 0 --pkg com.example.hiddenapp

3.3 多用户支持

java
public boolean shouldFilterApp(int userId, String packageName) {
    // 获取当前用户的父用户策略(适用于Work Profile)
    int parentUserId = getParentUserId(userId);
    AppFilterPolicy parentPolicy = mUserPolicies.get(parentUserId);
    
    // 合并策略逻辑
    return userPolicy.matches(pkg) || (parentPolicy != null && parentPolicy.matches(pkg));
}

4. 性能优化措施

4.1 内存缓存优化
使用LRU缓存策略:

java
private static final int MAX_CACHED_USERS = 5;
private LruCache<Integer, AppFilterPolicy> mPolicyCache = new LruCache<>(MAX_CACHED_USERS) {
    protected void entryRemoved(boolean evicted, Integer key, 
        AppFilterPolicy oldValue, AppFilterPolicy newValue) {
        persistPolicy(key); // 策略淘汰时自动持久化
    }
};

4.2 快速匹配算法
使用Trie树进行包名匹配:

java
class AppFilterPolicy {
    private TrieNode blacklistTrie;
    private Set<String> whitelist;

    boolean matches(String packageName) {
        // 白名单优先
        if (whitelist.contains(packageName)) return false;
        // Trie树匹配黑名单
        return blacklistTrie.contains(packageName);
    }
}

5. 安全与权限控制

5.1 权限声明
新增系统权限:

xml
<permission android:name="android.permission.MANAGE_APP_FILTER"
    android:protectionLevel="signature|privileged"/>

5.2 Binder调用校验

java
private void enforceManageAppFilterPermission() {
    if (Binder.getCallingUid() != Process.SYSTEM_UID) {
        throw new SecurityException("Requires MANAGE_APP_FILTER permission");
    }
}

6. 兼容性处理

6.1 版本适配方案
通过@SystemApi控制接口可见性:

java
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public interface IAppFilterManager {
    void addFilterRule(int userId, AppFilterRule rule);
    boolean shouldFilterApp(int userId, String packageName);
}

6.2 降级策略
当过滤服务不可用时自动跳过:

java
try {
    if (filterManager != null && filterManager.shouldFilterApp(...)) {
        iterator.remove();
    }
} catch (RemoteException e) {
    Slog.w(TAG, "AppFilter service unavailable", e);
}

7. 验证与测试

7.1 单元测试用例

java
@RunWith(AndroidJUnit4.class)
public class AppFilterTest {
    @Test
    public void testBasicFiltering() {
        // 添加过滤规则
        mFilterManager.addFilterRule(0, new AppFilterRule("com.example.hidden"));
        
        // 查询应用列表
        List<ResolveInfo> apps = mPms.queryIntentActivities(...);
        
        // 验证过滤结果
        assertFalse(containsPackage(apps, "com.example.hidden"));
    }
}

7.2 性能基准测试
使用Jetpack Macrobenchmark:

kotlin
@RunWith(AndroidJUnit4::class)
class FilterPerformanceTest {
    @get:Rule
    val rule = MacrobenchmarkRule()

    @Test
    fun queryAppsWithFilter() {
        rule.measureRepeated(
            packageName = "com.android.systemui",
            metrics = listOf(StartupTimingMetric()),
            iterations = 10,
            setup = { addFilterRules() }
        ) {
            startActivityAndWait(Intent(Intent.ACTION_MAIN).apply {
                addCategory(Intent.CATEGORY_HOME)
            })
        }
    }
}

通过以上系统级方案,可在不修改应用层代码的前提下,实现灵活高效的应用列表过滤功能。建议采用动态配置与内存缓存相结合的方式,在保证性能的同时满足企业级设备管理的多样化需求。