diff options
author | Setup Wizard Team <android-setup-team-eng@google.com> | 2018-12-19 11:31:37 +0800 |
---|---|---|
committer | cnchen <cnchen@google.com> | 2018-12-21 10:25:12 +0800 |
commit | ff4fecb9b05c27aef05f1acbe9cb2524062df65d (patch) | |
tree | 0c8b225b0dccfddf02038af026170fc800da0dec /main/java/com/google/android | |
parent | 1d79d004a05309c98637e35c27a37625025d0f9d (diff) | |
download | setupcompat-ff4fecb9b05c27aef05f1acbe9cb2524062df65d.tar.gz |
Import updated Android SetupCompat Library 226102911
Test: mm
PiperOrigin-RevId: 226102911
Change-Id: Ia10a54425adb7f990668be39b66716169f7150ff
Diffstat (limited to 'main/java/com/google/android')
5 files changed, 175 insertions, 73 deletions
diff --git a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java index 477097f..7d0e816 100644 --- a/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java +++ b/main/java/com/google/android/setupcompat/PartnerCustomizationLayout.java @@ -75,17 +75,6 @@ public class PartnerCustomizationLayout extends TemplateLayout { activity = lookupActivityFromContext(getContext()); boolean isSetupFlow = WizardManagerHelper.isAnySetupWizard(activity.getIntent()); - boolean applyPartnerResources = suwVersionSupportPartnerResource && isSetupFlow; - registerMixin( - StatusBarMixin.class, - new StatusBarMixin(this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResources)); - registerMixin( - SystemNavBarMixin.class, - new SystemNavBarMixin( - this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResources)); - registerMixin( - ButtonFooterMixin.class, - new ButtonFooterMixin(this, attrs, defStyleAttr, applyPartnerResources)); TypedArray a = getContext() @@ -99,12 +88,28 @@ public class PartnerCustomizationLayout extends TemplateLayout { boolean layoutFullscreen = a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucLayoutFullscreen, true); + + boolean usePartnerResource = + a.getBoolean(R.styleable.SucPartnerCustomizationLayout_sucUsePartnerResource, true); a.recycle(); if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && layoutFullscreen) { setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } + boolean applyPartnerResource = + suwVersionSupportPartnerResource && (isSetupFlow || usePartnerResource); + registerMixin( + StatusBarMixin.class, + new StatusBarMixin(this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResource)); + registerMixin( + SystemNavBarMixin.class, + new SystemNavBarMixin( + this, activity.getWindow(), attrs, defStyleAttr, applyPartnerResource)); + registerMixin( + ButtonFooterMixin.class, + new ButtonFooterMixin(this, attrs, defStyleAttr, applyPartnerResource)); + // 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. diff --git a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java index 0538450..e16dda9 100644 --- a/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java +++ b/main/java/com/google/android/setupcompat/internal/SetupCompatServiceProvider.java @@ -217,8 +217,13 @@ public class SetupCompatServiceProvider { new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder binder) { + State state = State.CONNECTED; + if (binder == null) { + state = State.DISCONNECTED; + Log.w(TAG, "Binder is null when onServiceConnected was called!"); + } swapServiceContextAndNotify( - new ServiceContext(State.CONNECTED, ISetupCompatService.Stub.asInterface(binder))); + new ServiceContext(state, ISetupCompatService.Stub.asInterface(binder))); } @Override diff --git a/main/java/com/google/android/setupcompat/item/FooterButton.java b/main/java/com/google/android/setupcompat/item/FooterButton.java index 4601ba0..dbebc90 100644 --- a/main/java/com/google/android/setupcompat/item/FooterButton.java +++ b/main/java/com/google/android/setupcompat/item/FooterButton.java @@ -19,12 +19,14 @@ package com.google.android.setupcompat.item; import android.content.Context; import android.content.res.TypedArray; import androidx.annotation.IdRes; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import android.util.AttributeSet; import android.view.View.OnClickListener; +import android.view.View.OnTouchListener; import com.google.android.setupcompat.R; import com.google.android.setupcompat.template.ButtonFooterMixin; @@ -32,7 +34,7 @@ import com.google.android.setupcompat.template.ButtonFooterMixin; * Definition of a footer button. Clients can use this class to customize attributes like text, * button type and click listener, and ButtonFooterMixin will inflate a corresponding Button view. */ -public class FooterButton { +public final class FooterButton { private static final int BUTTON_TYPE_NONE = 0; private final ButtonType buttonType; @@ -49,8 +51,9 @@ public class FooterButton { text = a.getString(R.styleable.SucFooterButton_android_text); onClickListener = null; buttonType = - ButtonType.values()[a.getInt(R.styleable.SucFooterButton_sucButtonType, BUTTON_TYPE_NONE)]; - theme = a.getResourceId(R.styleable.SucFooterButton_android_theme, 0); + ButtonType.valueOf( + a.getInt(R.styleable.SucFooterButton_sucButtonType, /* defValue= */ BUTTON_TYPE_NONE)); + theme = a.getResourceId(R.styleable.SucFooterButton_android_theme, /* defValue= */ 0); a.recycle(); } @@ -63,7 +66,9 @@ public class FooterButton { * @param listener The listener for button. * @param buttonType The type of button. * @param theme The theme for button. + * @deprecated use {@link #FooterButton.Builder(Context)} instead. */ + @Deprecated public FooterButton( Context context, @StringRes int text, @@ -73,6 +78,8 @@ public class FooterButton { this(context.getString(text), listener, buttonType, theme); } + /** @deprecated use {@link #FooterButton.Builder(Context)} instead. */ + @Deprecated public FooterButton( Context context, @StringRes int text, @@ -81,12 +88,16 @@ public class FooterButton { this(context.getString(text), listener, ButtonType.OTHER, theme); } + /** @deprecated use {@link #FooterButton.Builder(Context)} instead. */ + @Deprecated public FooterButton(String text, @Nullable OnClickListener listener, @StyleRes int theme) { this(text, listener, ButtonType.OTHER, theme); } + /** @deprecated use {@link #FooterButton.Builder(Context)} instead. */ + @Deprecated public FooterButton( - String text, + CharSequence text, @Nullable OnClickListener listener, @Nullable ButtonType buttonType, @StyleRes int theme) { @@ -125,6 +136,17 @@ public class FooterButton { } } + /** + * Registers a callback to be invoked when touch event footer button has reacted. + * + * @param listener The callback that will run + */ + public void setOnTouchListener(@Nullable OnTouchListener listener) { + if (buttonListener != null && id != 0) { + buttonListener.onTouchListenerChanged(listener, id); + } + } + /** Returns the type of this footer button icon. */ public ButtonType getButtonType() { return buttonType; @@ -200,6 +222,8 @@ public class FooterButton { void onClickListenerChanged(@Nullable OnClickListener listener, @IdRes int id); + void onTouchListenerChanged(@Nullable OnTouchListener listener, @IdRes int id); + void onEnabledChanged(boolean enabled, @IdRes int id); void onVisibilityChanged(int visibility, @IdRes int id); @@ -229,6 +253,78 @@ public class FooterButton { /** A type of button that will cancel the ongoing setup step(s) and exit setup when clicked. */ CANCEL, /** A type of button that will stop the ongoing setup step(s) and skip forward when clicked. */ - STOP + STOP; + + public static ButtonType valueOf(int value) { + if (value >= 0 && value < ButtonType.values().length) { + return ButtonType.values()[value]; + } else { + return OTHER; + } + } + } + + /** + * Builder class for constructing {@code FooterButton} objects. + * + * <p>Allows client customize text, click listener and theme for footer button before Button has + * been created. The {@link ButtonFooterMixin} will inflate a corresponding Button view. + * + * <p>Example: + * + * <pre class="prettyprint"> + * FooterButton primaryButton = + * new FooterButton.Builder(mContext) + * .setText(R.string.primary_button_label) + * .setListener(primaryButton) + * .setButtonType(ButtonType.NEXT) + * .setTheme(R.style.SuwGlifButton_Primary) + * .build(); + * </pre> + */ + public static class Builder { + private final Context context; + private String text = ""; + private OnClickListener onClickListener = null; + private ButtonType buttonType = ButtonType.OTHER; + private int theme = 0; + + public Builder(@NonNull Context context) { + this.context = context; + } + + /** Sets the {@code text} of FooterButton. */ + public Builder setText(String text) { + this.text = text; + return this; + } + + /** Sets the {@code text} of FooterButton by resource. */ + public Builder setText(@StringRes int text) { + this.text = context.getString(text); + return this; + } + + /** Sets the {@code listener} of FooterButton. */ + public Builder setListener(@Nullable OnClickListener listener) { + onClickListener = listener; + return this; + } + + /** Sets the {@code buttonType} of FooterButton. */ + public Builder setButtonType(ButtonType buttonType) { + this.buttonType = buttonType; + return this; + } + + /** Sets the {@code theme} for applying FooterButton. */ + public Builder setTheme(@StyleRes int theme) { + this.theme = theme; + return this; + } + + public FooterButton build() { + return new FooterButton(text, onClickListener, buttonType, theme); + } } } diff --git a/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java b/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java index 9effade..47177af 100644 --- a/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java +++ b/main/java/com/google/android/setupcompat/template/ButtonFooterMixin.java @@ -44,6 +44,7 @@ import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; +import android.view.View.OnTouchListener; import android.view.ViewStub; import android.widget.Button; import android.widget.LinearLayout; @@ -98,6 +99,16 @@ public class ButtonFooterMixin implements Mixin { } @Override + public void onTouchListenerChanged(@Nullable OnTouchListener listener, @IdRes int id) { + if (buttonContainer != null && id != 0) { + Button button = buttonContainer.findViewById(id); + if (button != null) { + button.setOnTouchListener(listener); + } + } + } + + @Override public void onEnabledChanged(boolean enabled, @IdRes int id) { if (buttonContainer != null && id != 0) { Button button = buttonContainer.findViewById(id); @@ -113,6 +124,7 @@ public class ButtonFooterMixin implements Mixin { Button button = buttonContainer.findViewById(id); if (button != null) { button.setVisibility(visibility); + autoSetButtonBarVisibility(); } } } @@ -190,6 +202,11 @@ public class ButtonFooterMixin implements Mixin { throw new IllegalStateException("Footer stub is not found in this template"); } buttonContainer = (LinearLayout) inflateFooter(R.layout.suc_footer_button_bar); + if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) { + buttonContainer.setId(View.generateViewId()); + } else { + buttonContainer.setId(generateViewId()); + } updateBottomBarPadding(); } return buttonContainer; @@ -205,7 +222,6 @@ public class ButtonFooterMixin implements Mixin { /** Sets primary button for footer. */ public void setPrimaryButton(FooterButton footerButton) { - addSpace(); LinearLayout buttonContainer = ensureFooterInflated(); // Set the default theme if theme is not set, or when running in setup flow. @@ -225,6 +241,7 @@ public class ButtonFooterMixin implements Mixin { Button button = inflateButton(footerButton); primaryButtonId = button.getId(); buttonContainer.addView(button); + autoSetButtonBarVisibility(); if (applyPartnerResources) { // This API should only be called after primaryButtonId is set. @@ -235,11 +252,9 @@ public class ButtonFooterMixin implements Mixin { footerButton.setOnButtonEventListener(onButtonEventListener); primaryButton = footerButton; - // Check secondary button has been set before primary button or not. If set, will re-populate - // buttons to make sure the position of buttons are correctly. - if (getSecondaryButton() != null) { - repopulateButtons(); - } + // Make sure the position of buttons are correctly and prevent primary button create twice or + // more. + repopulateButtons(); } /** Returns the {@link FooterButton} of primary button. */ @@ -287,13 +302,10 @@ public class ButtonFooterMixin implements Mixin { footerButton.setId(secondaryButtonId); footerButton.setOnButtonEventListener(onButtonEventListener); secondaryButton = footerButton; - addSpace(); - // Check primary button has been set before secondary button or not. If set, will re-populate - // buttons to make sure the position of buttons are correctly. - if (getPrimaryButton() != null) { - repopulateButtons(); - } + // Make sure the position of buttons are correctly and prevent secondary button create twice or + // more. + repopulateButtons(); } public void repopulateButtons() { @@ -301,9 +313,14 @@ public class ButtonFooterMixin implements Mixin { Button tempPrimaryButton = getPrimaryButtonView(); Button tempSecondaryButton = getSecondaryButtonView(); buttonContainer.removeAllViews(); - buttonContainer.addView(tempSecondaryButton); + + if (tempSecondaryButton != null) { + buttonContainer.addView(tempSecondaryButton); + } addSpace(); - buttonContainer.addView(tempPrimaryButton); + if (tempPrimaryButton != null) { + buttonContainer.addView(tempPrimaryButton); + } } @VisibleForTesting @@ -316,6 +333,26 @@ public class ButtonFooterMixin implements Mixin { return secondaryButton; } + /** + * Checks the visibility state of footer buttons to set the visibility state of this footer bar + * automatically. + */ + private void autoSetButtonBarVisibility() { + Button primaryButton = getPrimaryButtonView(); + Button secondaryButton = getSecondaryButtonView(); + boolean primaryVisible = primaryButton != null && primaryButton.getVisibility() == View.VISIBLE; + boolean secondaryVisible = + secondaryButton != null && secondaryButton.getVisibility() == View.VISIBLE; + + buttonContainer.setVisibility(primaryVisible || secondaryVisible ? View.VISIBLE : View.GONE); + } + + /** Returns the visibility status for this footer bar. */ + @VisibleForTesting + public int getVisibility() { + return buttonContainer.getVisibility(); + } + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public Button getSecondaryButtonView() { return buttonContainer == null ? null : buttonContainer.findViewById(secondaryButtonId); @@ -425,11 +462,9 @@ public class ButtonFooterMixin implements Mixin { private void updateButtonRadiusWithPartnerConfig(Button button) { if (Build.VERSION.SDK_INT >= VERSION_CODES.N) { - float defaultRadius = - context.getResources().getDimension(R.dimen.suc_customization_button_corner_radius); float radius = PartnerConfigHelper.get(context) - .getDimension(context, PartnerConfig.CONFIG_FOOTER_BUTTON_RADIUS, defaultRadius); + .getDimension(context, PartnerConfig.CONFIG_FOOTER_BUTTON_RADIUS); GradientDrawable gradientDrawable = getGradientDrawable(button); if (gradientDrawable != null) { gradientDrawable.setCornerRadius(radius); diff --git a/main/java/com/google/android/setupcompat/util/FlagHelper.java b/main/java/com/google/android/setupcompat/util/FlagHelper.java deleted file mode 100644 index b2b700f..0000000 --- a/main/java/com/google/android/setupcompat/util/FlagHelper.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018 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.content.Context; -import android.content.res.TypedArray; -import com.google.android.setupcompat.R; - -/** Helper utilities to get flags that enable/disable features of this library. */ -public final class FlagHelper { - - private FlagHelper() {} - - /** - * Returns whether customization styles should be loaded from the partner overlay APK. Default - * value is currently false, but will be changed to true once the feature is ready for general - * consumption. Outside of setup wizard flow, this flag should default to false. - */ - public static final boolean isPartnerStyleEnabled(Context context) { - TypedArray typedArray = context.obtainStyledAttributes(new int[] {R.attr.sucEnablePartnerStyle}); - boolean enablePartnerStyle = typedArray.getBoolean(0, false); - typedArray.recycle(); - return enablePartnerStyle; - } -} |