diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2019-03-14 10:00:10 +0800 |
---|---|---|
committer | pastychang <pastychang@google.com> | 2019-03-15 10:37:13 +0800 |
commit | 1ed3073417396ad4d3bec9d6a5722b490a49e47e (patch) | |
tree | 6be9a1c1b6f1d6bbba588ccc23cbd069bad56622 | |
parent | b5345f3d3b611fcf3513c613d1663f424414a12f (diff) | |
download | setupcompat-1ed3073417396ad4d3bec9d6a5722b490a49e47e.tar.gz |
Import updated Android SetupCompat Library 238357591
Test: mm
PiperOrigin-RevId: 238357591
Change-Id: Ifa32c7db8d5383f076582aeb7b44f42499a1217a
21 files changed, 476 insertions, 335 deletions
@@ -10,6 +10,7 @@ android_library { ], srcs: [ "main/java/**/*.java", + "partnerconfig/java/**/*.java", "main/aidl/**/*.aidl", ], static_libs: [ diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c8081c1..a9187f2 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -15,5 +15,7 @@ limitations under the License. --> -<manifest package="com.google.android.setupcompat"/> - +<manifest package="com.google.android.setupcompat"> + <!-- Set in the BUILD or gradle file --> + <uses-sdk /> +</manifest> diff --git a/build.gradle b/build.gradle index 508f3c5..2edaee3 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ android { sourceSets.main { manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['main/java'] + java.srcDirs = ['main/java', 'partnerconfig/java'] aidl.srcDirs = ['main/aidl'] res.srcDirs = ['main/res'] } diff --git a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java index cef0aee..faeda2c 100644 --- a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java +++ b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java @@ -21,9 +21,10 @@ import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.content.res.TypedArray; -import android.os.Build; +import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.PersistableBundle; +import androidx.annotation.ColorInt; import androidx.annotation.LayoutRes; import android.util.AttributeSet; import android.util.Log; @@ -38,6 +39,8 @@ import com.google.android.setupcompat.lifecycle.LifecycleFragment; 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.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.template.StatusBarMixin; @@ -49,7 +52,9 @@ public class PartnerCustomizationLayout extends TemplateLayout { // Log tags can have at most 23 characters on N or before. private static final String TAG = "PartnerCustomizedLayout"; - private final boolean suwVersionSupportPartnerResource = Build.VERSION.SDK_INT > VERSION_CODES.P; + private final boolean suwVersionSupportPartnerResource = isAtLeastQ(); + + private boolean applyPartnerResource; private Activity activity; public PartnerCustomizationLayout(Context context) { @@ -93,7 +98,7 @@ public class PartnerCustomizationLayout extends TemplateLayout { a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucUsePartnerResource, true); a.recycle(); - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && layoutFullscreen) { + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && layoutFullscreen) { setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } @@ -109,13 +114,10 @@ public class PartnerCustomizationLayout extends TemplateLayout { + usePartnerResource); if (suwVersionSupportPartnerResource && isSetupFlow && !applyPartnerResource()) { - Log.w( - TAG, - "This is inavlid usage that applyPartnerResource() should returns true" - + " during setup wizard flow"); + Log.w(TAG, "applyPartnerResource() should return true during setup wizard flow"); } - boolean applyPartnerResource = + applyPartnerResource = suwVersionSupportPartnerResource && applyPartnerResource() && (isSetupFlow || usePartnerResource); @@ -124,17 +126,22 @@ public class PartnerCustomizationLayout extends TemplateLayout { new StatusBarMixin(this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResource)); registerMixin( SystemNavBarMixin.class, - new SystemNavBarMixin( - this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResource)); + new SystemNavBarMixin(this, activity.getWindow(), applyPartnerResource)); registerMixin( FooterBarMixin.class, new FooterBarMixin(this, attrs, defStyleAttr, applyPartnerResource)); + getMixin(SystemNavBarMixin.class).applyPartnerCustomizations(attrs, defStyleAttr); + // Override the FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, FLAG_TRANSLUCENT_STATUS, // FLAG_TRANSLUCENT_NAVIGATION and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN attributes of window forces // showing status bar and navigation bar. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); + + if (applyPartnerResource) { + updateContentBackgroundColorWithPartnerConfig(); + } } @Override @@ -200,6 +207,14 @@ public class PartnerCustomizationLayout extends TemplateLayout { } } + // TODO(b/127925696): remove the code for pre-release version of Android Q + private static boolean isAtLeastQ() { + return (VERSION.SDK_INT > VERSION_CODES.P) + || (VERSION.CODENAME.length() == 1 + && VERSION.CODENAME.charAt(0) >= 'Q' + && VERSION.CODENAME.charAt(0) <= 'Z'); + } + /** * This method determines applying the partner resource regardless inside setup wizard flow or * not. It always returns true indicating applying partner resource inside setup wizard flow and @@ -222,4 +237,18 @@ public class PartnerCustomizationLayout extends TemplateLayout { footerStub.setLayoutResource(footer); return footerStub.inflate(); } + + /** Returns if the current layout/activity applies partner customized configurations or not. */ + protected boolean shouldApplyPartnerResource() { + return applyPartnerResource; + } + + /** Updates the background color of this layout with the partner-customizable background color. */ + private void updateContentBackgroundColorWithPartnerConfig() { + @ColorInt + int color = + PartnerConfigHelper.get(getContext()) + .getColor(getContext(), PartnerConfig.CONFIG_LAYOUT_BACKGROUND_COLOR); + this.getRootView().setBackgroundColor(color); + } } diff --git a/main/java/com/google/android/setupcompat/lifecycle/LifecycleFragment.java b/main/java/com/google/android/setupcompat/lifecycle/LifecycleFragment.java index a617fd7..71aa898 100644 --- a/main/java/com/google/android/setupcompat/lifecycle/LifecycleFragment.java +++ b/main/java/com/google/android/setupcompat/lifecycle/LifecycleFragment.java @@ -16,6 +16,8 @@ package com.google.android.setupcompat.lifecycle; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; @@ -94,7 +96,7 @@ public class LifecycleFragment extends Fragment { @Override public void onDetach() { super.onDetach(); - SetupMetricsLogger.logDuration(getContext(), metricKey, durationInNanos); + SetupMetricsLogger.logDuration(getContext(), metricKey, NANOSECONDS.toMillis(durationInNanos)); } @Override diff --git a/main/java/com/google/android/setupcompat/logging/internal/FooterBarMixinMetrics.java b/main/java/com/google/android/setupcompat/logging/internal/FooterBarMixinMetrics.java index 8886f51..007aff9 100644 --- a/main/java/com/google/android/setupcompat/logging/internal/FooterBarMixinMetrics.java +++ b/main/java/com/google/android/setupcompat/logging/internal/FooterBarMixinMetrics.java @@ -18,6 +18,8 @@ package com.google.android.setupcompat.logging.internal; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.annotation.TargetApi; +import android.os.Build.VERSION_CODES; import android.os.PersistableBundle; import androidx.annotation.StringDef; import androidx.annotation.VisibleForTesting; @@ -44,9 +46,9 @@ public class FooterBarMixinMetrics { @VisibleForTesting public @interface FooterButtonVisibility { String UNKNOWN = "Unknown"; - String VISIBLE_USING_XML = "VisibileUsingXml"; + String VISIBLE_USING_XML = "VisibleUsingXml"; String VISIBLE = "Visible"; - String VISIBLE_USING_XML_TO_INVISIBLE = "VisibileUsingXml_to_Invisible"; + String VISIBLE_USING_XML_TO_INVISIBLE = "VisibleUsingXml_to_Invisible"; String VISIBLE_TO_INVISIBLE = "Visible_to_Invisible"; String INVISIBLE_TO_VISIBLE = "Invisible_to_Visible"; String INVISIBLE = "Invisible"; @@ -92,35 +94,36 @@ public class FooterBarMixinMetrics { /** Saves footer button visibility when finish state */ public void updateButtonVisibility( - boolean isPrimaryButtonVisiable, boolean isSecondaryButtonVisible) { + boolean isPrimaryButtonVisible, boolean isSecondaryButtonVisible) { primaryButtonVisibility = - updateButtonVisibilityState(primaryButtonVisibility, isPrimaryButtonVisiable); + updateButtonVisibilityState(primaryButtonVisibility, isPrimaryButtonVisible); secondaryButtonVisibility = updateButtonVisibilityState(secondaryButtonVisibility, isSecondaryButtonVisible); } @FooterButtonVisibility static String updateButtonVisibilityState( - @FooterButtonVisibility String origionalVisibility, boolean isVisible) { - if (!origionalVisibility.equals(FooterButtonVisibility.VISIBLE_USING_XML) - && !origionalVisibility.equals(FooterButtonVisibility.VISIBLE) - && !origionalVisibility.equals(FooterButtonVisibility.INVISIBLE)) { - throw new IllegalStateException("Illegal visibility state:" + origionalVisibility); + @FooterButtonVisibility String originalVisibility, boolean isVisible) { + if (!FooterButtonVisibility.VISIBLE_USING_XML.equals(originalVisibility) + && !FooterButtonVisibility.VISIBLE.equals(originalVisibility) + && !FooterButtonVisibility.INVISIBLE.equals(originalVisibility)) { + throw new IllegalStateException("Illegal visibility state: " + originalVisibility); } - if (isVisible && origionalVisibility.equals(FooterButtonVisibility.INVISIBLE)) { + if (isVisible && FooterButtonVisibility.INVISIBLE.equals(originalVisibility)) { return FooterButtonVisibility.INVISIBLE_TO_VISIBLE; } else if (!isVisible) { - if (origionalVisibility.equals(FooterButtonVisibility.VISIBLE_USING_XML)) { + if (FooterButtonVisibility.VISIBLE_USING_XML.equals(originalVisibility)) { return FooterButtonVisibility.VISIBLE_USING_XML_TO_INVISIBLE; - } else if (origionalVisibility.equals(FooterButtonVisibility.VISIBLE)) { + } else if (FooterButtonVisibility.VISIBLE.equals(originalVisibility)) { return FooterButtonVisibility.VISIBLE_TO_INVISIBLE; } } - return origionalVisibility; + return originalVisibility; } /** Returns metrics data for logging */ + @TargetApi(VERSION_CODES.Q) public PersistableBundle getMetrics() { PersistableBundle persistableBundle = new PersistableBundle(); persistableBundle.putString(EXTRA_PRIMARY_BUTTON_VISIBILITY, primaryButtonVisibility); diff --git a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java index 25fe418..4284ac9 100644 --- a/main/java/com/google/android/setupcompat/template/FooterBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/FooterBarMixin.java @@ -17,6 +17,7 @@ package com.google.android.setupcompat.template; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; @@ -52,6 +53,8 @@ import android.widget.LinearLayout.LayoutParams; import com.google.android.setupcompat.R; import com.google.android.setupcompat.internal.TemplateLayout; import com.google.android.setupcompat.logging.internal.FooterBarMixinMetrics; +import com.google.android.setupcompat.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; import com.google.android.setupcompat.template.FooterButton.ButtonType; import java.util.concurrent.atomic.AtomicInteger; @@ -89,7 +92,6 @@ public class FooterBarMixin implements Mixin { return new FooterButton.OnButtonEventListener() { - @Override public void onEnabledChanged(boolean enabled) { if (buttonContainer != null) { @@ -196,7 +198,14 @@ public class FooterBarMixin implements Mixin { } else { buttonContainer.setId(generateViewId()); } - updateBottomBarPadding(); + updateFooterBarPadding(); + if (applyPartnerResources) { + @ColorInt + int color = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_FOOTER_BAR_BG_COLOR); + buttonContainer.setBackgroundColor(color); + } } return buttonContainer; } @@ -416,7 +425,7 @@ public class FooterBarMixin implements Mixin { private void updateButtonAttrsWithPartnerConfig( Button button, boolean isPrimaryButton, @ButtonType int buttonType) { updateButtonTextColorWithPartnerConfig(button, isPrimaryButton); - updateButtonTextSizeWithPartnerConfig(button, isPrimaryButton); + updateButtonTextSizeWithPartnerConfig(button); updateButtonTypeFaceWithPartnerConfig(button); updateButtonBackgroundWithPartnerConfig(button, isPrimaryButton); updateButtonRadiusWithPartnerConfig(button); @@ -438,18 +447,13 @@ public class FooterBarMixin implements Mixin { button.setTextColor(color); } - private void updateButtonTextSizeWithPartnerConfig(Button button, boolean isPrimaryButton) { - float size; - if (isPrimaryButton) { - size = - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_SIZE); - } else { - size = - PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_SIZE); + private void updateButtonTextSizeWithPartnerConfig(Button button) { + float size = + PartnerConfigHelper.get(context) + .getDimension(context, PartnerConfig.CONFIG_FOOTER_BUTTON_TEXT_SIZE); + if (size > 0) { + button.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); } - button.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); } private void updateButtonTypeFaceWithPartnerConfig(Button button) { @@ -639,7 +643,7 @@ public class FooterBarMixin implements Mixin { return footerStub.inflate(); } - private void updateBottomBarPadding() { + private void updateFooterBarPadding() { if (buttonContainer == null) { // Ignore action since buttonContainer is null return; @@ -692,6 +696,7 @@ public class FooterBarMixin implements Mixin { /** * Assigns logging metrics to bundle for PartnerCustomizationLayout to log metrics to SetupWizard. */ + @TargetApi(VERSION_CODES.Q) public PersistableBundle getLoggingMetrics() { return metrics.getMetrics(); } diff --git a/main/java/com/google/android/setupcompat/template/FooterButton.java b/main/java/com/google/android/setupcompat/template/FooterButton.java index f913c0b..e2ef6c6 100644 --- a/main/java/com/google/android/setupcompat/template/FooterButton.java +++ b/main/java/com/google/android/setupcompat/template/FooterButton.java @@ -18,8 +18,10 @@ package com.google.android.setupcompat.template; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; +import android.os.Build.VERSION_CODES; import android.os.PersistableBundle; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -320,6 +322,7 @@ public final class FooterButton implements OnClickListener { * Returns footer button related metrics bundle for PartnerCustomizationLayout to log to * SetupWizard. */ + @TargetApi(VERSION_CODES.Q) public PersistableBundle getMetrics(String buttonName) { PersistableBundle bundle = new PersistableBundle(); bundle.putString(buttonName + KEY_BUTTON_TEXT, getText().toString()); diff --git a/main/java/com/google/android/setupcompat/template/HeaderMixin.java b/main/java/com/google/android/setupcompat/template/HeaderMixin.java deleted file mode 100644 index f6ae697..0000000 --- a/main/java/com/google/android/setupcompat/template/HeaderMixin.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2017 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.template; - -import android.content.res.ColorStateList; -import android.content.res.TypedArray; -import androidx.annotation.AttrRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.AttributeSet; -import android.widget.TextView; -import com.google.android.setupcompat.R; -import com.google.android.setupcompat.internal.TemplateLayout; - -/** - * A {@link com.google.android.setupcompat.template.Mixin} for setting and getting the header text. - */ -public class HeaderMixin implements Mixin { - - private final TemplateLayout templateLayout; - - /** - * @param layout The layout this Mixin belongs to. - * @param attrs XML attributes given to the layout. - * @param defStyleAttr The default style attribute as given to the constructor of the layout. - */ - public HeaderMixin( - @NonNull TemplateLayout layout, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { - templateLayout = layout; - - final TypedArray a = - layout - .getContext() - .obtainStyledAttributes(attrs, R.styleable.SucHeaderMixin, defStyleAttr, 0); - - // Set the header text - final CharSequence headerText = a.getText(R.styleable.SucHeaderMixin_sucHeaderText); - if (headerText != null) { - setText(headerText); - } - // Set the header text color - final ColorStateList headerTextColor = - a.getColorStateList(R.styleable.SucHeaderMixin_sucHeaderTextColor); - if (headerTextColor != null) { - setTextColor(headerTextColor); - } - - a.recycle(); - } - - /** @return The TextView displaying the header. */ - public TextView getTextView() { - return (TextView) templateLayout.findManagedViewById(R.id.suc_layout_title); - } - - /** - * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}. - * - * @param title The resource ID of the text to be set as header. - */ - public void setText(int title) { - final TextView titleView = getTextView(); - if (titleView != null) { - titleView.setText(title); - } - } - - /** - * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}. - * - * @param title The text to be set as header. - */ - public void setText(CharSequence title) { - final TextView titleView = getTextView(); - if (titleView != null) { - titleView.setText(title); - } - } - - /** @return The current header text. */ - public CharSequence getText() { - final TextView titleView = getTextView(); - return titleView != null ? titleView.getText() : null; - } - - /** - * Sets the color of the header text. This can also be set via XML using {@code - * app:sucHeaderTextColor}. - * - * @param color The text color of the header. - */ - public void setTextColor(ColorStateList color) { - final TextView titleView = getTextView(); - if (titleView != null) { - titleView.setTextColor(color); - } - } - - /** Returns the current text color of the header. */ - public ColorStateList getTextColor() { - final TextView titleView = getTextView(); - return titleView != null ? titleView.getTextColors() : null; - } -} diff --git a/main/java/com/google/android/setupcompat/template/IconMixin.java b/main/java/com/google/android/setupcompat/template/IconMixin.java deleted file mode 100644 index c2002e2..0000000 --- a/main/java/com/google/android/setupcompat/template/IconMixin.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2017 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.template; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import androidx.annotation.DrawableRes; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ImageView; -import com.google.android.setupcompat.R; -import com.google.android.setupcompat.internal.TemplateLayout; - -/** - * A {@link com.google.android.setupcompat.template.Mixin} for setting an icon on the template - * layout. - */ -public class IconMixin implements Mixin { - - private final TemplateLayout templateLayout; - - /** - * @param layout The template layout that this Mixin is a part of. - * @param attrs XML attributes given to the layout. - * @param defStyleAttr The default style attribute as given to the constructor of the layout. - */ - public IconMixin(TemplateLayout layout, AttributeSet attrs, int defStyleAttr) { - templateLayout = layout; - final Context context = layout.getContext(); - - final TypedArray a = - context.obtainStyledAttributes(attrs, R.styleable.SucIconMixin, defStyleAttr, 0); - - final @DrawableRes int icon = a.getResourceId(R.styleable.SucIconMixin_android_icon, 0); - if (icon != 0) { - setIcon(icon); - } - - a.recycle(); - } - - /** - * Sets the icon on this layout. The icon can also be set in XML using {@code android:icon}. - * - * @param icon A drawable icon. - */ - public void setIcon(Drawable icon) { - final ImageView iconView = getView(); - if (iconView != null) { - iconView.setImageDrawable(icon); - iconView.setVisibility(icon != null ? View.VISIBLE : View.GONE); - } - } - - /** - * Sets the icon on this layout. The icon can also be set in XML using {@code android:icon}. - * - * @param icon A drawable icon resource. - */ - public void setIcon(@DrawableRes int icon) { - final ImageView iconView = getView(); - if (iconView != null) { - // Note: setImageResource on the ImageView is overridden in AppCompatImageView for - // support lib users, which enables vector drawable compat to work on versions pre-L. - iconView.setImageResource(icon); - iconView.setVisibility(icon != 0 ? View.VISIBLE : View.GONE); - } - } - - /** @return The icon previously set in {@link #setIcon(Drawable)} or {@code android:icon} */ - public Drawable getIcon() { - final ImageView iconView = getView(); - return iconView != null ? iconView.getDrawable() : null; - } - - /** Sets the content description of the icon view */ - public void setContentDescription(CharSequence description) { - final ImageView iconView = getView(); - if (iconView != null) { - iconView.setContentDescription(description); - } - } - - /** @return The content description of the icon view */ - public CharSequence getContentDescription() { - final ImageView iconView = getView(); - return iconView != null ? iconView.getContentDescription() : null; - } - - /** @return The ImageView responsible for displaying the icon. */ - protected ImageView getView() { - return (ImageView) templateLayout.findManagedViewById(R.id.suc_layout_icon); - } -} diff --git a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java index 38e903b..2aa37dc 100644 --- a/main/java/com/google/android/setupcompat/template/StatusBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/StatusBarMixin.java @@ -35,6 +35,8 @@ import android.view.Window; import android.widget.LinearLayout; import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.R; +import com.google.android.setupcompat.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; import com.google.android.setupcompat.view.StatusBarBackgroundLayout; /** diff --git a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java index f137e7f..eae876c 100644 --- a/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java +++ b/main/java/com/google/android/setupcompat/template/SystemNavBarMixin.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.os.Build; +import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -32,6 +33,10 @@ import android.view.View; import android.view.Window; import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.R; +import com.google.android.setupcompat.internal.TemplateLayout; +import com.google.android.setupcompat.partnerconfig.PartnerConfig; +import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper; +import com.google.android.setupcompat.util.SystemBarBaseHelper; /** * A {@link Mixin} for setting and getting background color and window compatible with light theme @@ -39,38 +44,39 @@ import com.google.android.setupcompat.R; */ public class SystemNavBarMixin implements Mixin { - private final PartnerCustomizationLayout partnerCustomizationLayout; - private final Window windowOfActivity; - private final View decorView; + private final TemplateLayout templateLayout; + @Nullable private final Window windowOfActivity; @VisibleForTesting final boolean applyPartnerResources; + private int sucSystemNavBarBackgroundColor = 0; /** - * Creates a mixin for managing system navigation bar. + * Creates a mixin for managing the system navigation bar. * * @param layout The layout this Mixin belongs to. - * @param window The window this activity of Mixin belongs to. - * @param attrs XML attributes given to the layout. - * @param defStyleAttr The default style attribute as given to the constructor of the layout. - * @param applyPartnerResources determine applies partner resources or not. + * @param window The window this activity of Mixin belongs to.* + * @param applyPartnerResources whether to apply partner resources or not. */ public SystemNavBarMixin( - @NonNull PartnerCustomizationLayout layout, - @NonNull Window window, - @Nullable AttributeSet attrs, - @AttrRes int defStyleAttr, - boolean applyPartnerResources) { - partnerCustomizationLayout = layout; - windowOfActivity = window; - decorView = window.getDecorView(); + @NonNull TemplateLayout layout, @Nullable Window window, boolean applyPartnerResources) { + this.templateLayout = layout; + this.windowOfActivity = window; this.applyPartnerResources = applyPartnerResources; + } + /** + * Creates a mixin for managing the system navigation bar. + * + * @param attrs XML attributes given to the layout. + * @param defStyleAttr The default style attribute as given to the constructor of the layout. + */ + public void applyPartnerCustomizations(@Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { TypedArray a = - partnerCustomizationLayout + templateLayout .getContext() .obtainStyledAttributes(attrs, R.styleable.SucSystemNavBarMixin, defStyleAttr, 0); - int navigationBarBackground = + sucSystemNavBarBackgroundColor = a.getColor(R.styleable.SucSystemNavBarMixin_sucSystemNavBarBackgroundColor, 0); - setSystemNavBarBackground(navigationBarBackground); + setSystemNavBarBackground(sucSystemNavBarBackgroundColor); setLightSystemNavBar( a.getBoolean(R.styleable.SucSystemNavBarMixin_sucLightSystemNavBar, isLightSystemNavBar())); a.recycle(); @@ -83,21 +89,20 @@ public class SystemNavBarMixin implements Mixin { * @param color The background color of navigation bar. */ public void setSystemNavBarBackground(int color) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && windowOfActivity != null) { if (applyPartnerResources) { - Context context = partnerCustomizationLayout.getContext(); + Context context = templateLayout.getContext(); color = PartnerConfigHelper.get(context) .getColor(context, PartnerConfig.CONFIG_NAVIGATION_BAR_BG_COLOR); } - windowOfActivity.setNavigationBarColor(color); } } /** Returns the background color of navigation bar. */ public int getSystemNavBarBackground() { - if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && windowOfActivity != null) { return windowOfActivity.getNavigationBarColor(); } return Color.BLACK; @@ -111,20 +116,25 @@ public class SystemNavBarMixin implements Mixin { * @param isLight true means compatible with light theme, otherwise compatible with dark theme */ public void setLightSystemNavBar(boolean isLight) { - if (Build.VERSION.SDK_INT >= VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= VERSION_CODES.O && windowOfActivity != null) { if (applyPartnerResources) { - Context context = partnerCustomizationLayout.getContext(); + Context context = templateLayout.getContext(); isLight = PartnerConfigHelper.get(context) .getBoolean(context, PartnerConfig.CONFIG_LIGHT_NAVIGATION_BAR, false); } - if (isLight) { - decorView.setSystemUiVisibility( - decorView.getSystemUiVisibility() | SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + windowOfActivity + .getDecorView() + .setSystemUiVisibility( + windowOfActivity.getDecorView().getSystemUiVisibility() + | SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } else { - decorView.setSystemUiVisibility( - decorView.getSystemUiVisibility() & ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + windowOfActivity + .getDecorView() + .setSystemUiVisibility( + windowOfActivity.getDecorView().getSystemUiVisibility() + & ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } } } @@ -134,10 +144,73 @@ public class SystemNavBarMixin implements Mixin { * should be drawn light-on-dark. */ public boolean isLightSystemNavBar() { - if (Build.VERSION.SDK_INT >= VERSION_CODES.O) { - return (decorView.getSystemUiVisibility() & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) + if (Build.VERSION.SDK_INT >= VERSION_CODES.O && windowOfActivity != null) { + return (windowOfActivity.getDecorView().getSystemUiVisibility() + & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) == SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; } return true; } + + /** + * Hides the navigation bar, make the color of the status and navigation bars transparent, and + * specify {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} flag so that the content is laid-out + * behind the transparent status bar. This is commonly used with {@link + * android.app.Activity#getWindow()} to make the navigation and status bars follow the Setup + * Wizard style. + * + * <p>This will only take effect in versions Lollipop or above. Otherwise this is a no-op. + */ + public void hideSystemBars(final Window window) { + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + SystemBarBaseHelper.addVisibilityFlag(window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS); + SystemBarBaseHelper.addImmersiveFlagsToDecorView( + window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS); + + // Also set the navigation bar and status bar to transparent color. Note that this + // doesn't work if android.R.boolean.config_enableTranslucentDecor is false. + window.setNavigationBarColor(Color.TRANSPARENT); + window.setStatusBarColor(Color.TRANSPARENT); + } + } + + /** + * Reverts the actions of hideSystemBars. Note that this will remove the system UI visibility + * flags regardless of whether it is originally present. The status bar color is reset to + * transparent, thus it will show the status bar color set by StatusBarMixin. + * + * <p>This will only take effect in versions Lollipop or above. Otherwise this is a no-op. + */ + public void showSystemBars(final Window window, final Context context) { + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + SystemBarBaseHelper.removeVisibilityFlag(window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS); + SystemBarBaseHelper.removeImmersiveFlagsFromDecorView( + window, SystemBarBaseHelper.DEFAULT_IMMERSIVE_FLAGS); + + if (context != null) { + if (applyPartnerResources) { + int partnerNavigationBarColor = + PartnerConfigHelper.get(context) + .getColor(context, PartnerConfig.CONFIG_NAVIGATION_BAR_BG_COLOR); + window.setStatusBarColor(Color.TRANSPARENT); + window.setNavigationBarColor(partnerNavigationBarColor); + } else { + if (templateLayout instanceof PartnerCustomizationLayout) { + window.setStatusBarColor(Color.TRANSPARENT); + window.setNavigationBarColor(sucSystemNavBarBackgroundColor); + } else { + // noinspection AndroidLintInlinedApi + final TypedArray typedArray = + context.obtainStyledAttributes( + new int[] {android.R.attr.statusBarColor, android.R.attr.navigationBarColor}); + final int statusBarColor = typedArray.getColor(0, 0); + final int navigationBarColor = typedArray.getColor(1, 0); + window.setStatusBarColor(statusBarColor); + window.setNavigationBarColor(navigationBarColor); + typedArray.recycle(); + } + } + } + } + } } diff --git a/main/java/com/google/android/setupcompat/util/SystemBarBaseHelper.java b/main/java/com/google/android/setupcompat/util/SystemBarBaseHelper.java new file mode 100644 index 0000000..a1c5f65 --- /dev/null +++ b/main/java/com/google/android/setupcompat/util/SystemBarBaseHelper.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2019 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.util; + +import android.annotation.SuppressLint; +import android.os.Handler; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +/** + * A helper class to manage the system navigation bar and status bar. This will add various + * systemUiVisibility flags to the given Window or View to make them follow the Setup Wizard style. + * + * <p>When the useImmersiveMode intent extra is true, a screen in Setup Wizard should hide the + * system bars using methods from this class. For Lollipop, {@link + * #hideSystemBars(android.view.Window)} will completely hide the system navigation bar and change + * the status bar to transparent, and layout the screen contents (usually the illustration) behind + * it. + */ +public class SystemBarBaseHelper { + + private static final String TAG = "SystemBarBaseHelper"; + + @SuppressLint("InlinedApi") + public static final int DEFAULT_IMMERSIVE_FLAGS = + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + + @SuppressLint("InlinedApi") + public static final int DIALOG_IMMERSIVE_FLAGS = + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + + /** + * The maximum number of retries when peeking the decor view. When polling for the decor view, + * waiting it to be installed, set a maximum number of retries. + */ + private static final int PEEK_DECOR_VIEW_RETRIES = 3; + + /** Convenience method to add a visibility flag in addition to the existing ones. */ + public static void addVisibilityFlag(final View view, final int flag) { + final int vis = view.getSystemUiVisibility(); + view.setSystemUiVisibility(vis | flag); + } + + /** Convenience method to add a visibility flag in addition to the existing ones. */ + public static void addVisibilityFlag(final Window window, final int flag) { + WindowManager.LayoutParams attrs = window.getAttributes(); + attrs.systemUiVisibility |= flag; + window.setAttributes(attrs); + } + + /** + * Convenience method to remove a visibility flag from the view, leaving other flags that are not + * specified intact. + */ + public static void removeVisibilityFlag(final View view, final int flag) { + final int vis = view.getSystemUiVisibility(); + view.setSystemUiVisibility(vis & ~flag); + } + + /** + * Convenience method to remove a visibility flag from the window, leaving other flags that are + * not specified intact. + */ + public static void removeVisibilityFlag(final Window window, final int flag) { + WindowManager.LayoutParams attrs = window.getAttributes(); + attrs.systemUiVisibility &= ~flag; + window.setAttributes(attrs); + } + + /** + * Add the specified immersive flags to the decor view of the window, because {@link + * View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} only takes effect when it is added to a view instead of + * the window. + */ + public static void addImmersiveFlagsToDecorView(final Window window, final int vis) { + getDecorView( + window, + new OnDecorViewInstalledListener() { + @Override + public void onDecorViewInstalled(View decorView) { + addVisibilityFlag(decorView, vis); + } + }); + } + + public static void removeImmersiveFlagsFromDecorView(final Window window, final int vis) { + getDecorView( + window, + new OnDecorViewInstalledListener() { + @Override + public void onDecorViewInstalled(View decorView) { + removeVisibilityFlag(decorView, vis); + } + }); + } + + private static void getDecorView(Window window, OnDecorViewInstalledListener callback) { + new DecorViewFinder().getDecorView(window, callback, PEEK_DECOR_VIEW_RETRIES); + } + + private static class DecorViewFinder { + + private final Handler handler = new Handler(); + private Window window; + private int retries; + private OnDecorViewInstalledListener callback; + + private final Runnable checkDecorViewRunnable = + new Runnable() { + @Override + public void run() { + // Use peekDecorView instead of getDecorView so that clients can still set window + // features after calling this method. + final View decorView = window.peekDecorView(); + if (decorView != null) { + callback.onDecorViewInstalled(decorView); + } else { + retries--; + if (retries >= 0) { + // If the decor view is not installed yet, try again in the next loop. + handler.post(checkDecorViewRunnable); + } else { + Log.w(TAG, "Cannot get decor view of window: " + window); + } + } + } + }; + + public void getDecorView(Window window, OnDecorViewInstalledListener callback, int retries) { + this.window = window; + this.retries = retries; + this.callback = callback; + checkDecorViewRunnable.run(); + } + } + + private interface OnDecorViewInstalledListener { + + void onDecorViewInstalled(View decorView); + } +} diff --git a/main/res/layout/partner_customization_layout.xml b/main/res/layout/partner_customization_layout.xml index 09ee7f1..30ef2b0 100644 --- a/main/res/layout/partner_customization_layout.xml +++ b/main/res/layout/partner_customization_layout.xml @@ -26,13 +26,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - <ImageView - android:id="@+id/suc_layout_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:contentDescription="@null" - android:visibility="gone" /> - <TextView android:id="@+id/suc_layout_title" android:layout_width="match_parent" diff --git a/main/res/values/attrs.xml b/main/res/values/attrs.xml index 3ad87e5..e336905 100644 --- a/main/res/values/attrs.xml +++ b/main/res/values/attrs.xml @@ -89,10 +89,6 @@ <attr name="sucFooterBarPaddingVertical" format="dimension" /> </declare-styleable> - <declare-styleable name="SucIconMixin"> - <attr name="android:icon" /> - </declare-styleable> - <declare-styleable name="SucHeaderMixin"> <attr name="sucHeaderText" format="string" localization="suggested" /> <attr name="sucHeaderTextColor" format="reference|color" /> diff --git a/partnerconfig/AndroidManifest.xml b/partnerconfig/AndroidManifest.xml new file mode 100644 index 0000000..c95a4dd --- /dev/null +++ b/partnerconfig/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2019 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.setupcompat.partnerconfig"> + + <uses-sdk + android:minSdkVersion="14" + android:targetSdkVersion="28" /> +</manifest> diff --git a/main/java/com/google/android/setupcompat/template/PartnerConfig.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java index 00a36b7..d2ae023 100644 --- a/main/java/com/google/android/setupcompat/template/PartnerConfig.java +++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfig.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.android.setupcompat.template; +package com.google.android.setupcompat.partnerconfig; // TODO(b/121371322): optimize the enum /** Resources that can be customized by partner overlay APK. */ -enum PartnerConfig { +public enum PartnerConfig { // Status bar background color or illustration. CONFIG_STATUS_BAR_BACKGROUND(PartnerConfigKey.KEY_STATUS_BAR_BACKGROUND, ResourceType.DRAWABLE), @@ -30,6 +30,9 @@ enum PartnerConfig { // Navigation bar background color CONFIG_NAVIGATION_BAR_BG_COLOR(PartnerConfigKey.KEY_NAVIGATION_BAR_BG_COLOR, ResourceType.COLOR), + // Background color of the footer bar. + CONFIG_FOOTER_BAR_BG_COLOR(PartnerConfigKey.KEY_FOOTER_BAR_BG_COLOR, ResourceType.COLOR), + // The same as "windowLightNavigationBar". If set true, the navigation bar icons will be drawn // such that it is compatible with a light navigation bar background. CONFIG_LIGHT_NAVIGATION_BAR(PartnerConfigKey.KEY_LIGHT_NAVIGATION_BAR, ResourceType.BOOL), @@ -86,6 +89,10 @@ enum PartnerConfig { CONFIG_FOOTER_BUTTON_RIPPLE_COLOR_ALPHA( PartnerConfigKey.KEY_FOOTER_BUTTON_RIPPLE_ALPHA, ResourceType.FRACTION), + // Text size of the primary footer button + CONFIG_FOOTER_BUTTON_TEXT_SIZE( + PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_SIZE, ResourceType.DIMENSION), + // Background color of the primary footer button CONFIG_FOOTER_PRIMARY_BUTTON_BG_COLOR( PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_BG_COLOR, ResourceType.COLOR), @@ -94,10 +101,6 @@ enum PartnerConfig { CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_COLOR( PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_TEXT_COLOR, ResourceType.COLOR), - // Text size of the primary footer button - CONFIG_FOOTER_PRIMARY_BUTTON_TEXT_SIZE( - PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_TEXT_SIZE, ResourceType.DIMENSION), - // Background color of the secondary footer button CONFIG_FOOTER_SECONDARY_BUTTON_BG_COLOR( PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_BG_COLOR, ResourceType.COLOR), @@ -106,9 +109,37 @@ enum PartnerConfig { CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_COLOR( PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_TEXT_COLOR, ResourceType.COLOR), - // Text size of the secondary footer button - CONFIG_FOOTER_SECONDARY_BUTTON_TEXT_SIZE( - PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_TEXT_SIZE, ResourceType.DIMENSION); + // Background color of layout + CONFIG_LAYOUT_BACKGROUND_COLOR(PartnerConfigKey.KEY_LAYOUT_BACKGROUND_COLOR, ResourceType.COLOR), + + // Text color of the header + CONFIG_HEADER_TEXT_COLOR(PartnerConfigKey.KEY_HEADER_TEXT_COLOR, ResourceType.COLOR), + + // Text size of the header + CONFIG_HEADER_TEXT_SIZE(PartnerConfigKey.KEY_HEADER_TEXT_SIZE, ResourceType.DIMENSION), + + // Font family of the header + CONFIG_HEADER_FONT_FAMILY(PartnerConfigKey.KEY_HEADER_FONT_FAMILY, ResourceType.STRING), + + // Gravity of the header, icon and description + CONFIG_LAYOUT_GRAVITY(PartnerConfigKey.KEY_LAYOUT_GRAVITY, ResourceType.STRING), + + // Background color of the header area + CONFIG_HEADER_AREA_BACKGROUND_COLOR( + PartnerConfigKey.KEY_HEADER_AREA_BACKGROUND_COLOR, ResourceType.COLOR), + + // Text size of the description + CONFIG_DESCRIPTION_TEXT_SIZE(PartnerConfigKey.KEY_DESCRIPTION_TEXT_SIZE, ResourceType.DIMENSION), + + // Text color of the description + CONFIG_DESCRIPTION_TEXT_COLOR(PartnerConfigKey.KEY_DESCRIPTION_TEXT_COLOR, ResourceType.COLOR), + + // Link text color of the description + CONFIG_DESCRIPTION_LINK_TEXT_COLOR( + PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR, ResourceType.COLOR), + + // Font family of the description + CONFIG_DESCRIPTION_FONT_FAMILY(PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, ResourceType.STRING); public enum ResourceType { BOOL, diff --git a/main/java/com/google/android/setupcompat/template/PartnerConfigHelper.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java index 9c540dd..6fb391c 100644 --- a/main/java/com/google/android/setupcompat/template/PartnerConfigHelper.java +++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigHelper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.setupcompat.template; +package com.google.android.setupcompat.partnerconfig; import android.content.ContentResolver; import android.content.Context; @@ -32,12 +32,10 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import android.util.Log; import android.util.TypedValue; -import com.google.android.setupcompat.template.PartnerConfig.ResourceType; -import com.google.android.setupcompat.util.ResourceEntry; +import com.google.android.setupcompat.partnerconfig.PartnerConfig.ResourceType; import java.util.EnumMap; /** The helper reads and caches the partner configurations from SUW. */ -@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class PartnerConfigHelper { private static final String TAG = PartnerConfigHelper.class.getSimpleName(); diff --git a/main/java/com/google/android/setupcompat/template/PartnerConfigKey.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java index d79c152..0c0c44f 100644 --- a/main/java/com/google/android/setupcompat/template/PartnerConfigKey.java +++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/PartnerConfigKey.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.setupcompat.template; +package com.google.android.setupcompat.partnerconfig; import androidx.annotation.StringDef; import androidx.annotation.VisibleForTesting; @@ -28,6 +28,7 @@ import java.lang.annotation.RetentionPolicy; PartnerConfigKey.KEY_LIGHT_STATUS_BAR, PartnerConfigKey.KEY_NAVIGATION_BAR_BG_COLOR, PartnerConfigKey.KEY_LIGHT_NAVIGATION_BAR, + PartnerConfigKey.KEY_FOOTER_BAR_BG_COLOR, PartnerConfigKey.KEY_FOOTER_BUTTON_FONT_FAMILY, PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_ADD_ANOTHER, PartnerConfigKey.KEY_FOOTER_BUTTON_ICON_CANCEL, @@ -41,14 +42,23 @@ import java.lang.annotation.RetentionPolicy; PartnerConfigKey.KEY_FOOTER_BUTTON_PADDING_BOTTOM, PartnerConfigKey.KEY_FOOTER_BUTTON_RADIUS, PartnerConfigKey.KEY_FOOTER_BUTTON_RIPPLE_ALPHA, + PartnerConfigKey.KEY_FOOTER_BUTTON_TEXT_SIZE, PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_BG_COLOR, PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_TEXT_COLOR, - PartnerConfigKey.KEY_FOOTER_PRIMARY_BUTTON_TEXT_SIZE, PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_BG_COLOR, PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_TEXT_COLOR, - PartnerConfigKey.KEY_FOOTER_SECONDARY_BUTTON_TEXT_SIZE, + PartnerConfigKey.KEY_LAYOUT_BACKGROUND_COLOR, + PartnerConfigKey.KEY_HEADER_TEXT_SIZE, + PartnerConfigKey.KEY_HEADER_TEXT_COLOR, + PartnerConfigKey.KEY_HEADER_FONT_FAMILY, + PartnerConfigKey.KEY_HEADER_AREA_BACKGROUND_COLOR, + PartnerConfigKey.KEY_LAYOUT_GRAVITY, + PartnerConfigKey.KEY_DESCRIPTION_TEXT_SIZE, + PartnerConfigKey.KEY_DESCRIPTION_TEXT_COLOR, + PartnerConfigKey.KEY_DESCRIPTION_LINK_TEXT_COLOR, + PartnerConfigKey.KEY_DESCRIPTION_FONT_FAMILY, }) -// TODO(121371322): can be removed and always reference PartnerConfig.getResourceName()? +// TODO(b/121371322): can be removed and always reference PartnerConfig.getResourceName()? @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public @interface PartnerConfigKey { // Status bar background color or illustration. @@ -65,6 +75,9 @@ public @interface PartnerConfigKey { // such that it is compatible with a light navigation bar background. String KEY_LIGHT_NAVIGATION_BAR = "setup_compat_light_navigation_bar"; + // Background color of the footer bar. + String KEY_FOOTER_BAR_BG_COLOR = "setup_compat_footer_bar_bg_color"; + // The font face used in footer buttons. This must be a string reference to a font that is // available in the system. Font references (@font or @xml) are not allowed. String KEY_FOOTER_BUTTON_FONT_FAMILY = "setup_compat_footer_button_font_family"; @@ -105,21 +118,48 @@ public @interface PartnerConfigKey { // Ripple color alpha of the footer button String KEY_FOOTER_BUTTON_RIPPLE_ALPHA = "setup_compat_footer_button_ripple_alpha"; + // Text size of the footer button + String KEY_FOOTER_BUTTON_TEXT_SIZE = "setup_compat_footer_button_text_size"; + // Background color of the primary footer button String KEY_FOOTER_PRIMARY_BUTTON_BG_COLOR = "setup_compat_footer_primary_button_bg_color"; // Text color of the primary footer button String KEY_FOOTER_PRIMARY_BUTTON_TEXT_COLOR = "setup_compat_footer_primary_button_text_color"; - // Text size of the primary footer button - String KEY_FOOTER_PRIMARY_BUTTON_TEXT_SIZE = "setup_compat_footer_primary_button_text_size"; - // Background color of the secondary footer button String KEY_FOOTER_SECONDARY_BUTTON_BG_COLOR = "setup_compat_footer_secondary_button_bg_color"; // Text color of the secondary footer button String KEY_FOOTER_SECONDARY_BUTTON_TEXT_COLOR = "setup_compat_footer_secondary_button_text_color"; - // Text size of the secondary footer button - String KEY_FOOTER_SECONDARY_BUTTON_TEXT_SIZE = "setup_compat_footer_secondary_button_text_size"; + // Background color of layout + String KEY_LAYOUT_BACKGROUND_COLOR = "setup_compat_layout_bg_color"; + + // Text size of the header + String KEY_HEADER_TEXT_SIZE = "setup_design_header_text_size"; + + // Text color of the header + String KEY_HEADER_TEXT_COLOR = "setup_design_header_text_color"; + + // Font family of the header + String KEY_HEADER_FONT_FAMILY = "setup_design_header_font_family"; + + // Gravity of the header, icon and description + String KEY_LAYOUT_GRAVITY = "setup_design_layout_gravity"; + + // Background color of the header area + String KEY_HEADER_AREA_BACKGROUND_COLOR = "setup_design_header_area_background_color"; + + // Text size of the description + String KEY_DESCRIPTION_TEXT_SIZE = "setup_design_description_text_size"; + + // Text color of the description + String KEY_DESCRIPTION_TEXT_COLOR = "setup_design_description_text_color"; + + // Link text color of the description + String KEY_DESCRIPTION_LINK_TEXT_COLOR = "setup_design_description_link_text_color"; + + // Font family of the description + String KEY_DESCRIPTION_FONT_FAMILY = "setup_design_description_font_family"; } diff --git a/main/java/com/google/android/setupcompat/util/ResourceEntry.java b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java index c1dee67..2794f22 100644 --- a/main/java/com/google/android/setupcompat/util/ResourceEntry.java +++ b/partnerconfig/java/com/google/android/setupcompat/partnerconfig/ResourceEntry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.setupcompat.util; +package com.google.android.setupcompat.partnerconfig; import android.os.Bundle; import androidx.annotation.VisibleForTesting; diff --git a/proguard.flags b/proguard.flags new file mode 100644 index 0000000..8cc2b25 --- /dev/null +++ b/proguard.flags @@ -0,0 +1,6 @@ +# All parcelable classes under com.google.android.setupcompat.logging are serialized across processes +# and need to have the same class names to avoid (de)serialization errors/mismatches. +-keepnames class com.google.android.setupcompat.logging.* implements android.os.Parcelable +-keepclassmembers class com.google.android.setupcompat.logging.* implements android.os.Parcelable { + public static final ** CREATOR; +}
\ No newline at end of file |