Почему я не могу зарегистрировать приемник вещания, используя инструментальный контекст теста? - PullRequest
0 голосов
/ 30 октября 2019

Почему это не дубликат

Я видел другие вопросы, такие как этот , задайте что-то похожее, но я думаю, что предоставленные ответы неполные.

Проблема

Я пытаюсь сделать следующее:

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. Это, конечно, не очень хорошее решение, но я нашел его интересным. Я не уверен, есть ли здесь какие-либо последствия для безопасности. Может быть, я победил только контроль безопасности, который никогда не должен был существовать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...