Add Progress screens

Bug: 270710048
Test: mm & test locally
Change-Id: Ice32cc69765160a25cc4f2ad98bfc2cdc8fd9eb0
diff --git a/DeviceLockController/res/layout/fragment_progress.xml b/DeviceLockController/res/layout/fragment_progress.xml
new file mode 100644
index 0000000..385dec5
--- /dev/null
+++ b/DeviceLockController/res/layout/fragment_progress.xml
@@ -0,0 +1,61 @@
+<!--
+  ~ Copyright (C) 2023 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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_margin="16dp">
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/header"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/progress_bar"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent">
+        <ImageView
+            android:id="@+id/header_icon"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:scaleType="fitCenter"
+            android:contentDescription="@string/header_icon_content_description"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"/>
+        <TextView
+            android:id="@+id/header_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="24dp"
+            android:textSize="32sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/header_icon"/>
+        <TextView
+            android:id="@+id/subheader_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="24dp"
+            android:textSize="16sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/header_text"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+    <ProgressBar
+        android:id="@+id/progress_bar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/header"/>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/DeviceLockController/res/layout/provisioning_activity.xml b/DeviceLockController/res/layout/provisioning_activity.xml
index fb9cb28..7e18124 100644
--- a/DeviceLockController/res/layout/provisioning_activity.xml
+++ b/DeviceLockController/res/layout/provisioning_activity.xml
@@ -20,8 +20,7 @@
               android:layout_height="match_parent"
               android:orientation="vertical">
     <androidx.fragment.app.FragmentContainerView
-        android:id="@+id/provision_info_fragment"
+        android:id="@+id/fragment_container"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:name="com.android.devicelockcontroller.activities.DevicePoliciesFragment"/>
+        android:layout_height="match_parent"/>
 </LinearLayout>
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/activities/DevicePoliciesFragment.java b/DeviceLockController/src/com/android/devicelockcontroller/activities/DevicePoliciesFragment.java
index df2c36d..1bb1f63 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/activities/DevicePoliciesFragment.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/activities/DevicePoliciesFragment.java
@@ -16,11 +16,14 @@
 
 package com.android.devicelockcontroller.activities;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -37,7 +40,7 @@
 /**
  * A screen which lists the polies enforced on the device by the device provider.
  */
-public class DevicePoliciesFragment extends Fragment {
+public final class DevicePoliciesFragment extends Fragment {
 
     private static final String TAG = "DevicePoliciesFragment";
 
@@ -68,27 +71,27 @@
         recyclerView.setAdapter(adapter);
 
         ImageView imageView = view.findViewById(R.id.header_icon);
-        if (imageView == null) {
-            LogUtil.e(TAG, "Could not find header ImageView, should not reach here.");
-            return;
-        }
+        checkNotNull(imageView);
         viewModel.mHeaderDrawableIdLiveData.observe(getViewLifecycleOwner(),
                 imageView::setImageResource);
 
         TextView headerTextView = view.findViewById(R.id.header_text);
-        if (headerTextView == null) {
-            LogUtil.e(TAG, "Could not find header TextView, should not reach here.");
-            return;
-        }
+        checkNotNull(headerTextView);
         viewModel.mHeaderTextIdLiveData.observe(getViewLifecycleOwner(),
                 id -> headerTextView.setText(getString(id, providerName)));
 
         TextView footerTextView = view.findViewById(R.id.footer_text);
-        if (footerTextView == null) {
-            LogUtil.e(TAG, "Could not find footer TextView, should not reach here.");
-            return;
-        }
+        checkNotNull(footerTextView);
         viewModel.mFooterTextIdLiveData.observe(getViewLifecycleOwner(),
                 id -> footerTextView.setText(getText(id)));
+
+        ProvisioningProgressViewModel provisioningProgressViewModel =
+                new ViewModelProvider(requireActivity()).get(ProvisioningProgressViewModel.class);
+        Button button = view.findViewById(R.id.button_next);
+        checkNotNull(button);
+        button.setOnClickListener(
+                v -> provisioningProgressViewModel
+                        .getProvisioningProgressMutableLiveData()
+                        .setValue(ProvisioningProgress.GETTING_DEVICE_READY));
     }
 }
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/activities/ProgressFragment.java b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProgressFragment.java
new file mode 100644
index 0000000..49fb9f2
--- /dev/null
+++ b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProgressFragment.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 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.devicelockcontroller.activities;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.android.devicelockcontroller.R;
+
+/**
+ * A screen which always displays a progress bar.
+ */
+public final class ProgressFragment extends Fragment {
+
+    /** The Bundle key for the resource id of the icon. */
+    private static final String KEY_ICON_ID = "key_icon_id";
+
+    /** The Bundle key for the resource id of the header text. */
+    private static final String KEY_HEADER_TEXT_ID = "key_header_text_id";
+
+    private static final String KEY_SUBHEADER_TEXT_ID = "key_subheader_text_id";
+
+    @Nullable
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater,
+            @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        Bundle args = getArguments();
+        checkNotNull(args);
+        checkArgument(args.containsKey(KEY_ICON_ID));
+        checkArgument(args.containsKey(KEY_HEADER_TEXT_ID));
+
+        View v = inflater.inflate(R.layout.fragment_progress, container, false);
+
+        ImageView headerIconImageView = v.findViewById(R.id.header_icon);
+        checkNotNull(headerIconImageView);
+        headerIconImageView.setImageResource(args.getInt(KEY_ICON_ID));
+
+        TextView headerTextView = v.findViewById(R.id.header_text);
+        checkNotNull(headerTextView);
+        headerTextView.setText(args.getInt(KEY_HEADER_TEXT_ID));
+
+        if (args.containsKey(KEY_SUBHEADER_TEXT_ID)) {
+            TextView subheaderTextView = v.findViewById(R.id.subheader_text);
+            checkNotNull(subheaderTextView);
+            subheaderTextView.setText(args.getInt(KEY_SUBHEADER_TEXT_ID));
+        }
+
+        return v;
+    }
+
+    static ProgressFragment create(int iconId, int headerTextId, int subheaderTextId) {
+        ProgressFragment progressFragment = new ProgressFragment();
+        Bundle bundle = new Bundle();
+        if (iconId != 0) {
+            bundle.putInt(KEY_ICON_ID, iconId);
+        }
+        if (headerTextId != 0) {
+            bundle.putInt(KEY_HEADER_TEXT_ID, headerTextId);
+        }
+        if (subheaderTextId != 0) {
+            bundle.putInt(KEY_SUBHEADER_TEXT_ID, subheaderTextId);
+        }
+        progressFragment.setArguments(bundle);
+        return progressFragment;
+    }
+
+}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningActivity.java b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningActivity.java
index 1fa0fe8..e796bb4 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningActivity.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningActivity.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.lifecycle.ViewModelProvider;
 
 import com.android.devicelockcontroller.R;
 
