Тайм-аут Android SafetyNetClient.attest()

Как вы знаете, SafetyNetClient.attest() работает асинхронно.
Но в нашем приложении мы хотим получать SafetyNetApi.AttestationResponse синхронно. Потому что результат SafetyNet требуется в качестве входных данных для другого варианта использования.
Чтобы достичь этого, мы внедрили Wrapper вокруг SafetyNetClient.attest(), который выглядит примерно так.

public Result getAttestationResult(Input input) {
    
    // NOTE: ResultWaiter is our own component to get the result of a async operation in a synchronous manner.
    ResultWaiter<Result> waiter = ResultWaiter.<Result>builder(executor)
      .timeout(10) // timeout set to 10 seconds
      .build();

    Task<SafetyNetApi.AttestationResponse> task = SafetyNet.getClient(context).attest(input.nonce(), input.apiKey());

    // notify ResultWaiter if SafetyNetClient returns a result
    task.addOnSuccessListener(attestationResponse -> waiter.setResult(Result.builder()
      .jwsResult(attestationResponse.getJwsResult())
      .build()));

    // notify ResultWaiter if SafetyNetClient returns an exception
    task.addOnFailureListener(exception -> waiter.setResult(Result.builder()
      .error(exception)
      .build()));

    try {
      // NOTE: waiter.waitForResult() blocks the current thread where getAttestationResult() was called 
      // (of course this can not be the Main/UI Thread!)
      // the blocking is released if
      //    1. waiter.setResult() is called
      //    2. if configured timeout runs out, this method throws a TimeoutException
      return waiter.waitForResult();
    } catch (TimeoutException exception) {
      return Result.builder()
        .error(exception)
        .build();
    }
  }

Проблема, с которой мы сталкиваемся в настоящее время, заключается в том, что у нас есть множество конечных пользователей, которые попадают в блок catch (TimeoutException e) этого примера кода.
Это означает, что SafetyNet не предоставил результат или ошибку в настроенное время ожидания 10 секунд.

При каких обстоятельствах SafetyNet может не вернуть результат в течение 10 секунд?
За исключением, может быть, очевидной причины плохой связи. Должны быть другие причины, так как у нас очень много конечных пользователей с этой проблемой.

Мы не хотим просто увеличивать время ожидания примерно до 30 или 40 секунд, потому что это повлияет на взаимодействие с пользователем в этом конкретном потоке приложения, где требуется аттестация SafetyNet.

Является ли логика вашего приложения, которая реализует SafetyNetClient.attest(), просто ждет, пока Task либо вернет результат, либо исключение на неопределенный срок?
И вы полагаетесь на тот факт, что Task должно заканчиваться либо на OnSuccessListener, либо на onFailureListener?

Есть ли у вас опыт того, как долго обычно работает SafetyNetClient.attest(), пока не завершится в одном из этих прослушивателей?

Мы уже можем исключить какую-либо ошибку в компоненте ResusltWaiter, потому что он используется в нескольких других частях нашего приложения и там работает без нареканий.

Спасибо за вашу помощь и обратную связь заранее!


person iBinVuiDabei    schedule 15.09.2020    source источник


Ответы (1)


Я 3 дня бился с этой проблемой и сначала подумал, что у меня какие-то проблемы с настройкой SafetyNet. Однако я, наконец, обнаружил, что это происходит только с физическим устройством Android, и помог перезапуск маршрутизатора/модема (к которому подключается устройство).

Этот ответ помог мне: https://stackoverflow.com/a/51122769/10179386

person Mark Nguyen    schedule 27.06.2021