Blocking particular apps in Android (By modifying source code)

http://stackoverflow.com/questions/16222320/blocking-particular-apps-in-android-by-modifying-source-code


1 down vote accepted

In general, when an intent can be handled by an application(its activity, service), and the user prefers that application to handle it. The ActivityManagerService(Ams) in Android framework will first see whether the corresponding application of the target activity/service is still alive. If it hasn't been started yet or killed, the Ams will start that application by calling startProcessLocked method.

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated) {
    //you can get the uid from ApplicationInfo.uid
    ...
    startProcessLocked(app, hostingType, hostingNameStr);
    ...
}

private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
    //prepare its uid, gid, gids for starting that process
    ...
    Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, null, null);
    ...
}

So in that method, it start a new process. The Process.start is what you have mentioned in your question, and it finally calls Zygote to fork a new process.

I think intercepting the application startup process in Ams is a better way. You can get more information about this application and it is also the upstream of your Process.start method.

UPDATE:

Just noticed that you were thinking about restricting intent. An intent can be handled by multiple applications, so we cannot restrict applications from sending a particular intent. But we can modify the resolving process. Resolving means the Android framework need to determine which activity/service can handle this intent. If there are multiple choices and the user haven't set any preference, then the following dialog will appear:

Intent Handling

So it is possible to modify the resolving process to let the Android framework discard the fact that your specific application is able to handle that intent. I think this is also a way to do your work but it is much more compilicated because Android resolves intent differently for activity, service and receiver. For activity, Ams will call resolveIntent in PackageManagerService to get which activity to start. For service, it is the resolveService method in PackageManagerService get called. So you need to handle them differently. But since they will all get a list of ResolveInfo in their implementation, you can just filter out your application easily. For example, in resolveIntent in PackageManagerService:

@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
        int flags, int userId) {
    if (!sUserManager.exists(userId)) return null;
    enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
    List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
    //filter out here!!!!
    return chooseBestActivity(intent, resolvedType, flags, query, userId);
}

You can easily get the ApplicationInfo from the ResolveInfo if you take a look at ResolveInfo.java.

For receiver, it is even more complicated because receivers registered in AndroidManifest.xml and by registerReceiver(...) are different. If the intent in broadcastIntent hasn't set the flag FLAG_RECEIVER_REGISTERED_ONLY(common case), then the resolving result would be a list of receivers that listen to that broadcast, which may contain two kinds of receivers. For those in AndroidManifest.xml, Ams will call queryIntentReceiver in PackageManagerService to get a list of receivers that listen to a broadcast. For those registered dynamically by registerReciever(...), they are managed by ActivityManagerService not PackageManagerService, so Ams will directly call mReceiverResolver.queryIntent to get those receivers. The mReceiverResolver is defined as:

final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
        = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
        ...
}

So what you need to do is override the queryIntent method to filter out the receivers in your application. For ContentProvider, the method is resolveContentProvider in PackageManagerService. Same way to handle it.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值