• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.managedprovisioning.provisioning;
18 
19 import static com.google.android.setupdesign.util.ThemeHelper.shouldApplyExtendedPartnerConfig;
20 
21 import android.app.Activity;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.LinearLayout;
25 import android.widget.Space;
26 import android.widget.TextView;
27 
28 import androidx.annotation.StringRes;
29 
30 import com.android.managedprovisioning.R;
31 import com.android.managedprovisioning.common.InitializeLayoutConsumerHandler;
32 import com.android.managedprovisioning.common.StylerHelper;
33 import com.android.managedprovisioning.common.Utils;
34 import com.android.managedprovisioning.model.CustomizationParams;
35 import com.android.managedprovisioning.model.ProvisioningParams;
36 import com.android.managedprovisioning.provisioning.ProvisioningActivity.ProvisioningMode;
37 import com.android.managedprovisioning.provisioning.ProvisioningModeWrapperProvider.ProvisioningModeWrapper;
38 import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.AnimationComponents;
39 import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.TransitionAnimationCallback;
40 import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.TransitionAnimationStateManager;
41 
42 import com.airbnb.lottie.LottieAnimationView;
43 import com.google.android.setupdesign.GlifLayout;
44 import com.google.android.setupdesign.util.ContentStyler;
45 import com.google.android.setupdesign.util.DescriptionStyler;
46 import com.google.auto.value.AutoValue;
47 
48 import java.util.function.Supplier;
49 
50 @AutoValue
51 abstract class ProvisioningActivityBridgeImpl implements ProvisioningActivityBridge {
52 
53     private TransitionAnimationHelper mTransitionAnimationHelper;
54     private ViewGroup mButtonFooterContainer;
55 
getUtils()56     abstract Utils getUtils();
getParams()57     abstract ProvisioningParams getParams();
getProvisioningMode()58     abstract @ProvisioningMode int getProvisioningMode();
getProvisioningManager()59     abstract ProvisioningManager getProvisioningManager();
getTransitionAnimationCallback()60     abstract TransitionAnimationCallback getTransitionAnimationCallback();
getInitializeLayoutParamsConsumer()61     abstract InitializeLayoutConsumerHandler getInitializeLayoutParamsConsumer();
getShouldSkipEducationScreens()62     abstract boolean getShouldSkipEducationScreens();
getProgressLabelResId()63     abstract @StringRes int getProgressLabelResId();
getBridgeCallbacks()64     abstract ProvisioningActivityBridgeCallbacks getBridgeCallbacks();
getStateManager()65     abstract TransitionAnimationStateManager getStateManager();
66 
67     @Override
initiateUi(Activity activity)68     public void initiateUi(Activity activity) {
69         boolean isPoProvisioning = getUtils().isProfileOwnerAction(getParams().provisioningAction);
70         int titleResId =
71                 isPoProvisioning ? R.string.setup_profile_progress : R.string.setup_device_progress;
72         int layoutResId = getShouldSkipEducationScreens()
73                 ? R.layout.empty_loading_layout
74                 : R.layout.provisioning_progress;
75 
76         CustomizationParams customizationParams =
77                 CustomizationParams.createInstance(getParams(), activity, getUtils());
78         getInitializeLayoutParamsConsumer().initializeLayoutParams(
79                 layoutResId, /* headerResId */ null, customizationParams);
80         activity.setTitle(titleResId);
81 
82         GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout);
83         setupEducationViews(
84                 layout, activity, getShouldSkipEducationScreens(), getProgressLabelResId());
85         if (getUtils().isFinancedDeviceAction(getParams().provisioningAction)) {
86             // make the icon invisible
87             layout.findViewById(R.id.sud_layout_icon).setVisibility(View.INVISIBLE);
88         }
89 
90         Utils.addNextButton(layout, v -> getBridgeCallbacks().onNextButtonClicked());
91         //TODO(b/181323689): Add tests to ProvisioningActivityTest that the button is not
92         // shown for non-DO provisioning flows.
93         if (getUtils().isDeviceOwnerAction(getParams().provisioningAction)) {
94             Utils.addAbortAndResetButton(layout, v -> getBridgeCallbacks().onAbortButtonClicked());
95         }
96         ViewGroup root = activity.findViewById(R.id.sud_layout_template_content);
97         mButtonFooterContainer = getButtonFooterContainer(root);
98 
99         getUtils().onViewMeasured(
100                 mButtonFooterContainer,
101                 view -> onContainerMeasured(
102                         view,
103                         activity,
104                         getBridgeCallbacks()::isProvisioningFinalized));
105     }
106 
onContainerMeasured( View view, Activity activity, Supplier<Boolean> checkIsProvisioningFinalised)107     private void onContainerMeasured(
108             View view,
109             Activity activity,
110             Supplier<Boolean> checkIsProvisioningFinalised) {
111         if (checkIsProvisioningFinalised.get()) {
112             view.setVisibility(View.VISIBLE);
113             return;
114         }
115         getProvisioningProgressLabelContainer(activity).setLayoutParams(
116                 new LinearLayout.LayoutParams(
117                         ViewGroup.LayoutParams.MATCH_PARENT,
118                         view.getHeight()));
119         view.setVisibility(View.GONE);
120     }
121 
122     @Override
onStart(Activity activity)123     public void onStart(Activity activity) {
124         if (!getShouldSkipEducationScreens()) {
125             startTransitionAnimation(activity, getTransitionAnimationCallback());
126         }
127     }
128 
129     @Override
onStop()130     public void onStop() {
131         if (!getShouldSkipEducationScreens()) {
132             endTransitionAnimation();
133         }
134     }
135 
136     @Override
onProvisioningFinalized(Activity activity)137     public void onProvisioningFinalized(Activity activity) {
138         if (!getShouldSkipEducationScreens()) {
139             getProvisioningProgressLabelContainer(activity).setVisibility(View.GONE);
140             mButtonFooterContainer.setVisibility(View.VISIBLE);
141         }
142 
143         if (getShouldSkipEducationScreens()) {
144             getBridgeCallbacks().onNextButtonClicked();
145         }
146     }
147 
148     @Override
shouldShowButtonsWhenPreProvisioningCompletes()149     public boolean shouldShowButtonsWhenPreProvisioningCompletes() {
150         return mTransitionAnimationHelper.areAllTransitionsShown();
151     }
152 
startTransitionAnimation( Activity activity, TransitionAnimationCallback callback)153     private void startTransitionAnimation(
154             Activity activity,
155             TransitionAnimationCallback callback) {
156         final GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout);
157         setupTransitionAnimationHelper(layout, callback);
158         mTransitionAnimationHelper.start();
159     }
160 
endTransitionAnimation()161     private void endTransitionAnimation() {
162         mTransitionAnimationHelper.stop();
163         mTransitionAnimationHelper = null;
164     }
165 
setupTransitionAnimationHelper( GlifLayout layout, TransitionAnimationCallback callback)166     private void setupTransitionAnimationHelper(
167             GlifLayout layout,
168             TransitionAnimationCallback callback) {
169         TextView header = layout.findViewById(R.id.suc_layout_title);
170         TextView description = layout.findViewById(R.id.sud_layout_subtitle);
171         ViewGroup item1 = layout.findViewById(R.id.item1);
172         ViewGroup item2 = layout.findViewById(R.id.item2);
173         LottieAnimationView drawable = layout.findViewById(R.id.animation);
174         ViewGroup drawableContainer = layout.findViewById(R.id.animation_container);
175         Space space1 = layout.findViewById(R.id.space1);
176         Space space2 = layout.findViewById(R.id.space2);
177         AnimationComponents animationComponents =
178                 new AnimationComponents(
179                         header, description, item1, item2, drawable, drawableContainer,
180                         space1, space2);
181 
182         ProvisioningModeWrapperProvider provider = new ProvisioningModeWrapperProvider(getParams());
183         ProvisioningModeWrapper provisioningModeWrapper = provider
184                 .getProvisioningModeWrapper(getProvisioningMode());
185         mTransitionAnimationHelper = new TransitionAnimationHelper(
186                 animationComponents,
187                 callback,
188                 getStateManager(),
189                 new StylerHelper(),
190                 provisioningModeWrapper);
191     }
192 
setupEducationViews( GlifLayout layout, Activity activity, boolean shouldSkipEducationScreens, @StringRes int progressLabelResId)193     private void setupEducationViews(
194             GlifLayout layout,
195             Activity activity,
196             boolean shouldSkipEducationScreens,
197             @StringRes int progressLabelResId) {
198         addProvisioningProgressLabel(activity);
199         if (shouldSkipEducationScreens) {
200             TextView header = layout.findViewById(R.id.suc_layout_title);
201             header.setText(progressLabelResId);
202             getProvisioningProgressLabelContainer(activity).setVisibility(View.GONE);
203         } else {
204             setupProgressLabel(progressLabelResId, activity);
205         }
206     }
207 
addProvisioningProgressLabel(Activity activity)208     private void addProvisioningProgressLabel(Activity activity) {
209         ViewGroup parent = activity.findViewById(R.id.sud_layout_template_content);
210         activity.getLayoutInflater().inflate(R.layout.label_provisioning_progress, parent, true);
211     }
212 
getProvisioningProgressLabelContainer(Activity activity)213     private ViewGroup getProvisioningProgressLabelContainer(Activity activity) {
214         ViewGroup parent = activity.findViewById(R.id.sud_layout_template_content);
215         return parent.findViewById(R.id.provisioning_progress_container);
216     }
217 
218     /**
219      * Returns the relevant progress label and takes care of visibilities to show the correct one.
220      */
setupProgressLabel(@tringRes int progressLabelResId, Activity activity)221     private void setupProgressLabel(@StringRes int progressLabelResId, Activity activity) {
222         TextView progressLabel = getRelevantProgressLabel(activity);
223         DescriptionStyler.applyPartnerCustomizationHeavyStyle(progressLabel);
224         progressLabel.setTextColor(
225                 shouldApplyExtendedPartnerConfig(activity)
226                         ? getUtils().getTextSecondaryColor(activity)
227                         : getUtils().getAccentColor(activity));
228         progressLabel.setText(progressLabelResId);
229         int sidePadding = (int) ContentStyler.getPartnerContentMarginStart(activity);
230         progressLabel.setPadding(sidePadding, /* top= */ 0, sidePadding, /* bottom= */ 0);
231         getProvisioningProgressLabelContainer(activity).setVisibility(View.VISIBLE);
232     }
233 
getRelevantProgressLabel(Activity activity)234     private TextView getRelevantProgressLabel(Activity activity) {
235         ViewGroup parent = (ViewGroup) activity.findViewById(R.id.suc_layout_footer).getParent();
236         TextView provisioningProgressLabel = parent.findViewById(R.id.provisioning_progress);
237         if (provisioningProgressLabel != null) {
238             return provisioningProgressLabel;
239         }
240         TextView leftProgress = parent.findViewById(R.id.provisioning_progress_left);
241         TextView rightProgress = parent.findViewById(R.id.provisioning_progress_right);
242         if (activity.getResources().getBoolean(R.bool.show_progress_label_on_left_side)) {
243             leftProgress.setVisibility(View.VISIBLE);
244             rightProgress.setVisibility(View.INVISIBLE);
245             return leftProgress;
246         }
247         leftProgress.setVisibility(View.INVISIBLE);
248         rightProgress.setVisibility(View.VISIBLE);
249         return rightProgress;
250     }
251 
getButtonFooterContainer(ViewGroup root)252     private ViewGroup getButtonFooterContainer(ViewGroup root) {
253         return (ViewGroup) root.getChildAt(root.getChildCount() - 2);
254     }
255 
builder()256     static Builder builder() {
257         return new AutoValue_ProvisioningActivityBridgeImpl.Builder();
258     }
259 
260     @AutoValue.Builder
261     abstract static class Builder {
setUtils(Utils utils)262         abstract Builder setUtils(Utils utils);
setParams(ProvisioningParams params)263         abstract Builder setParams(ProvisioningParams params);
setProvisioningMode(@rovisioningMode int provisioningMode)264         abstract Builder setProvisioningMode(@ProvisioningMode int provisioningMode);
setProvisioningManager(ProvisioningManager provisioningManager)265         abstract Builder setProvisioningManager(ProvisioningManager provisioningManager);
setTransitionAnimationCallback(TransitionAnimationCallback callback)266         abstract Builder setTransitionAnimationCallback(TransitionAnimationCallback callback);
setInitializeLayoutParamsConsumer( InitializeLayoutConsumerHandler initializeLayoutParamsConsumer)267         abstract Builder setInitializeLayoutParamsConsumer(
268                 InitializeLayoutConsumerHandler initializeLayoutParamsConsumer);
setShouldSkipEducationScreens(boolean shouldSkipEducationScreens)269         abstract Builder setShouldSkipEducationScreens(boolean shouldSkipEducationScreens);
setProgressLabelResId(@tringRes int progressLabelResId)270         abstract Builder setProgressLabelResId(@StringRes int progressLabelResId);
setBridgeCallbacks( ProvisioningActivityBridgeCallbacks callbacks)271         abstract Builder setBridgeCallbacks(
272                 ProvisioningActivityBridgeCallbacks callbacks);
setStateManager(TransitionAnimationStateManager stateManager)273         abstract Builder setStateManager(TransitionAnimationStateManager stateManager);
build()274         abstract ProvisioningActivityBridgeImpl build();
275     }
276 }
277