@@ -32,5 +33,22 @@
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.provisioning_activity);
+
+        ProvisioningProgressViewModel viewModel = new ViewModelProvider(this).get(
+                ProvisioningProgressViewModel.class);
+        viewModel.mProvisioningProgressMutableLiveData.observe(this, progress -> {
+            ProgressFragment progressFragment =
+                    ProgressFragment.create(
+                            progress.mIconId, progress.mHeaderId, progress.mSubheaderId);
+            getSupportFragmentManager()
+                    .beginTransaction()
+                    .replace(R.id.fragment_container, progressFragment)
+                    .commit();
+        });
+
+        getSupportFragmentManager()
+                .beginTransaction()
+                .add(R.id.fragment_container, new DevicePoliciesFragment())
+                .commit();
     }
 }
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgress.java b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgress.java
new file mode 100644
index 0000000..e235d23
--- /dev/null
+++ b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgress.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.devicelockcontroller.activities;
+
+import com.android.devicelockcontroller.R;
+
+/**
+ * Different stages of the provisioning progress.
+ */
+public enum ProvisioningProgress {
+    GETTING_DEVICE_READY(R.drawable.ic_smartphone_24px, R.string.getting_device_ready,
+            R.string.this_may_take_a_few_minutes),
+    INSTALLING_KIOSK_APP(R.drawable.ic_downloading_24px, R.string.installing_kiosk_app),
+    OPENING_KIOSK_APP(R.drawable.ic_open_in_new_24px, R.string.opening_kiosk_app);
+
+    final int mIconId;
+    final int mHeaderId;
+    final int mSubheaderId;
+
+    ProvisioningProgress(int iconId, int headerId) {
+        this(iconId, headerId, 0);
+    }
+
+    ProvisioningProgress(int iconId, int headerId, int subheaderId) {
+        this.mHeaderId = headerId;
+        this.mIconId = iconId;
+        this.mSubheaderId = subheaderId;
+    }
+
+}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgressViewModel.java b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgressViewModel.java
new file mode 100644
index 0000000..826b869
--- /dev/null
+++ b/DeviceLockController/src/com/android/devicelockcontroller/activities/ProvisioningProgressViewModel.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.devicelockcontroller.activities;
+
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+/**
+ * A {@link ViewModel} which provides {@link ProvisioningProgress} to the
+ * {@link ProvisioningActivity}.
+ */
+public final class ProvisioningProgressViewModel extends ViewModel {
+
+    final MutableLiveData<ProvisioningProgress> mProvisioningProgressMutableLiveData;
+
+    public ProvisioningProgressViewModel() {
+        mProvisioningProgressMutableLiveData = new MutableLiveData<>();
+    }
+
+    MutableLiveData<ProvisioningProgress> getProvisioningProgressMutableLiveData() {
+        return mProvisioningProgressMutableLiveData;
+    }
+
+}