From 7c473650599e984d2234e2908599db5b53d41290 Mon Sep 17 00:00:00 2001 From: Tianjie Date: Sat, 22 May 2021 22:43:12 -0700 Subject: [PATCH] Add an error code for RoR failure due to no network This gives us detailed information on whether server based RoR fails due to no network after reboot. There might be a race condition when the device gets network (check) after RoR fails in gmscore (use). But the case should be rare, and it's acceptable for metrics purpose. Also mock the methods to read timeouts. This helps avoids denail to read device_config when running test on internal targets. Bug: 179105110 Test: trigger a server based ror, check error code Change-Id: If600e8e06d7707da7160fec66d71bc9341327965 --- .../locksettings/RebootEscrowManager.java | 30 ++++++++++++++++++- .../RebootEscrowManagerTests.java | 19 ++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java index 3f2b8fffcc54d..b714c6d736130 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java @@ -33,6 +33,9 @@ import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; import android.os.Handler; import android.os.SystemClock; import android.os.SystemProperties; @@ -126,6 +129,7 @@ class RebootEscrowManager { ERROR_UNLOCK_ALL_USERS, ERROR_PROVIDER_MISMATCH, ERROR_KEYSTORE_FAILURE, + ERROR_NO_NETWORK, }) @Retention(RetentionPolicy.SOURCE) @interface RebootEscrowErrorCode { @@ -139,6 +143,7 @@ class RebootEscrowManager { static final int ERROR_UNLOCK_ALL_USERS = 5; static final int ERROR_PROVIDER_MISMATCH = 6; static final int ERROR_KEYSTORE_FAILURE = 7; + static final int ERROR_NO_NETWORK = 8; private @RebootEscrowErrorCode int mLoadEscrowDataErrorCode = ERROR_NONE; @@ -235,6 +240,23 @@ class RebootEscrowManager { "server_based_ror_enabled", false); } + public boolean isNetworkConnected() { + final ConnectivityManager connectivityManager = + mContext.getSystemService(ConnectivityManager.class); + if (connectivityManager == null) { + return false; + } + + Network activeNetwork = connectivityManager.getActiveNetwork(); + NetworkCapabilities networkCapabilities = + connectivityManager.getNetworkCapabilities(activeNetwork); + return networkCapabilities != null + && networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_INTERNET) + && networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_VALIDATED); + } + public Context getContext() { return mContext; } @@ -363,7 +385,11 @@ class RebootEscrowManager { } Slog.w(TAG, "Failed to load reboot escrow data after " + attemptNumber + " attempts"); - mLoadEscrowDataErrorCode = ERROR_RETRY_COUNT_EXHAUSTED; + if (mInjector.serverBasedResumeOnReboot() && !mInjector.isNetworkConnected()) { + mLoadEscrowDataErrorCode = ERROR_NO_NETWORK; + } else { + mLoadEscrowDataErrorCode = ERROR_RETRY_COUNT_EXHAUSTED; + } onGetRebootEscrowKeyFailed(users, attemptNumber); } @@ -471,6 +497,8 @@ class RebootEscrowManager { mLoadEscrowDataErrorCode = ERROR_UNKNOWN; } + Slog.i(TAG, "Reporting RoR recovery metrics, success: " + success + ", service type: " + + serviceType + ", error code: " + mLoadEscrowDataErrorCode); // TODO(179105110) report the duration since boot complete. mInjector.reportMetric(success, mLoadEscrowDataErrorCode, serviceType, attemptCount, escrowDurationInSeconds, vbmetaDigestStatus, -1); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java index aecc7942b2660..b01c1c8ead28e 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java @@ -165,7 +165,17 @@ public class RebootEscrowManagerTests { mRebootEscrow = null; mServerBased = true; RebootEscrowProviderServerBasedImpl.Injector injector = - new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection); + new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection) { + @Override + long getServiceTimeoutInSeconds() { + return 30; + } + + @Override + long getServerBlobLifetimeInMillis() { + return 600_000; + } + }; mDefaultRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl( storage, injector); mUserManager = userManager; @@ -188,6 +198,11 @@ public class RebootEscrowManagerTests { return mServerBased; } + @Override + public boolean isNetworkConnected() { + return false; + } + @Override public RebootEscrowProviderInterface createRebootEscrowProviderIfNeeded() { mRebootEscrowProviderInUse = mDefaultRebootEscrowProvider; @@ -602,7 +617,7 @@ public class RebootEscrowManagerTests { // Sleep 5s for the retry to complete Thread.sleep(5 * 1000); assertFalse(metricsSuccessCaptor.getValue()); - assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_RETRY_COUNT_EXHAUSTED), + assertEquals(Integer.valueOf(RebootEscrowManager.ERROR_NO_NETWORK), metricsErrorCodeCaptor.getValue()); }