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;
+ }
+
+}