blob: b7f6000a755ab3539c05f9f2563719ab2519e711 [file] [log] [blame]
/*
* 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();
}
}