Почему это не дубликат
Я видел другие вопросы, такие как этот , задайте что-то похожее, но я думаю, что предоставленные ответы неполные.
Проблема
Я пытаюсь сделать следующее:
IntentFilter filter = new IntentFilter("com.example.foo.intent.action.MY_ACTION");
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// do something
}
};
InstrumentationRegistry.getContext().registerReceiver(receiver, filter);
Но это не с:
java.lang.SecurityException: Given caller package com.example.foo.test is not running in process ProcessRecord{6cffcd6 28355:com.example.foo/u0a118}
Я хочу проверить, работает ли незащищенная неявная трансляцияправильно. Поэтому я не хочу использовать getTargetContext()
(который является принятым ответом на вышеупомянутый вопрос). По сути, я пытаюсь проверить, что приложение, которое является , а не целевым приложением, может получать широковещательную от целевого приложения.
Почему я считаю, что это ошибка
Исключение безопасности выдается в ActivityManagerService.java в строке 20824 , поскольку !callerApp.pkgList.containsKey(callerPackage)
оценивается как true
.
Это, наряду с приведенным выше сообщением об ошибке, означает, чтоIApplicationThread caller
принадлежит приложению target , но String callerPackage
- это имя пакета приложения test .
Разве caller
не должно быть тест само приложение? Если нет, то чего-то мне не хватает? Возможно, существует другой способ регистрации приемника вещания специально для приложения test . Или, может быть, это недостаток способа выполнения инструментального теста? Если тестовое приложение и целевое приложение совместно используют IApplicationThread
, я думаю, что имя тестового пакета должно быть добавлено к callerApp.pkgList
, когда инструментальный тест выполняется. В противном случае они должны иметь свой собственный IApplicationThread
?
TL; DR
Как я могу зарегистрировать приемник вещания с контекстом приложения test , а не с target app?
EDIT
Я создал грязный обходной путь. Мы можем отредактировать имя пакета Context, чтобы оно соответствовало целевому пакету:
Context c = null;
try {
c = InstrumentationRegistry.getContext();
Field f = c.getClass().getDeclaredField("mBasePackageName");
f.setAccessible(true);
f.set(c, "com.example.foo");
} catch (Exception e) {
// ignored
}
Это приводит к успешному выполнению транзакции Binder, так как имя пакета, которое мы дали, теперь находится в белом списке пакетов, которые должны бытьчасть callerApp
. Это, конечно, не очень хорошее решение, но я нашел его интересным. Я не уверен, есть ли здесь какие-либо последствия для безопасности. Может быть, я победил только контроль безопасности, который никогда не должен был существовать?