1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.privatespace;
18 
19 import static android.text.Layout.BREAK_STRATEGY_SIMPLE;
20 
21 import static com.android.settings.privatespace.PrivateSpaceSetupActivity.EXTRA_ACTION_TYPE;
22 import static com.android.settings.privatespace.PrivateSpaceSetupActivity.SET_LOCK_ACTION;
23 
24 import android.app.settings.SettingsEnums;
25 import android.content.Intent;
26 import android.os.Bundle;
27 import android.os.UserHandle;
28 import android.util.Log;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 
33 import androidx.activity.OnBackPressedCallback;
34 import androidx.annotation.Nullable;
35 import androidx.navigation.fragment.NavHostFragment;
36 
37 import com.android.settings.R;
38 import com.android.settings.core.InstrumentedFragment;
39 import com.android.settingslib.widget.LottieColorUtils;
40 
41 import com.airbnb.lottie.LottieAnimationView;
42 import com.google.android.setupcompat.template.FooterBarMixin;
43 import com.google.android.setupcompat.template.FooterButton;
44 import com.google.android.setupdesign.GlifLayout;
45 
46 /**
47  * Fragment that provides an option to user to choose between the existing screen lock or set a
48  * separate private profile lock.
49  */
50 public class PrivateSpaceSetLockFragment extends InstrumentedFragment {
51     private static final String TAG = "PrivateSpaceSetLockFrag";
52     private static final int HEADER_TEXT_MAX_LINES = 4;
53 
54     @Override
onCreateView( LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)55     public View onCreateView(
56             LayoutInflater inflater,
57             @Nullable ViewGroup container,
58             @Nullable Bundle savedInstanceState) {
59         if (!android.os.Flags.allowPrivateProfile()
60                 || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
61             return null;
62         }
63         GlifLayout rootView =
64                 (GlifLayout)
65                         inflater.inflate(R.layout.private_space_setlock_screen, container, false);
66         rootView.getHeaderTextView().setBreakStrategy(BREAK_STRATEGY_SIMPLE);
67         rootView.getHeaderTextView().setMaxLines(HEADER_TEXT_MAX_LINES);
68         final FooterBarMixin mixin = rootView.getMixin(FooterBarMixin.class);
69         mixin.setPrimaryButton(
70                 new FooterButton.Builder(getContext())
71                         .setText(R.string.private_space_set_lock_label)
72                         .setListener(onClickNewLock())
73                         .setButtonType(FooterButton.ButtonType.NEXT)
74                         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
75                         .build());
76         mixin.setSecondaryButton(
77                 new FooterButton.Builder(getContext())
78                         .setText(R.string.private_space_use_screenlock_label)
79                         .setListener(onClickUse())
80                         .setButtonType(FooterButton.ButtonType.SKIP)
81                         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary)
82                         .build());
83         OnBackPressedCallback callback =
84                 new OnBackPressedCallback(true /* enabled by default */) {
85                     @Override
86                     public void handleOnBackPressed() {
87                         // Handle the back button event. We intentionally don't want to allow back
88                         // button to work in this screen during the setup flow.
89                     }
90                 };
91         requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
92         LottieAnimationView lottieAnimationView = rootView.findViewById(R.id.lottie_animation);
93         LottieColorUtils.applyDynamicColors(getContext(), lottieAnimationView);
94 
95         return rootView;
96     }
97 
98     @Override
getMetricsCategory()99     public int getMetricsCategory() {
100         return SettingsEnums.PRIVATE_SPACE_SETUP_LOCK;
101     }
102 
onClickUse()103     private View.OnClickListener onClickUse() {
104         return v -> {
105             mMetricsFeatureProvider.action(
106                     getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_USE_SCREEN_LOCK);
107             // Simply Use default screen lock. No need to handle
108             NavHostFragment.findNavController(PrivateSpaceSetLockFragment.this)
109                     .navigate(R.id.action_pre_finish_delay_fragment);
110         };
111     }
112 
onClickNewLock()113     private View.OnClickListener onClickNewLock() {
114         return v -> {
115             mMetricsFeatureProvider.action(
116                     getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_NEW_LOCK);
117             launchActivityForAction(SET_LOCK_ACTION);
118         };
119     }
120 
121     private void launchActivityForAction(int action) {
122         UserHandle userHandle =
123                 PrivateSpaceMaintainer.getInstance(getActivity()).getPrivateProfileHandle();
124         if (userHandle != null) {
125             Intent intent = new Intent(getContext(), PrivateProfileContextHelperActivity.class);
126             intent.putExtra(EXTRA_ACTION_TYPE, action);
127             Log.i(TAG, "Start separate lock setup for private profile");
128             getActivity().startActivityForResultAsUser(intent, action, userHandle);
129         } else {
130             Log.w(TAG, "Private profile user handle is null");
131         }
132     }
133 }
134