1 /*
2  * Copyright (C) 2021 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 package com.android.managedprovisioning.common;
17 
18 import static java.util.Objects.requireNonNull;
19 
20 import android.annotation.Nullable;
21 import android.annotation.StringRes;
22 import android.app.Activity;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.view.ViewStub;
26 import android.widget.ImageView;
27 import android.widget.TextView;
28 
29 import com.android.car.setupwizardlib.CarSetupWizardCompatLayout;
30 import com.android.car.setupwizardlib.util.CarOrientationHelper;
31 import com.android.managedprovisioning.R;
32 
33 /**
34  * Sets the layout for screens that's integrated with CarSetupWizard layout. It will have a
35  * hierarchical strucutre with {@code ViewStub}:
36  *
37  * <p> {@code MAIN_LAYOUT_RES_Id} will be the main layout for all provisioning screens. The main
38  * view will have a {@code MAIN_VIEW_RES_ID} which contains a {@code ViewStub} and its resource id
39  * is {@code MAIN_VIEW_STUB_RES_ID}.
40  * <p> Either a double column or a single column layout will be passed into
41  * {@code ViewStub}. This layout should have another {@code ViewStub} with resource id
42  * {@code MAIN_VIEW_STUB_RES_ID}.
43  * <p> Provisioning screen specific layout will be passed into the {@code ViewStub} from the
44  * previous level.
45  */
46 public final class CarSetupWizardLayoutHelper {
47     private static final String TAG = CarSetupWizardLayoutHelper.class.getSimpleName();
48 
49     // Main layout for all provisioning screens.
50     public static final int MAIN_LAYOUT_RES_ID = R.layout.car_layout;
51     // Main layout's main view.
52     private static final int MAIN_VIEW_RES_ID = R.id.car_layout;
53     // Main layout's view stub that will take either single or double column layout.
54     private static final int MAIN_VIEW_STUB_RES_ID = R.id.layout_content_stub;
55     // Main layout's logo view.
56     private static final int TITLE_LOGO_VIEW_RES_ID = R.id.title_logo;
57     // Sub-screen's view stub that will take specific layout for different provisioning screens.
58     private static final int SUB_VIEW_STUB_RES_ID = R.id.sub_content_stub;
59     // Default icon for the provisioning screen header.
60     private static final int ICON_RES_ID =
61             com.android.internal.R.drawable.ic_corp_badge_case;
62 
63     private final Activity mActivity;
64     private CarSetupWizardCompatLayout mLayout;
65 
CarSetupWizardLayoutHelper(Activity activity)66     public CarSetupWizardLayoutHelper(Activity activity) {
67         mActivity = requireNonNull(activity);
68     }
69 
getBaseLayout()70     public CarSetupWizardCompatLayout getBaseLayout() {
71         return mLayout;
72     }
73 
74     /**
75      * Sets the layout for the current Activity with a default main layout.
76      *
77      * @param subLayoutId {@code LayoutRes} for the {@code ViewStub} on the right column of
78      * double column layout or at the bottom of single column layout
79      * @param isDoubleColumnAllowed whether to use double column layout for the sub layout
80      */
setBaseLayout(int subLayoutId, boolean isDoubleColumnAllowed)81     public CarSetupWizardCompatLayout setBaseLayout(int subLayoutId,
82             boolean isDoubleColumnAllowed) {
83         return setBaseLayout(MAIN_LAYOUT_RES_ID, subLayoutId, isDoubleColumnAllowed);
84     }
85 
86     /**
87      * Sets base layout for the current Activity.
88      *
89      * @param mainLayoutId main {@code LayoutRes} to be set for the current Activity
90      * @param subLayoutId {@code LayoutRes} to be passed to {@code ViewStub} in main layout
91      * @param isDoubleColumnAllowed whether there should be single or double column
92      */
setBaseLayout(int mainLayoutId, int subLayoutId, boolean isDoubleColumnAllowed)93     public CarSetupWizardCompatLayout setBaseLayout(int mainLayoutId, int subLayoutId,
94             boolean isDoubleColumnAllowed) {
95         // TODO(b/203732347) enable split-nav support after split-nav cls are merged to sc-dev
96         // boolean isSplitNavLayoutUsed = mLayout.isSplitNavLayoutUsed();
97         return setBaseLayout(MAIN_LAYOUT_RES_ID,
98                 getColumnLayoutResourceId(/* isSplitNavLayoutUsed= */ false,
99                         isDoubleColumnAllowed), subLayoutId);
100     }
101 
102     /**
103      * Sets base layout for the current Activity.
104      *
105      * @param mainLayoutId main {@code LayoutRes} to be set for the current Activity
106      * @param columnLayoutId {@code LayoutRes} to be set withint the main layout
107      * @param subLayoutId {@code LayoutRes} to be passed to {@code ViewStub} in main layout
108      */
setBaseLayout(int mainLayoutId, int columnLayoutId, int subLayoutId)109     public CarSetupWizardCompatLayout setBaseLayout(int mainLayoutId, int columnLayoutId,
110             int subLayoutId) {
111         mActivity.setContentView(mainLayoutId);
112 
113         mLayout = mActivity.findViewById(MAIN_VIEW_RES_ID);
114         mLayout.setBackgroundColor(mActivity.getColor(R.color.background_grey));
115 
116         ViewStub contentLayoutRes = (ViewStub) mLayout.findViewById(MAIN_VIEW_STUB_RES_ID);
117 
118         requireNonNull(contentLayoutRes);
119 
120         contentLayoutRes.setLayoutResource(columnLayoutId);
121         contentLayoutRes.inflate();
122 
123         ViewStub subContentStub = (ViewStub) mLayout.findViewById(SUB_VIEW_STUB_RES_ID);
124         subContentStub.setLayoutResource(subLayoutId);
125         subContentStub.inflate();
126 
127         mLayout.setBackButtonListener(v -> mActivity.onBackPressed());
128         setupDefaultLogo();
129 
130         return mLayout;
131     }
132 
133     /**
134      * Gets the layout resource for the current Activity.
135      *
136      * @return either single column or double column resource id
137      */
getColumnLayoutResourceId(boolean isSplitNavLayoutUsed, boolean isDoubleColumnAllowed)138     public int getColumnLayoutResourceId(boolean isSplitNavLayoutUsed,
139             boolean isDoubleColumnAllowed) {
140 
141         if (isDoubleColumnAllowed && !CarOrientationHelper.isNarrowOrientation(mActivity)) {
142             return isSplitNavLayoutUsed ? R.layout.double_column_gmodel_layout
143                     : R.layout.double_column_layout;
144         }
145         return isSplitNavLayoutUsed ? R.layout.single_column_gmodel_layout
146                 : R.layout.single_column_layout;
147     }
148 
149     /**
150      * Sets the header title and description in {@code CarSetupWizardCompatLayout} for current
151      * activity.
152      */
setHeaderText(int headerResId, int descriptionResId)153     public void setHeaderText(int headerResId, int descriptionResId) {
154         setHeaderTitle(headerResId);
155 
156         TextView description = mActivity.findViewById(R.id.description);
157         description.setText(descriptionResId);
158     }
159 
160     /**
161      * Sets the header title in {@code CarSetupWizardCompatLayout} for current
162      * activity and removes empty description view.
163      */
setHeaderText(int headerResId)164     public void setHeaderText(int headerResId) {
165         setHeaderTitle(headerResId);
166 
167         TextView description = mActivity.findViewById(R.id.description);
168         ViewGroup parent = (ViewGroup) description.getParent();
169         parent.removeView(description);
170     }
171 
setHeaderTitle(int headerResId)172     private void setHeaderTitle(int headerResId) {
173         TextView descriptionTitle = mActivity.findViewById(R.id.description_title);
174         descriptionTitle.setText(headerResId);
175     }
176 
177     /**
178      * Sets up primary tool bar button.
179      *
180      * @param resId {@code StringRes} for the primary toolbar button's text
181      * @param listener  {@code View.OnClickListener} for the primary toolbar button
182      */
setupPrimaryToolbarButton(@tringRes int resId, @Nullable View.OnClickListener listener)183     public void setupPrimaryToolbarButton(@StringRes int resId,
184             @Nullable View.OnClickListener listener) {
185         mLayout.setPrimaryToolbarButtonText(mActivity.getString(resId));
186         mLayout.setPrimaryToolbarButtonListener(listener);
187     }
188 
189     /**
190      * Sets the icon for the header.
191      */
setupLogo(int logoResId)192     public void setupLogo(int logoResId) {
193         ImageView logo = mLayout.findViewById(TITLE_LOGO_VIEW_RES_ID);
194         logo.setImageResource(logoResId);
195     }
196 
197     /**
198      * Sets the default icon for the header.
199      */
setupDefaultLogo()200     public void setupDefaultLogo() {
201         setupLogo(ICON_RES_ID);
202     }
203 }
204