Merge "Import updated Android SetupCompat Library 515497412" into udc-dev
diff --git a/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsReceiver.java b/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsReceiver.java
deleted file mode 100644
index 9e15e30..0000000
--- a/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsReceiver.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.setupcompat.bts;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import androidx.annotation.NonNull;
-import com.google.android.setupcompat.internal.Preconditions;
-import com.google.android.setupcompat.util.Logger;
-import java.util.concurrent.Executor;
-
-/** Class to receive broadcast intent from SUW, and execute the client's task in the executor. */
-public abstract class AbstractSetupBtsReceiver extends BroadcastReceiver {
- private static final Logger LOG = new Logger(AbstractSetupBtsReceiver.class);
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent != null && getIntentAction().equals(intent.getAction())) {
- Executor executor = getExecutor();
- String simpleClassName = this.getClass().getSimpleName();
- if (executor != null) {
- executor.execute(
- () -> {
- Preconditions.ensureNotOnMainThread(simpleClassName + "::onStartTask");
- onStartTask();
- });
- }
- } else {
- LOG.w(
- "["
- + this.getClass().getSimpleName()
- + "] Unauthorized binder uid="
- + Binder.getCallingUid()
- + ", intentAction="
- + (intent == null ? "(null)" : intent.getAction()));
- }
- }
-
- /**
- * Gets the intent action that expected to execute the task. Use to avoid the receiver launch
- * unexpectedly.
- */
- @NonNull
- protected abstract String getIntentAction();
-
- /** Returns the executor used to execute the task. */
- @NonNull
- protected abstract Executor getExecutor();
-
- /** Tasks can be done before activity launched, in order to remove the loading before activity. */
- protected abstract void onStartTask();
-}
diff --git a/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsService.java b/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsService.java
index eb10693..80066ab 100644
--- a/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsService.java
+++ b/bts/java/com/google/android/setupcompat/bts/AbstractSetupBtsService.java
@@ -256,7 +256,7 @@
for (Signature signature : info.signingInfo.getApkContentsSigners()) {
if (SETUP_WIZARD_RELEASE_CERTIFICATE_STRING.equals(signature.toCharsString())
- || (allowDebugKeys
+ || (isAllowDebugKeysOrBuild()
&& SETUP_WIZARD_DEBUG_CERTIFICATE_STRING.equals(signature.toCharsString()))) {
return true;
}
@@ -273,6 +273,10 @@
return false;
}
+ private boolean isAllowDebugKeysOrBuild() {
+ return Build.TYPE.equals("userdebug") || Build.TYPE.equals("eng") || allowDebugKeys;
+ }
+
@VisibleForTesting
boolean verifyCallingAppPermission() {
int checkPermission =
diff --git a/main/java/com/google/android/setupcompat/logging/SetupMetricsLogger.java b/main/java/com/google/android/setupcompat/logging/SetupMetricsLogger.java
index 786494e..fab38a2 100644
--- a/main/java/com/google/android/setupcompat/logging/SetupMetricsLogger.java
+++ b/main/java/com/google/android/setupcompat/logging/SetupMetricsLogger.java
@@ -16,8 +16,10 @@
package com.google.android.setupcompat.logging;
+import android.annotation.SuppressLint;
import android.content.Context;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import com.google.android.setupcompat.internal.Preconditions;
import com.google.android.setupcompat.internal.SetupCompatServiceInvoker;
import com.google.android.setupcompat.logging.internal.MetricBundleConverter;
@@ -25,7 +27,10 @@
import com.google.android.setupcompat.util.Logger;
import java.util.concurrent.TimeUnit;
-/** SetupMetricsLogger provides an easy way to log custom metrics to SetupWizard. */
+/**
+ * SetupMetricsLogger provides an easy way to log custom metrics to SetupWizard.
+ * (go/suw-metrics-collection-api)
+ */
public class SetupMetricsLogger {
private static final Logger LOG = new Logger("SetupMetricsLogger");
@@ -76,7 +81,7 @@
}
/**
- * Logs setup collection metrics (go/suw-metrics-collection-api)
+ * Logs setup collection metrics
*/
public static void logMetrics(
@NonNull Context context, @NonNull ScreenKey screenKey, @NonNull SetupMetric... metrics) {
@@ -92,4 +97,46 @@
MetricBundleConverter.createBundleForLoggingSetupMetric(screenKey, metric));
}
}
+
+ /**
+ * A non-static method to log setup collection metrics calling
+ * {@link #logMetrics(Context, ScreenKey, SetupMetric...)} as the actual implementation. This
+ * function is useful when performing unit tests in caller's implementation.
+ * <p>
+ * For unit testing, caller uses {@link #setInstanceForTesting(SetupMetricsLogger)} to inject the
+ * mocked SetupMetricsLogger instance and use {@link SetupMetricsLogger#get(Context)} to get the
+ * SetupMetricsLogger. And verify the this function is called with expected parameters.
+ *
+ * @see #logMetrics(Context, ScreenKey, SetupMetric...)
+ */
+ public void logMetrics(@NonNull ScreenKey screenKey, @NonNull SetupMetric... metrics) {
+ SetupMetricsLogger.logMetrics(context, screenKey, metrics);
+ }
+
+ private SetupMetricsLogger(Context context) {
+ this.context = context;
+ }
+
+ private final Context context;
+
+ /** Use this function to get a singleton of {@link SetupMetricsLogger} */
+ public static synchronized SetupMetricsLogger get(Context context) {
+ if (instance == null) {
+ instance = new SetupMetricsLogger(context.getApplicationContext());
+ }
+
+ return instance;
+ }
+
+ @VisibleForTesting
+ public static void setInstanceForTesting(SetupMetricsLogger testInstance) {
+ instance = testInstance;
+ }
+
+ // The instance is coming from Application context which alive during the application activate and
+ // it's not depend on the activities life cycle, so we can avoid memory leak. However linter
+ // cannot distinguish Application context or activity context, so we add @SuppressLint to avoid
+ // lint error.
+ @SuppressLint("StaticFieldLeak")
+ private static SetupMetricsLogger instance;
}