| /* |
| * Copyright (C) 2021 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.android.managedprovisioning.provisioning; |
| |
| import static com.google.android.setupdesign.util.ThemeHelper.shouldApplyExtendedPartnerConfig; |
| |
| import android.app.Activity; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.ImageView; |
| import android.widget.LinearLayout; |
| import android.widget.TextView; |
| |
| import androidx.annotation.StringRes; |
| |
| import com.android.managedprovisioning.R; |
| import com.android.managedprovisioning.common.InitializeLayoutConsumerHandler; |
| import com.android.managedprovisioning.common.Utils; |
| import com.android.managedprovisioning.model.CustomizationParams; |
| import com.android.managedprovisioning.model.ProvisioningParams; |
| import com.android.managedprovisioning.provisioning.ProvisioningActivity.ProvisioningMode; |
| import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.AnimationComponents; |
| import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.TransitionAnimationCallback; |
| |
| import com.google.android.setupdesign.GlifLayout; |
| import com.google.android.setupdesign.util.ContentStyler; |
| import com.google.android.setupdesign.util.DescriptionStyler; |
| import com.google.auto.value.AutoValue; |
| |
| import java.util.function.Supplier; |
| |
| @AutoValue |
| abstract class ProvisioningActivityBridgeImpl implements ProvisioningActivityBridge { |
| |
| private TransitionAnimationHelper mTransitionAnimationHelper; |
| private ViewGroup mButtonFooterContainer; |
| |
| abstract Utils getUtils(); |
| abstract ProvisioningParams getParams(); |
| abstract @ProvisioningMode int getProvisioningMode(); |
| abstract ProvisioningManager getProvisioningManager(); |
| abstract TransitionAnimationCallback getTransitionAnimationCallback(); |
| abstract InitializeLayoutConsumerHandler getInitializeLayoutParamsConsumer(); |
| abstract boolean getShouldSkipEducationScreens(); |
| abstract @StringRes int getProgressLabelResId(); |
| abstract ProvisioningActivityBridgeCallbacks getBridgeCallbacks(); |
| |
| @Override |
| public void initiateUi(Activity activity) { |
| boolean isPoProvisioning = getUtils().isProfileOwnerAction(getParams().provisioningAction); |
| int titleResId = |
| isPoProvisioning ? R.string.setup_profile_progress : R.string.setup_device_progress; |
| int layoutResId = getShouldSkipEducationScreens() |
| ? R.layout.empty_loading_layout |
| : R.layout.provisioning_progress; |
| |
| CustomizationParams customizationParams = |
| CustomizationParams.createInstance(getParams(), activity, getUtils()); |
| getInitializeLayoutParamsConsumer().initializeLayoutParams( |
| layoutResId, /* headerResId */ null, customizationParams); |
| activity.setTitle(titleResId); |
| |
| GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout); |
| setupEducationViews( |
| layout, activity, getShouldSkipEducationScreens(), getProgressLabelResId()); |
| if (getUtils().isFinancedDeviceAction(getParams().provisioningAction)) { |
| // make the icon invisible |
| layout.findViewById(R.id.sud_layout_icon).setVisibility(View.INVISIBLE); |
| } |
| |
| Utils.addNextButton(layout, v -> getBridgeCallbacks().onNextButtonClicked()); |
| //TODO(b/181323689): Add tests to ProvisioningActivityTest that the button is not |
| // shown for non-DO provisioning flows. |
| if (getUtils().isDeviceOwnerAction(getParams().provisioningAction)) { |
| Utils.addAbortAndResetButton(layout, v -> getBridgeCallbacks().onAbortButtonClicked()); |
| } |
| ViewGroup root = activity.findViewById(R.id.sud_layout_template_content); |
| mButtonFooterContainer = getButtonFooterContainer(root); |
| |
| getUtils().onViewMeasured( |
| mButtonFooterContainer, |
| view -> onContainerMeasured( |
| view, |
| activity, |
| getBridgeCallbacks()::isProvisioningFinalized)); |
| } |
| |
| private void onContainerMeasured( |
| View view, |
| Activity activity, |
| Supplier<Boolean> checkIsProvisioningFinalised) { |
| if (checkIsProvisioningFinalised.get()) { |
| view.setVisibility(View.VISIBLE); |
| return; |
| } |
| getProvisioningProgressLabelContainer(activity).setLayoutParams( |
| new LinearLayout.LayoutParams( |
| ViewGroup.LayoutParams.MATCH_PARENT, |
| view.getHeight())); |
| view.setVisibility(View.GONE); |
| } |
| |
| @Override |
| public void onStart(Activity activity) { |
| if (!getShouldSkipEducationScreens()) { |
| startTransitionAnimation(activity, getTransitionAnimationCallback()); |
| } |
| } |
| |
| @Override |
| public void onStop() { |
| if (!getShouldSkipEducationScreens()) { |
| endTransitionAnimation(); |
| } |
| } |
| |
| @Override |
| public void onProvisioningFinalized(Activity activity) { |
| if (!getShouldSkipEducationScreens()) { |
| getProvisioningProgressLabelContainer(activity).setVisibility(View.GONE); |
| mButtonFooterContainer.setVisibility(View.VISIBLE); |
| } |
| |
| if (getShouldSkipEducationScreens()) { |
| getBridgeCallbacks().onNextButtonClicked(); |
| } |
| } |
| |
| @Override |
| public boolean shouldShowButtonsWhenPreProvisioningCompletes() { |
| return mTransitionAnimationHelper.areAllTransitionsShown(); |
| } |
| |
| private void startTransitionAnimation(Activity activity, TransitionAnimationCallback callback) { |
| final GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout); |
| setupTransitionAnimationHelper(layout, callback); |
| mTransitionAnimationHelper.start(); |
| } |
| |
| private void endTransitionAnimation() { |
| mTransitionAnimationHelper.clean(); |
| mTransitionAnimationHelper = null; |
| } |
| |
| private void setupTransitionAnimationHelper( |
| GlifLayout layout, |
| TransitionAnimationCallback callback) { |
| TextView header = layout.findViewById(R.id.suc_layout_title); |
| TextView description = layout.findViewById(R.id.sud_layout_subtitle); |
| ViewGroup item1 = layout.findViewById(R.id.item1); |
| ViewGroup item2 = layout.findViewById(R.id.item2); |
| ImageView drawable = layout.findViewById(R.id.animation); |
| ViewGroup drawableContainer = layout.findViewById(R.id.animation_container); |
| AnimationComponents animationComponents = |
| new AnimationComponents( |
| header, description, item1, item2, drawable, drawableContainer); |
| mTransitionAnimationHelper = new TransitionAnimationHelper(getProvisioningMode(), |
| /* adminCanGrantSensorsPermissions= */ |
| !getParams().deviceOwnerPermissionGrantOptOut, |
| animationComponents, |
| callback, |
| getProvisioningManager().getCurrentTransitionAnimation()); |
| } |
| |
| private void setupEducationViews( |
| GlifLayout layout, |
| Activity activity, |
| boolean shouldSkipEducationScreens, |
| @StringRes int progressLabelResId) { |
| addProvisioningProgressLabel(activity); |
| if (shouldSkipEducationScreens) { |
| TextView header = layout.findViewById(R.id.suc_layout_title); |
| header.setText(progressLabelResId); |
| getProvisioningProgressLabelContainer(activity).setVisibility(View.GONE); |
| } else { |
| setupProgressLabel(progressLabelResId, activity); |
| } |
| } |
| |
| private void addProvisioningProgressLabel(Activity activity) { |
| ViewGroup parent = activity.findViewById(R.id.sud_layout_template_content); |
| activity.getLayoutInflater().inflate(R.layout.label_provisioning_progress, parent, true); |
| } |
| |
| private ViewGroup getProvisioningProgressLabelContainer(Activity activity) { |
| ViewGroup parent = activity.findViewById(R.id.sud_layout_template_content); |
| return parent.findViewById(R.id.provisioning_progress_container); |
| } |
| |
| /** |
| * Returns the relevant progress label and takes care of visibilities to show the correct one. |
| */ |
| private void setupProgressLabel(@StringRes int progressLabelResId, Activity activity) { |
| TextView progressLabel = getRelevantProgressLabel(activity); |
| DescriptionStyler.applyPartnerCustomizationHeavyStyle(progressLabel); |
| progressLabel.setTextColor( |
| shouldApplyExtendedPartnerConfig(activity) |
| ? getUtils().getTextSecondaryColor(activity) |
| : getUtils().getAccentColor(activity)); |
| progressLabel.setText(progressLabelResId); |
| int sidePadding = (int) ContentStyler.getPartnerContentMarginStart(activity); |
| progressLabel.setPadding(sidePadding, /* top= */ 0, sidePadding, /* bottom= */ 0); |
| getProvisioningProgressLabelContainer(activity).setVisibility(View.VISIBLE); |
| } |
| |
| private TextView getRelevantProgressLabel(Activity activity) { |
| ViewGroup parent = (ViewGroup) activity.findViewById(R.id.suc_layout_footer).getParent(); |
| TextView provisioningProgressLabel = parent.findViewById(R.id.provisioning_progress); |
| if (provisioningProgressLabel != null) { |
| return provisioningProgressLabel; |
| } |
| TextView leftProgress = parent.findViewById(R.id.provisioning_progress_left); |
| TextView rightProgress = parent.findViewById(R.id.provisioning_progress_right); |
| if (activity.getResources().getBoolean(R.bool.show_progress_label_on_left_side)) { |
| leftProgress.setVisibility(View.VISIBLE); |
| rightProgress.setVisibility(View.INVISIBLE); |
| return leftProgress; |
| } |
| leftProgress.setVisibility(View.INVISIBLE); |
| rightProgress.setVisibility(View.VISIBLE); |
| return rightProgress; |
| } |
| |
| private ViewGroup getButtonFooterContainer(ViewGroup root) { |
| return (ViewGroup) root.getChildAt(root.getChildCount() - 2); |
| } |
| |
| static Builder builder() { |
| return new AutoValue_ProvisioningActivityBridgeImpl.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setUtils(Utils utils); |
| abstract Builder setParams(ProvisioningParams params); |
| abstract Builder setProvisioningMode(@ProvisioningMode int provisioningMode); |
| abstract Builder setProvisioningManager(ProvisioningManager provisioningManager); |
| abstract Builder setTransitionAnimationCallback(TransitionAnimationCallback callback); |
| abstract Builder setInitializeLayoutParamsConsumer( |
| InitializeLayoutConsumerHandler initializeLayoutParamsConsumer); |
| abstract Builder setShouldSkipEducationScreens(boolean shouldSkipEducationScreens); |
| abstract Builder setProgressLabelResId(@StringRes int progressLabelResId); |
| abstract Builder setBridgeCallbacks( |
| ProvisioningActivityBridgeCallbacks callbacks); |
| abstract ProvisioningActivityBridgeImpl build(); |
| } |
| } |