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 
17 package com.android.car.debuggingrestrictioncontroller.ui.token;
18 
19 import android.app.Activity;
20 import android.os.Bundle;
21 import android.os.UserManager;
22 import android.text.Html;
23 import android.text.Spanned;
24 import android.util.Log;
25 import android.view.View;
26 import android.widget.Button;
27 import android.widget.ProgressBar;
28 import android.widget.TextView;
29 import androidx.annotation.NonNull;
30 import androidx.annotation.VisibleForTesting;
31 import androidx.appcompat.app.AppCompatActivity;
32 import androidx.lifecycle.Observer;
33 import androidx.test.espresso.idling.CountingIdlingResource;
34 import com.android.car.debuggingrestrictioncontroller.R;
35 import com.google.common.collect.ImmutableSet;
36 import com.google.firebase.auth.FirebaseAuth;
37 import java.util.HashMap;
38 import java.util.Map;
39 import java.util.Set;
40 
41 public class TokenActivity extends AppCompatActivity {
42 
43   private static final String TAG = TokenActivity.class.getSimpleName();
44   private static final Set<String> SUPPORTED_RESTRICTIONS =
45       ImmutableSet.of(UserManager.DISALLOW_DEBUGGING_FEATURES);
46   private final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
47 
48   @VisibleForTesting
49   private final CountingIdlingResource idlingResource = new CountingIdlingResource(TAG);
50 
51   private final TokenViewModel tokenViewModel = new TokenViewModel();
52   private UserManager userManager;
53   private Button agreeButton;
54   private Button disagreeButton;
55 
56   @VisibleForTesting
getIdlingResource()57   public CountingIdlingResource getIdlingResource() {
58     return idlingResource;
59   }
60 
61   @Override
onCreate(Bundle savedInstanceState)62   public void onCreate(Bundle savedInstanceState) {
63     super.onCreate(savedInstanceState);
64     userManager = getSystemService(UserManager.class);
65     setContentView(R.layout.activity_token);
66 
67     final TextView agreementTextView = findViewById(R.id.agreement);
68     final ProgressBar loadingProgressBar = findViewById(R.id.token_loading);
69     agreeButton = findViewById(R.id.agree);
70     disagreeButton = findViewById(R.id.disagree);
71 
72     Spanned agreementString =
73         Html.fromHtml(getString(R.string.agreement_text), Html.FROM_HTML_MODE_LEGACY);
74     agreementTextView.setText(agreementString);
75 
76     tokenViewModel
77         .getTokenResult()
78         .observe(
79             this,
80             new Observer<TokenResult>() {
81               @Override
82               public void onChanged(@NonNull TokenResult result) {
83                 loadingProgressBar.setVisibility(View.GONE);
84                 if (!idlingResource.isIdleNow()) {
85                   idlingResource.decrement();
86                 }
87                 if (result.getError() != null) {
88                   setResult(Activity.RESULT_CANCELED);
89                   finish();
90                 }
91                 if (result.getSuccess() != null) {
92 
93                   Log.d(TAG, "Message: " + result.getSuccess().getMessage());
94                   HashMap<String, Boolean> approvedRestrictions =
95                       result.getSuccess().getApprovedRestrictions();
96                   approvedRestrictions
97                       .entrySet()
98                       .removeIf(entry -> !SUPPORTED_RESTRICTIONS.contains(entry.getKey()));
99                   try {
100                     approvedRestrictions
101                         .entrySet()
102                         .forEach(
103                             entry ->
104                                 userManager.setUserRestriction(entry.getKey(), entry.getValue()));
105                     setResult(Activity.RESULT_OK);
106                   } catch (SecurityException e) {
107                     Log.e(TAG, "This app requires the MANAGE_USERS permission");
108                     setResult(Activity.RESULT_CANCELED);
109                   }
110                   finish();
111                 }
112               }
113             });
114 
115     agreeButton.setOnClickListener(
116         new View.OnClickListener() {
117           @Override
118           public void onClick(View v) {
119             idlingResource.increment();
120             Map<String, Object> query = new HashMap<>();
121             loadingProgressBar.setVisibility(View.VISIBLE);
122             tokenViewModel.requestAccessToken(query);
123           }
124         });
125 
126     disagreeButton.setOnClickListener(
127         new View.OnClickListener() {
128           @Override
129           public void onClick(View v) {
130             setResult(Activity.RESULT_CANCELED);
131             finishAffinity();
132           }
133         });
134   }
135 
136   @Override
onResume()137   protected void onResume() {
138     updateButtonState();
139     super.onResume();
140   }
141 
updateButtonState()142   private void updateButtonState() {
143     if (firebaseAuth.getCurrentUser() == null) {
144       agreeButton.setEnabled(false);
145       setResult(Activity.RESULT_CANCELED);
146       finish();
147     } else {
148       agreeButton.setEnabled(true);
149     }
150   }
151 }
152