1 /*
2  * Copyright 2016, 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.preprovisioning.terms;
17 
18 import static android.view.View.TEXT_ALIGNMENT_TEXT_START;
19 
20 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_TERMS_ACTIVITY_TIME_MS;
21 import static com.android.internal.util.Preconditions.checkNotNull;
22 
23 import static com.google.android.setupdesign.util.ThemeHelper.shouldApplyExtendedPartnerConfig;
24 
25 import static java.util.Objects.requireNonNull;
26 
27 import android.content.Context;
28 import android.content.Intent;
29 import android.os.Bundle;
30 import android.view.ContextMenu;
31 import android.view.MenuItem;
32 import android.view.View;
33 import android.widget.LinearLayout;
34 import android.widget.TextView;
35 
36 import androidx.annotation.VisibleForTesting;
37 import androidx.appcompat.app.AppCompatActivity;
38 import androidx.appcompat.widget.Toolbar;
39 import androidx.lifecycle.ViewModelProvider;
40 import androidx.recyclerview.widget.LinearLayoutManager;
41 import androidx.recyclerview.widget.RecyclerView;
42 
43 import com.android.managedprovisioning.R;
44 import com.android.managedprovisioning.analytics.MetricsWriterFactory;
45 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
46 import com.android.managedprovisioning.common.AccessibilityContextMenuMaker;
47 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
48 import com.android.managedprovisioning.common.SettingsFacade;
49 import com.android.managedprovisioning.common.SetupGlifLayoutActivity;
50 import com.android.managedprovisioning.common.StylerHelper;
51 import com.android.managedprovisioning.common.ThemeHelper;
52 import com.android.managedprovisioning.common.ThemeHelper.DefaultNightModeChecker;
53 import com.android.managedprovisioning.common.ThemeHelper.DefaultSetupWizardBridge;
54 import com.android.managedprovisioning.common.Utils;
55 import com.android.managedprovisioning.model.ProvisioningParams;
56 import com.android.managedprovisioning.preprovisioning.terms.TermsViewModel.TermsViewModelFactory;
57 import com.android.managedprovisioning.preprovisioning.terms.adapters.TermsListAdapter;
58 
59 import java.util.List;
60 import java.util.function.BiFunction;
61 
62 /**
63  * Activity responsible for displaying the Terms screen
64  */
65 public class TermsActivity extends SetupGlifLayoutActivity implements
66         TermsListAdapter.TermsBridge {
67     private final AccessibilityContextMenuMaker mContextMenuMaker;
68     private final SettingsFacade mSettingsFacade;
69     private ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker;
70     private final BiFunction<AppCompatActivity, ProvisioningParams, TermsViewModel>
71             mViewModelFetcher;
72     private TermsViewModel mViewModel;
73     private final StylerHelper mStylerHelper;
74 
75     @SuppressWarnings("unused")
TermsActivity()76     public TermsActivity() {
77         this(
78                 /* contextMenuMaker= */ null,
79                 new SettingsFacade(),
80                 new StylerHelper(),
81                 (activity, params) -> {
82                     final TermsViewModelFactory factory =
83                             new TermsViewModelFactory(activity.getApplication(), params);
84                     return new ViewModelProvider(activity, factory).get(TermsViewModel.class);
85                 });
86     }
87 
88     @VisibleForTesting
TermsActivity(AccessibilityContextMenuMaker contextMenuMaker, SettingsFacade settingsFacade, StylerHelper stylerHelper, BiFunction<AppCompatActivity, ProvisioningParams, TermsViewModel> viewModelFetcher)89     TermsActivity(AccessibilityContextMenuMaker contextMenuMaker, SettingsFacade settingsFacade,
90             StylerHelper stylerHelper,
91             BiFunction<AppCompatActivity, ProvisioningParams, TermsViewModel> viewModelFetcher) {
92         super(new Utils(), settingsFacade,
93                 new ThemeHelper(new DefaultNightModeChecker(), new DefaultSetupWizardBridge()));
94 
95         mContextMenuMaker =
96                 contextMenuMaker != null ? contextMenuMaker : new AccessibilityContextMenuMaker(
97                         this);
98         mSettingsFacade = requireNonNull(settingsFacade);
99         mViewModelFetcher = requireNonNull(viewModelFetcher);
100         mStylerHelper = requireNonNull(stylerHelper);
101     }
102 
103     @Override
onCreate(Bundle savedInstanceState)104     protected void onCreate(Bundle savedInstanceState) {
105         super.onCreate(savedInstanceState);
106         setContentView(R.layout.terms_screen);
107         setTitle(R.string.terms);
108 
109         ProvisioningParams params = checkNotNull(
110                 getIntent().getParcelableExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS));
111         mViewModel = mViewModelFetcher.apply(this, params);
112         List<TermsDocument> terms = mViewModel.getTerms();
113 
114         initializeUiForHandhelds(terms);
115 
116         mProvisioningAnalyticsTracker = new ProvisioningAnalyticsTracker(
117                 MetricsWriterFactory.getMetricsWriter(this, mSettingsFacade),
118                 new ManagedProvisioningSharedPreferences(getApplicationContext()));
119         mProvisioningAnalyticsTracker.logNumberOfTermsDisplayed(this, terms.size());
120     }
121 
initializeUiForHandhelds(List<TermsDocument> terms)122     private void initializeUiForHandhelds(List<TermsDocument> terms) {
123         setupHeader();
124         setupRecyclerView();
125         setupToolbar();
126         setupTermsListForHandhelds(terms);
127     }
128 
setupHeader()129     private void setupHeader() {
130         if (!shouldApplyExtendedPartnerConfig(this)) {
131             return;
132         }
133         TextView header = findViewById(R.id.header);
134         header.setVisibility(View.VISIBLE);
135         header.setText(R.string.terms);
136         mStylerHelper.applyHeaderStyling(header,
137                 new LinearLayout.LayoutParams(header.getLayoutParams()));
138         header.setTextAlignment(TEXT_ALIGNMENT_TEXT_START);
139     }
140 
setupRecyclerView()141     private void setupRecyclerView() {
142         final RecyclerView recyclerView = findViewById(R.id.terms_container);
143         if (recyclerView.getItemDecorationCount() > 0) {
144             recyclerView.removeItemDecorationAt(/* index= */ 0);
145         }
146     }
147 
setupToolbar()148     private void setupToolbar() {
149         Toolbar toolbar = findViewById(R.id.toolbar);
150         toolbar.setNavigationContentDescription(R.string.navigation_button_description);
151         toolbar.setNavigationIcon(getDrawable(R.drawable.ic_arrow_back_24dp));
152         toolbar.setNavigationOnClickListener(v ->
153                 getTransitionHelper().finishActivity(TermsActivity.this));
154         if (!shouldApplyExtendedPartnerConfig(this)) {
155             toolbar.setTitle(R.string.terms);
156         }
157     }
158 
setupTermsListForHandhelds(List<TermsDocument> terms)159     private void setupTermsListForHandhelds(List<TermsDocument> terms) {
160         RecyclerView recyclerView = findViewById(R.id.terms_container);
161         recyclerView.setLayoutManager(new LinearLayoutManager(/* context= */ this));
162         recyclerView.setAdapter(new TermsListAdapter(
163                 this,
164                 mViewModel.getGeneralDisclaimer(),
165                 terms,
166                 getLayoutInflater(),
167                 new AccessibilityContextMenuMaker(this),
168                 this,
169                 mUtils,
170                 mStylerHelper));
171     }
172 
173     @Override
onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)174     public void onCreateContextMenu(ContextMenu menu, View v,
175             ContextMenu.ContextMenuInfo menuInfo) {
176         super.onCreateContextMenu(menu, v, menuInfo);
177         if (v instanceof TextView) {
178             mContextMenuMaker.populateMenuContent(menu, (TextView) v);
179         }
180     }
181 
182     @Override
onOptionsItemSelected(MenuItem item)183     public boolean onOptionsItemSelected(MenuItem item) {
184         if (item.getItemId() == android.R.id.home) {
185             onBackPressed();
186             return true;
187         }
188         return super.onOptionsItemSelected(item);
189     }
190 
191     @Override
onDestroy()192     public void onDestroy() {
193         mProvisioningAnalyticsTracker.logNumberOfTermsRead(
194                 this, mViewModel.getNumberOfReadTerms());
195         super.onDestroy();
196     }
197 
198     @Override
getMetricsCategory()199     protected int getMetricsCategory() {
200         return PROVISIONING_TERMS_ACTIVITY_TIME_MS;
201     }
202 
203     @Override
isTermExpanded(int groupPosition)204     public boolean isTermExpanded(int groupPosition) {
205         return mViewModel.isTermExpanded(groupPosition);
206     }
207 
208     @Override
onTermExpanded(int groupPosition, boolean expanded)209     public void onTermExpanded(int groupPosition, boolean expanded) {
210         mViewModel.setTermExpanded(groupPosition, expanded);
211     }
212 
213     @Override
onLinkClicked(Intent intent)214     public void onLinkClicked(Intent intent) {
215         getTransitionHelper().startActivityWithTransition(this, intent);
216     }
217 
218     @Override
shouldSetupDynamicColors()219     protected boolean shouldSetupDynamicColors() {
220         Context context = getApplicationContext();
221         return !mSettingsFacade.isDeferredSetup(context)
222                 && !mSettingsFacade.isDuringSetupWizard(context);
223     }
224 }
225