summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSetup Wizard Team <android-setup-team-eng@google.com>2019-11-08 15:22:51 +0800
committerNicole Huang <nicolehuang@google.com>2019-12-16 15:47:53 +0800
commit24bb1e2b3fd9dec35953ae7324586f95dcef0d95 (patch)
tree8b1b58a1eee7f5e6e1c6dd1d44d26ce82539b8df
parent66148a82e392aaacb27502a9d44cde9dd6bab279 (diff)
downloadsetupcompat-24bb1e2b3fd9dec35953ae7324586f95dcef0d95.tar.gz
Import updated Android SetupCompat Library 279249746
Copied from google3/third_party/java_src/android_libs/setupcompat Test: mm Included changes: - 279249746 Trims the metric value less than CustomEvent.MAX_STRING_L... - 258686629 Fix activity test fail. - 258478750 Log onResume time for sort the flow of SUW - 257138376 Fix fail to publish metrics log - 256076624 Refactor the screenName of Metrics - 254929273 Fix PartnerConfigHelper#getResourceEntryFromKey throw NPE - 253952206 Provide the fallback values from setup wizard when the sc... - 252376490 Add partner config for body content text - 251553482 qt-dev is freeze, code will sync to qt-r1-dev PiperOrigin-RevId: 279249746 Change-Id: Id7af2272ded4550bea5246abe75026a68cb51b19
-rw-r--r--main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java4
-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/FooterButton.java4
-rw-r--r--partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java17
-rw-r--r--partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java105
-rw-r--r--partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java20
-rw-r--r--partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java73
10 files changed, 222 insertions, 67 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/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/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/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
index 73d66e6..cd479ee 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java
@@ -139,7 +139,22 @@ public enum PartnerConfig {
PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR, ResourceType.COLOR),
// Font family of the description
- CONFIG_DESCRIPTION_FONT_FAMILY(PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, ResourceType.STRING);
+ CONFIG_DESCRIPTION_FONT_FAMILY(PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, ResourceType.STRING),
+
+ // Text size of the body content text
+ CONFIG_CONTENT_TEXT_SIZE(PartnerConfigKey.KEY_CONTENT_TEXT_SIZE, ResourceType.DIMENSION),
+
+ // Text color of the body content text
+ CONFIG_CONTENT_TEXT_COLOR(PartnerConfigKey.KEY_CONTENT_TEXT_COLOR, ResourceType.COLOR),
+
+ // Link text color of the body content text
+ CONFIG_CONTENT_LINK_TEXT_COLOR(PartnerConfigKey.KEY_CONTENT_LINK_TEXT_COLOR, ResourceType.COLOR),
+
+ // Font family of the body content text
+ CONFIG_CONTENT_FONT_FAMILY(PartnerConfigKey.KEY_CONTENT_FONT_FAMILY, ResourceType.STRING),
+
+ // Gravity of the body content text
+ CONFIG_CONTENT_LAYOUT_GRAVITY(PartnerConfigKey.KEY_CONTENT_LAYOUT_GRAVITY, ResourceType.STRING);
public enum ResourceType {
BOOL,
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
index eac403f..7205bbe 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java
@@ -18,7 +18,6 @@ package com.google.android.setupcompat.partnerconfig;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
@@ -45,6 +44,9 @@ public class PartnerConfigHelper {
public static final String SUW_AUTHORITY = "com.google.android.setupwizard.partner";
@VisibleForTesting public static final String SUW_GET_PARTNER_CONFIG_METHOD = "getOverlayConfig";
+
+ @VisibleForTesting public static final String KEY_FALLBACK_CONFIG = "fallbackConfig";
+
private static PartnerConfigHelper instance = null;
@VisibleForTesting Bundle resultBundle = null;
@@ -92,16 +94,18 @@ public class PartnerConfigHelper {
int result = 0;
try {
- String resourceName = resourceConfig.getResourceName();
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceName);
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
+
if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
- result = resource.getColor(resourceEntry.getResourceId(), null);
+ result = resource.getColor(resId, null);
} else {
- result = resource.getColor(resourceEntry.getResourceId());
+ result = resource.getColor(resId);
}
partnerResourceCache.put(resourceConfig, result);
- } catch (PackageManager.NameNotFoundException | NullPointerException exception) {
+ } catch (NullPointerException exception) {
// fall through
}
return result;
@@ -127,25 +131,25 @@ public class PartnerConfigHelper {
Drawable result = null;
try {
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceConfig.getResourceName());
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
// for @null
TypedValue outValue = new TypedValue();
- resource.getValue(resourceEntry.getResourceId(), outValue, true);
+ resource.getValue(resId, outValue, true);
if (outValue.type == TypedValue.TYPE_REFERENCE && outValue.data == 0) {
return result;
}
if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- result = resource.getDrawable(resourceEntry.getResourceId(), null);
+ result = resource.getDrawable(resId, null);
} else {
- result = resource.getDrawable(resourceEntry.getResourceId());
+ result = resource.getDrawable(resId);
}
partnerResourceCache.put(resourceConfig, result);
- } catch (PackageManager.NameNotFoundException
- | NullPointerException
- | NotFoundException exception) {
+ } catch (NullPointerException | NotFoundException exception) {
// fall through
}
return result;
@@ -171,11 +175,14 @@ public class PartnerConfigHelper {
String result = null;
try {
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceConfig.getResourceName());
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
- result = resource.getString(resourceEntry.getResourceId());
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
+
+ result = resource.getString(resId);
partnerResourceCache.put(resourceConfig, result);
- } catch (PackageManager.NameNotFoundException | NullPointerException exception) {
+ } catch (NullPointerException exception) {
// fall through
}
return result;
@@ -202,11 +209,14 @@ public class PartnerConfigHelper {
boolean result = defaultValue;
try {
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceConfig.getResourceName());
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
- result = resource.getBoolean(resourceEntry.getResourceId());
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
+
+ result = resource.getBoolean(resId);
partnerResourceCache.put(resourceConfig, result);
- } catch (PackageManager.NameNotFoundException | NullPointerException exception) {
+ } catch (NullPointerException exception) {
// fall through
}
return result;
@@ -244,17 +254,18 @@ public class PartnerConfigHelper {
float result = defaultValue;
try {
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceConfig.getResourceName());
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
- result = resource.getDimension(resourceEntry.getResourceId());
- TypedValue value =
- getTypedValueFromResource(
- resource, resourceEntry.getResourceId(), TypedValue.TYPE_DIMENSION);
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
+
+ result = resource.getDimension(resId);
+ TypedValue value = getTypedValueFromResource(resource, resId, TypedValue.TYPE_DIMENSION);
partnerResourceCache.put(resourceConfig, value);
result =
getDimensionFromTypedValue(
context, (TypedValue) partnerResourceCache.get(resourceConfig));
- } catch (PackageManager.NameNotFoundException | NullPointerException exception) {
+ } catch (NullPointerException exception) {
// fall through
}
return result;
@@ -291,11 +302,14 @@ public class PartnerConfigHelper {
float result = defaultValue;
try {
- ResourceEntry resourceEntry = getResourceEntryFromKey(resourceConfig.getResourceName());
- Resources resource = getResourcesByPackageName(context, resourceEntry.getPackageName());
- result = resource.getFraction(resourceEntry.getResourceId(), 1, 1);
+ ResourceEntry resourceEntry =
+ getResourceEntryFromKey(context, resourceConfig.getResourceName());
+ Resources resource = resourceEntry.getResources();
+ int resId = resourceEntry.getResourceId();
+
+ result = resource.getFraction(resId, 1, 1);
partnerResourceCache.put(resourceConfig, result);
- } catch (PackageManager.NameNotFoundException | NullPointerException exception) {
+ } catch (NullPointerException exception) {
// fall through
}
return result;
@@ -322,23 +336,14 @@ public class PartnerConfigHelper {
}
}
- private Resources getResourcesByPackageName(Context context, String packageName)
- throws PackageManager.NameNotFoundException {
- PackageManager manager = context.getPackageManager();
- if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
- return manager.getResourcesForApplication(
- manager.getApplicationInfo(packageName, PackageManager.MATCH_DISABLED_COMPONENTS));
- } else {
- return manager.getResourcesForApplication(
- manager.getApplicationInfo(packageName, PackageManager.GET_DISABLED_COMPONENTS));
- }
- }
-
- private ResourceEntry getResourceEntryFromKey(String resourceName) {
- if (resultBundle == null) {
- return null;
+ @Nullable
+ private ResourceEntry getResourceEntryFromKey(Context context, String resourceName) {
+ Bundle resourceEntryBundle = resultBundle.getBundle(resourceName);
+ Bundle fallbackBundle = resultBundle.getBundle(KEY_FALLBACK_CONFIG);
+ if (fallbackBundle != null) {
+ resourceEntryBundle.putBundle(KEY_FALLBACK_CONFIG, fallbackBundle.getBundle(resourceName));
}
- return ResourceEntry.fromBundle(resultBundle.getBundle(resourceName));
+ return ResourceEntry.fromBundle(context, resourceEntryBundle);
}
@VisibleForTesting
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
index 87f51ba..6701fdd 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java
@@ -57,6 +57,11 @@ import java.lang.annotation.RetentionPolicy;
PartnerConfigKey.KEY_DESCRIPTION_TEXT_COLOR,
PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR,
PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY,
+ PartnerConfigKey.KEY_CONTENT_TEXT_SIZE,
+ PartnerConfigKey.KEY_CONTENT_TEXT_COLOR,
+ PartnerConfigKey.KEY_CONTENT_LINK_TEXT_COLOR,
+ PartnerConfigKey.KEY_CONTENT_FONT_FAMILY,
+ PartnerConfigKey.KEY_CONTENT_LAYOUT_GRAVITY,
})
// TODO: can be removed and always reference PartnerConfig.getResourceName()?
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
@@ -162,4 +167,19 @@ public @interface PartnerConfigKey {
// Font family of the description
String KEY_DESCRIPTION_FONT_FAMILY = "setup_design_description_font_family";
+
+ // Text size of the body content text
+ String KEY_CONTENT_TEXT_SIZE = "setup_design_content_text_size";
+
+ // Text color of the body content text
+ String KEY_CONTENT_TEXT_COLOR = "setup_design_content_text_color";
+
+ // Link text color of the body content text
+ String KEY_CONTENT_LINK_TEXT_COLOR = "setup_design_content_link_text_color";
+
+ // Font family of the body content text
+ String KEY_CONTENT_FONT_FAMILY = "setup_design_content_font_family";
+
+ // Gravity of the body content text
+ String KEY_CONTENT_LAYOUT_GRAVITY = "setup_design_content_layout_gravity";
}
diff --git a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
index 2794f22..8f7c9d8 100644
--- a/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
+++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java
@@ -16,15 +16,29 @@
package com.google.android.setupcompat.partnerconfig;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import android.util.Log;
/**
* A potentially cross-package resource entry, which can then be retrieved using {@link
- * PackageManager#getApplicationForResources}. This class can also be sent across to other packages
+ * PackageManager#getResourcesForApplication}. This class can also be sent across to other packages
* on IPC via the Bundle representation.
*/
public final class ResourceEntry {
+
+ private static final String TAG = ResourceEntry.class.getSimpleName();
+
+ @VisibleForTesting static final String KEY_FALLBACK_CONFIG = "fallbackConfig";
+
@VisibleForTesting static final String KEY_PACKAGE_NAME = "packageName";
@VisibleForTesting static final String KEY_RESOURCE_NAME = "resourceName";
@VisibleForTesting static final String KEY_RESOURCE_ID = "resourceId";
@@ -34,11 +48,22 @@ public final class ResourceEntry {
private final int resourceId;
/**
- * Creates a {@code ResourceEntry} object from a provided bundle.
+ * The {@link Resources} for accessing a specific package's resources. This is {@code null} only
+ * if the deprecated constructor {@link #ResourceEntry(String, String, int)} is used.
+ */
+ @Nullable private final Resources resources;
+
+ /**
+ * Creates a {@code ResourceEntry} object from a provided bundle or the fallback resource if
+ * partner resource not found and the {@code fallbackConfig} key exists in provided bundle.
+ * Returns {@code null} if fallback package is not found or the {@code bundle} doesn't contain
+ * packageName, resourceName, or resourceId.
*
+ * @param context the context need to retrieve the {@link Resources}
* @param bundle the source bundle needs to have all the information for a {@code ResourceEntry}
*/
- public static ResourceEntry fromBundle(Bundle bundle) {
+ @Nullable
+ public static ResourceEntry fromBundle(@NonNull Context context, Bundle bundle) {
String packageName;
String resourceName;
int resourceId;
@@ -50,13 +75,31 @@ public final class ResourceEntry {
packageName = bundle.getString(KEY_PACKAGE_NAME);
resourceName = bundle.getString(KEY_RESOURCE_NAME);
resourceId = bundle.getInt(KEY_RESOURCE_ID);
- return new ResourceEntry(packageName, resourceName, resourceId);
+ try {
+ return new ResourceEntry(
+ packageName, resourceName, resourceId, getResourcesByPackageName(context, packageName));
+ } catch (NameNotFoundException e) {
+ Bundle fallbackBundle = bundle.getBundle(KEY_FALLBACK_CONFIG);
+ if (fallbackBundle != null) {
+ Log.w(TAG, packageName + " not found, " + resourceName + " fallback to default value");
+ return fromBundle(context, fallbackBundle);
+ }
+ }
+ return null;
}
+ /** @deprecated Use {@link #ResourceEntry(String, String, int, Resources)} instead. */
+ @Deprecated
public ResourceEntry(String packageName, String resourceName, int resourceId) {
+ this(packageName, resourceName, resourceId, /* resources= */ null);
+ }
+
+ public ResourceEntry(
+ String packageName, String resourceName, int resourceId, @Nullable Resources resources) {
this.packageName = packageName;
this.resourceName = resourceName;
this.resourceId = resourceId;
+ this.resources = resources;
}
public String getPackageName() {
@@ -72,9 +115,17 @@ public final class ResourceEntry {
}
/**
+ * Returns a {@link Resources} for accessing specific package's resources. It will be {@code null}
+ * when the {@link #ResourceEntry(String, String, int)} is used).
+ */
+ public Resources getResources() {
+ return resources;
+ }
+
+ /**
* Returns a bundle representation of this resource entry, which can then be sent over IPC.
*
- * @see #fromBundle(Bundle)
+ * @see #fromBundle(Context, Bundle)
*/
public Bundle toBundle() {
Bundle result = new Bundle();
@@ -83,4 +134,16 @@ public final class ResourceEntry {
result.putInt(KEY_RESOURCE_ID, resourceId);
return result;
}
+
+ private static Resources getResourcesByPackageName(Context context, String packageName)
+ throws NameNotFoundException {
+ PackageManager manager = context.getPackageManager();
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
+ return manager.getResourcesForApplication(
+ manager.getApplicationInfo(packageName, PackageManager.MATCH_DISABLED_COMPONENTS));
+ } else {
+ return manager.getResourcesForApplication(
+ manager.getApplicationInfo(packageName, PackageManager.GET_DISABLED_COMPONENTS));
+ }
+ }
}