summaryrefslogtreecommitdiff
path: root/main/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'main/java/com/google')
-rw-r--r--main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java4
-rw-r--r--main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java28
-rw-r--r--main/java/com/google/android/setupcompat/internal/LifecycleFragment.java15
-rw-r--r--main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java2
-rw-r--r--main/java/com/google/android/setupcompat/logging/CustomEvent.java14
-rw-r--r--main/java/com/google/android/setupcompat/logging/MetricKey.java35
-rw-r--r--main/java/com/google/android/setupcompat/template/FooterBarMixin.java55
-rw-r--r--main/java/com/google/android/setupcompat/template/FooterButton.java4
-rw-r--r--main/java/com/google/android/setupcompat/util/ResultCodes.java4
-rw-r--r--main/java/com/google/android/setupcompat/util/SystemBarHelper.java2
-rw-r--r--main/java/com/google/android/setupcompat/util/WizardManagerHelper.java4
11 files changed, 141 insertions, 26 deletions
diff --git a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
index 360a0a0..fac4b39 100644
--- a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
+++ b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java
@@ -212,9 +212,7 @@ public class PartnerCustomizationLayout extends TemplateLayout {
SetupMetricsLogger.logCustomEvent(
getContext(),
- CustomEvent.create(
- MetricKey.get("SetupCompatMetrics", activity.getClass().getSimpleName()),
- persistableBundle));
+ CustomEvent.create(MetricKey.get("SetupCompatMetrics", activity), persistableBundle));
}
}
diff --git a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
index 6a019fd..39b50cf 100644
--- a/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
+++ b/main/java/com/google/android/setupcompat/internal/FooterButtonPartnerConfig.java
@@ -22,6 +22,8 @@ import com.google.android.setupcompat.template.FooterButton;
/** Keep the partner configuration of a footer button. Used when the button is inflated. */
public class FooterButtonPartnerConfig {
private final PartnerConfig buttonBackgroundConfig;
+ private final PartnerConfig buttonDisableAlphaConfig;
+ private final PartnerConfig buttonDisableBackgroundConfig;
private final PartnerConfig buttonIconConfig;
private final PartnerConfig buttonTextColorConfig;
private final PartnerConfig buttonTextSizeConfig;
@@ -33,6 +35,8 @@ public class FooterButtonPartnerConfig {
private FooterButtonPartnerConfig(
int partnerTheme,
PartnerConfig buttonBackgroundConfig,
+ PartnerConfig buttonDisableAlphaConfig,
+ PartnerConfig buttonDisableBackgroundConfig,
PartnerConfig buttonIconConfig,
PartnerConfig buttonTextColorConfig,
PartnerConfig buttonTextSizeConfig,
@@ -45,6 +49,8 @@ public class FooterButtonPartnerConfig {
this.buttonTextSizeConfig = buttonTextSizeConfig;
this.buttonTextTypeFaceConfig = buttonTextTypeFaceConfig;
this.buttonBackgroundConfig = buttonBackgroundConfig;
+ this.buttonDisableAlphaConfig = buttonDisableAlphaConfig;
+ this.buttonDisableBackgroundConfig = buttonDisableBackgroundConfig;
this.buttonRadiusConfig = buttonRadiusConfig;
this.buttonIconConfig = buttonIconConfig;
this.buttonRippleColorAlphaConfig = buttonRippleColorAlphaConfig;
@@ -58,6 +64,14 @@ public class FooterButtonPartnerConfig {
return buttonBackgroundConfig;
}
+ public PartnerConfig getButtonDisableAlphaConfig() {
+ return buttonDisableAlphaConfig;
+ }
+
+ public PartnerConfig getButtonDisableBackgroundConfig() {
+ return buttonDisableBackgroundConfig;
+ }
+
public PartnerConfig getButtonIconConfig() {
return buttonIconConfig;
}
@@ -86,6 +100,8 @@ public class FooterButtonPartnerConfig {
public static class Builder {
private final FooterButton footerButton;
private PartnerConfig buttonBackgroundConfig = null;
+ private PartnerConfig buttonDisableAlphaConfig = null;
+ private PartnerConfig buttonDisableBackgroundConfig = null;
private PartnerConfig buttonIconConfig = null;
private PartnerConfig buttonTextColorConfig = null;
private PartnerConfig buttonTextSizeConfig = null;
@@ -105,6 +121,16 @@ public class FooterButtonPartnerConfig {
return this;
}
+ public Builder setButtonDisableAlphaConfig(PartnerConfig buttonDisableAlphaConfig) {
+ this.buttonDisableAlphaConfig = buttonDisableAlphaConfig;
+ return this;
+ }
+
+ public Builder setButtonDisableBackgroundConfig(PartnerConfig buttonDisableBackgroundConfig) {
+ this.buttonDisableBackgroundConfig = buttonDisableBackgroundConfig;
+ return this;
+ }
+
public Builder setButtonIconConfig(PartnerConfig buttonIconConfig) {
this.buttonIconConfig = buttonIconConfig;
return this;
@@ -144,6 +170,8 @@ public class FooterButtonPartnerConfig {
return new FooterButtonPartnerConfig(
partnerTheme,
buttonBackgroundConfig,
+ buttonDisableAlphaConfig,
+ buttonDisableBackgroundConfig,
buttonIconConfig,
buttonTextColorConfig,
buttonTextSizeConfig,
diff --git a/main/java/com/google/android/setupcompat/internal/LifecycleFragment.java b/main/java/com/google/android/setupcompat/internal/LifecycleFragment.java
index 269dd6d..d882c9d 100644
--- a/main/java/com/google/android/setupcompat/internal/LifecycleFragment.java
+++ b/main/java/com/google/android/setupcompat/internal/LifecycleFragment.java
@@ -24,7 +24,9 @@ import android.app.FragmentManager;
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
+import android.os.PersistableBundle;
import android.util.Log;
+import com.google.android.setupcompat.logging.CustomEvent;
import com.google.android.setupcompat.logging.MetricKey;
import com.google.android.setupcompat.logging.SetupMetricsLogger;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -87,7 +89,7 @@ public class LifecycleFragment extends Fragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
- metricKey = MetricKey.get("ScreenDuration", getActivity().getClass().getSimpleName());
+ metricKey = MetricKey.get("ScreenDuration", getActivity());
}
@Override
@@ -100,6 +102,7 @@ public class LifecycleFragment extends Fragment {
public void onResume() {
super.onResume();
startInNanos = ClockProvider.timeInNanos();
+ logScreenResume();
}
@Override
@@ -107,4 +110,14 @@ public class LifecycleFragment extends Fragment {
super.onPause();
durationInNanos += (ClockProvider.timeInNanos() - startInNanos);
}
+
+ private void logScreenResume() {
+ if (VERSION.SDK_INT >= VERSION_CODES.Q) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putLong("onScreenResume", System.nanoTime());
+ SetupMetricsLogger.logCustomEvent(
+ getActivity(),
+ CustomEvent.create(MetricKey.get("ScreenActivity", getActivity()), bundle));
+ }
+ }
}
diff --git a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
index 66503a7..2043a81 100644
--- a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
+++ b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java
@@ -169,7 +169,7 @@ public class SetupCompatServiceProvider {
return serviceContext.state;
}
- private ServiceContext getCurrentServiceState() {
+ private synchronized ServiceContext getCurrentServiceState() {
return serviceContext;
}
diff --git a/main/java/com/google/android/setupcompat/logging/CustomEvent.java b/main/java/com/google/android/setupcompat/logging/CustomEvent.java
index 88ac05e..38c32fa 100644
--- a/main/java/com/google/android/setupcompat/logging/CustomEvent.java
+++ b/main/java/com/google/android/setupcompat/logging/CustomEvent.java
@@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.google.android.setupcompat.internal.ClockProvider;
import com.google.android.setupcompat.internal.PersistableBundles;
@@ -201,6 +202,19 @@ public final class CustomEvent implements Parcelable {
}
}
+ /**
+ * Trims the string longer than {@code MAX_STR_LENGTH} character, only keep the first {@code
+ * MAX_STR_LENGTH} - 1 characters and attached … in the end.
+ */
+ @NonNull
+ public static String trimsStringOverMaxLength(@NonNull String str) {
+ if (str.length() <= MAX_STR_LENGTH) {
+ return str;
+ } else {
+ return String.format("%s…", str.substring(0, MAX_STR_LENGTH - 1));
+ }
+ }
+
@VisibleForTesting static final int MAX_STR_LENGTH = 50;
@VisibleForTesting static final int MIN_BUNDLE_KEY_LENGTH = 3;
}
diff --git a/main/java/com/google/android/setupcompat/logging/MetricKey.java b/main/java/com/google/android/setupcompat/logging/MetricKey.java
index 125dee9..cdfb7d7 100644
--- a/main/java/com/google/android/setupcompat/logging/MetricKey.java
+++ b/main/java/com/google/android/setupcompat/logging/MetricKey.java
@@ -18,6 +18,7 @@ package com.google.android.setupcompat.logging;
import static com.google.android.setupcompat.internal.Validations.assertLengthInRange;
+import android.app.Activity;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,6 +41,21 @@ public final class MetricKey implements Parcelable {
/**
* Creates a new instance of MetricKey.
*
+ * @param name metric name to identify what we log
+ * @param activity activity of metric screen, uses to generate screenName
+ */
+ public static MetricKey get(@NonNull String name, @NonNull Activity activity) {
+ String screenName = activity.getComponentName().getClassName();
+ assertLengthInRange(name, "MetricKey.name", MIN_METRIC_KEY_LENGTH, MAX_METRIC_KEY_LENGTH);
+ Preconditions.checkArgument(
+ METRIC_KEY_PATTERN.matcher(name).matches(),
+ "Invalid MetricKey, only alpha numeric characters are allowed.");
+ return new MetricKey(name, screenName);
+ }
+
+ /**
+ * Creates a new instance of MetricKey.
+ *
* <p>NOTE:
*
* <ul>
@@ -50,15 +66,21 @@ public final class MetricKey implements Parcelable {
* </ul>
*/
public static MetricKey get(@NonNull String name, @NonNull String screenName) {
+ // We only checked the length of customized screen name, by the reason if the screenName match
+ // to the class name skip check it
+ if (!SCREEN_COMPONENTNAME_PATTERN.matcher(screenName).matches()) {
+ assertLengthInRange(
+ screenName, "MetricKey.screenName", MIN_SCREEN_NAME_LENGTH, MAX_SCREEN_NAME_LENGTH);
+ Preconditions.checkArgument(
+ SCREEN_NAME_PATTERN.matcher(screenName).matches(),
+ "Invalid ScreenName, only alpha numeric characters are allowed.");
+ }
+
assertLengthInRange(name, "MetricKey.name", MIN_METRIC_KEY_LENGTH, MAX_METRIC_KEY_LENGTH);
- assertLengthInRange(
- screenName, "MetricKey.screenName", MIN_SCREEN_NAME_LENGTH, MAX_SCREEN_NAME_LENGTH);
Preconditions.checkArgument(
METRIC_KEY_PATTERN.matcher(name).matches(),
"Invalid MetricKey, only alpha numeric characters are allowed.");
- Preconditions.checkArgument(
- METRIC_KEY_PATTERN.matcher(screenName).matches(),
- "Invalid MetricKey, only alpha numeric characters are allowed.");
+
return new MetricKey(name, screenName);
}
@@ -145,4 +167,7 @@ public final class MetricKey implements Parcelable {
private static final int MAX_SCREEN_NAME_LENGTH = 50;
private static final int MAX_METRIC_KEY_LENGTH = 30;
private static final Pattern METRIC_KEY_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]+");
+ private static final Pattern SCREEN_COMPONENTNAME_PATTERN =
+ Pattern.compile("^([a-z]+[.])+[A-Z][a-zA-Z0-9]+");
+ private static final Pattern SCREEN_NAME_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]+");
}
diff --git a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
index 3c88791..bc9e5c1 100644
--- a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
+++ b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java
@@ -303,6 +303,8 @@ public class FooterBarMixin implements Mixin {
/* buttonBackgroundColorConfig= */ PartnerConfig
.CONFIG_FOOTER_PRIMARY_BUTTON_BG_COLOR))
.setButtonBackgroundConfig(PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_BG_COLOR)
+ .setButtonDisableAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_DISABLED_ALPHA)
+ .setButtonDisableBackgroundConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_DISABLED_BG_COLOR)
.setButtonIconConfig(getDrawablePartnerConfig(footerButton.getButtonType()))
.setButtonRadiusConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RADIUS)
.setButtonRippleColorAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA)
@@ -357,6 +359,8 @@ public class FooterBarMixin implements Mixin {
/* buttonBackgroundColorConfig= */ PartnerConfig
.CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR))
.setButtonBackgroundConfig(PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR)
+ .setButtonDisableAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_DISABLED_ALPHA)
+ .setButtonDisableBackgroundConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_DISABLED_BG_COLOR)
.setButtonIconConfig(getDrawablePartnerConfig(footerButton.getButtonType()))
.setButtonRadiusConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RADIUS)
.setButtonRippleColorAlphaConfig(PartnerConfig.CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA)
@@ -428,14 +432,16 @@ public class FooterBarMixin implements Mixin {
// TODO: Make sure customize attributes in theme can be applied during setup flow.
// If sets background color to full transparent, the button changes to colored borderless ink
// button style.
- int color = PartnerConfigHelper.get(context).getColor(context, buttonBackgroundColorConfig);
- if (applyPartnerResources && color == Color.TRANSPARENT) {
- overrideTheme = R.style.SucPartnerCustomizationButton_Secondary;
- } else if (applyPartnerResources && (color != Color.TRANSPARENT)) {
- // TODO: remove the constrain (color != Color.WHITE), need to check all pages go
- // well without customization. It should be fine since the default value of secondary bg color
- // is set as transparent.
- overrideTheme = R.style.SucPartnerCustomizationButton_Primary;
+ if (applyPartnerResources) {
+ int color = PartnerConfigHelper.get(context).getColor(context, buttonBackgroundColorConfig);
+ if (color == Color.TRANSPARENT) {
+ overrideTheme = R.style.SucPartnerCustomizationButton_Secondary;
+ } else if (color != Color.TRANSPARENT) {
+ // TODO: remove the constrain (color != Color.WHITE), need to check all pages
+ // go well without customization. It should be fine since the default value of secondary bg
+ // color is set as transparent.
+ overrideTheme = R.style.SucPartnerCustomizationButton_Primary;
+ }
}
return overrideTheme;
}
@@ -545,7 +551,10 @@ public class FooterBarMixin implements Mixin {
updateButtonTypeFaceWithPartnerConfig(
button, footerButtonPartnerConfig.getButtonTextTypeFaceConfig());
updateButtonBackgroundWithPartnerConfig(
- button, footerButtonPartnerConfig.getButtonBackgroundConfig());
+ button,
+ footerButtonPartnerConfig.getButtonBackgroundConfig(),
+ footerButtonPartnerConfig.getButtonDisableAlphaConfig(),
+ footerButtonPartnerConfig.getButtonDisableBackgroundConfig());
updateButtonRadiusWithPartnerConfig(button, footerButtonPartnerConfig.getButtonRadiusConfig());
updateButtonIconWithPartnerConfig(button, footerButtonPartnerConfig.getButtonIconConfig());
updateButtonRippleColorWithPartnerConfig(button, footerButtonPartnerConfig);
@@ -586,25 +595,43 @@ public class FooterBarMixin implements Mixin {
@TargetApi(VERSION_CODES.Q)
private void updateButtonBackgroundWithPartnerConfig(
- Button button, PartnerConfig buttonBackgroundConfig) {
+ Button button,
+ PartnerConfig buttonBackgroundConfig,
+ PartnerConfig buttonDisableAlphaConfig,
+ PartnerConfig buttonDisableBackgroundConfig) {
Preconditions.checkArgument(
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q,
"Update button background only support on sdk Q or higher");
@ColorInt int color;
+ @ColorInt int disabledColor;
+ float disabledAlpha;
int[] DISABLED_STATE_SET = {-android.R.attr.state_enabled};
int[] ENABLED_STATE_SET = {};
color = PartnerConfigHelper.get(context).getColor(context, buttonBackgroundConfig);
+ disabledAlpha =
+ PartnerConfigHelper.get(context).getFraction(context, buttonDisableAlphaConfig, 0f);
+ disabledColor =
+ PartnerConfigHelper.get(context).getColor(context, buttonDisableBackgroundConfig);
if (color != Color.TRANSPARENT) {
- TypedArray a = context.obtainStyledAttributes(new int[] {android.R.attr.disabledAlpha});
- float alpha = a.getFloat(0, DEFAULT_DISABLED_ALPHA);
- a.recycle();
+ if (disabledAlpha <= 0f) {
+ // if no partner resource, fallback to theme disable alpha
+ float alpha;
+ TypedArray a = context.obtainStyledAttributes(new int[] {android.R.attr.disabledAlpha});
+ alpha = a.getFloat(0, DEFAULT_DISABLED_ALPHA);
+ a.recycle();
+ disabledAlpha = alpha;
+ }
+ if (disabledColor == Color.TRANSPARENT) {
+ // if no partner resource, fallback to button background color
+ disabledColor = color;
+ }
// Set text color for ripple.
ColorStateList colorStateList =
new ColorStateList(
new int[][] {DISABLED_STATE_SET, ENABLED_STATE_SET},
- new int[] {convertRgbToArgb(color, alpha), color});
+ new int[] {convertRgbToArgb(disabledColor, disabledAlpha), color});
// b/129482013: When a LayerDrawable is mutated, a new clone of its children drawables are
// created, but without copying the state from the parent drawable. So even though the
diff --git a/main/java/com/google/android/setupcompat/template/FooterButton.java b/main/java/com/google/android/setupcompat/template/FooterButton.java
index a4d2c87..2fa8c7c 100644
--- a/main/java/com/google/android/setupcompat/template/FooterButton.java
+++ b/main/java/com/google/android/setupcompat/template/FooterButton.java
@@ -32,6 +32,7 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import com.google.android.setupcompat.R;
+import com.google.android.setupcompat.logging.CustomEvent;
import java.lang.annotation.Retention;
/**
@@ -285,7 +286,8 @@ public final class FooterButton implements OnClickListener {
@TargetApi(VERSION_CODES.Q)
public PersistableBundle getMetrics(String buttonName) {
PersistableBundle bundle = new PersistableBundle();
- bundle.putString(buttonName + KEY_BUTTON_TEXT, getText().toString());
+ bundle.putString(
+ buttonName + KEY_BUTTON_TEXT, CustomEvent.trimsStringOverMaxLength(getText().toString()));
bundle.putString(buttonName + KEY_BUTTON_TYPE, getButtonTypeName());
bundle.putInt(buttonName + KEY_BUTTON_ON_CLICK_COUNT, clickCount);
return bundle;
diff --git a/main/java/com/google/android/setupcompat/util/ResultCodes.java b/main/java/com/google/android/setupcompat/util/ResultCodes.java
index 3934b21..5fed731 100644
--- a/main/java/com/google/android/setupcompat/util/ResultCodes.java
+++ b/main/java/com/google/android/setupcompat/util/ResultCodes.java
@@ -24,6 +24,10 @@ public final class ResultCodes {
public static final int RESULT_SKIP = RESULT_FIRST_USER;
public static final int RESULT_RETRY = RESULT_FIRST_USER + 1;
public static final int RESULT_ACTIVITY_NOT_FOUND = RESULT_FIRST_USER + 2;
+ public static final int RESULT_LIFECYCLE_NOT_MATCHED = RESULT_FIRST_USER + 3;
+ public static final int RESULT_FLOW_NOT_MATCHED = RESULT_FIRST_USER + 4;
public static final int RESULT_FIRST_SETUP_USER = RESULT_FIRST_USER + 100;
+
+ private ResultCodes() {}
}
diff --git a/main/java/com/google/android/setupcompat/util/SystemBarHelper.java b/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
index f336617..75e5dd3 100644
--- a/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
+++ b/main/java/com/google/android/setupcompat/util/SystemBarHelper.java
@@ -347,4 +347,6 @@ public final class SystemBarHelper {
void onDecorViewInstalled(View decorView);
}
+
+ private SystemBarHelper() {}
}
diff --git a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
index 36b7d38..bfe1dbb 100644
--- a/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
+++ b/main/java/com/google/android/setupcompat/util/WizardManagerHelper.java
@@ -32,7 +32,7 @@ import java.util.Arrays;
* shown inside the setup flow. This includes things like parsing extras passed by Wizard Manager,
* and invoking Wizard Manager to start the next action.
*/
-public class WizardManagerHelper {
+public final class WizardManagerHelper {
private static final String ACTION_NEXT = "com.android.wizard.NEXT";
@@ -216,4 +216,6 @@ public class WizardManagerHelper {
|| isDeferredSetupWizard(originalIntent);
}
}
+
+ private WizardManagerHelper() {}
}