blob: d9e572f2c1361f97c67cf24075133e3131a2fd23 [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 android.view.View.ACCESSIBILITY_LIVE_REGION_POLITE;
import static com.google.android.setupdesign.util.ThemeHelper.shouldApplyMaterialYouStyle;
import android.app.Activity;
import android.content.Context;
import android.text.Layout;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Space;
import android.widget.TextView;
import androidx.annotation.StringRes;
import com.android.managedprovisioning.R;
import com.android.managedprovisioning.common.InitializeLayoutConsumerHandler;
import com.android.managedprovisioning.common.StylerHelper;
import com.android.managedprovisioning.common.Utils;
import com.android.managedprovisioning.model.ProvisioningParams;
import com.android.managedprovisioning.provisioning.ProvisioningActivity.ProvisioningMode;
import com.android.managedprovisioning.provisioning.ProvisioningModeWrapperProvider.ProvisioningModeWrapper;
import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.AnimationComponents;
import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.TransitionAnimationCallback;
import com.android.managedprovisioning.provisioning.TransitionAnimationHelper.TransitionAnimationStateManager;
import com.airbnb.lottie.LottieAnimationView;
import com.google.android.setupdesign.GlifLayout;
import com.google.android.setupdesign.util.ContentStyler;
import com.google.android.setupdesign.util.DescriptionStyler;
import com.google.android.setupdesign.util.DeviceHelper;
import com.google.auto.value.AutoValue;
import java.util.function.Supplier;
@AutoValue
abstract class ProvisioningActivityBridgeImpl implements ProvisioningActivityBridge {
private TransitionAnimationHelper mTransitionAnimationHelper;
private ViewGroup mButtonFooterContainer;
private Context mContext;
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();
abstract TransitionAnimationStateManager getStateManager();
@Override
public void initiateUi(Activity activity) {
Context context = activity.getApplicationContext();
CharSequence deviceName = DeviceHelper.getDeviceName(context);
boolean isPoProvisioning = getUtils().isProfileOwnerAction(getParams().provisioningAction);
String title =
isPoProvisioning
? activity.getString(R.string.setup_profile_progress)
: activity.getString(R.string.setup_device_progress, deviceName);
int layoutResId =
getShouldSkipEducationScreens()
? R.layout.empty_loading_layout
: R.layout.provisioning_progress;
getInitializeLayoutParamsConsumer()
.initializeLayoutParams(layoutResId, /* headerResId */ null);
activity.setTitle(title);
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(com.google.android.setupdesign.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(
com.google.android.setupdesign.R.id.sud_layout_template_content);
mButtonFooterContainer = getButtonFooterContainer(root);
mButtonFooterContainer.setAccessibilityLiveRegion(ACCESSIBILITY_LIVE_REGION_POLITE);
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.stop();
mTransitionAnimationHelper = null;
}
private void setupTransitionAnimationHelper(
GlifLayout layout, TransitionAnimationCallback callback) {
TextView header = layout.findViewById(com.google.android.setupdesign.R.id.suc_layout_title);
TextView description =
layout.findViewById(com.google.android.setupdesign.R.id.sud_layout_subtitle);
// No hyphenation split word in header
header.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL);
ViewGroup item1 = layout.findViewById(R.id.item1);
ViewGroup item2 = layout.findViewById(R.id.item2);
LottieAnimationView drawable = layout.findViewById(R.id.animation);
ViewGroup drawableContainer = layout.findViewById(R.id.animation_container);
Space space1 = layout.findViewById(R.id.space1);
Space space2 = layout.findViewById(R.id.space2);
AnimationComponents animationComponents =
new AnimationComponents(
header, description, item1, item2, drawable, drawableContainer, space1,
space2);
ProvisioningModeWrapperProvider provider =
new ProvisioningModeWrapperProvider(getParams());
ProvisioningModeWrapper provisioningModeWrapper =
provider.getProvisioningModeWrapper(getProvisioningMode(),
DeviceHelper.getDeviceName(layout.getContext()));
mTransitionAnimationHelper =
new TransitionAnimationHelper(
animationComponents,
callback,
getStateManager(),
new StylerHelper(),
provisioningModeWrapper);
}
private void setupEducationViews(
GlifLayout layout,
Activity activity,
boolean shouldSkipEducationScreens,
@StringRes int progressLabelResId) {
addProvisioningProgressLabel(activity);
if (shouldSkipEducationScreens) {
TextView header =
layout.findViewById(com.google.android.setupdesign.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(
com.google.android.setupdesign.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(
com.google.android.setupdesign.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(
shouldApplyMaterialYouStyle(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(
com.google.android.setupdesign.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 Builder setStateManager(TransitionAnimationStateManager stateManager);
abstract ProvisioningActivityBridgeImpl build();
}
}