1 /*
2  * Copyright (C) 2013 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.wifi;
18 
19 import android.app.Dialog;
20 import android.app.settings.SettingsEnums;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.net.wifi.WifiManager;
25 import android.os.Bundle;
26 import android.os.UserManager;
27 import android.text.TextUtils;
28 import android.util.EventLog;
29 import android.util.Log;
30 import android.view.WindowManager;
31 
32 import androidx.annotation.VisibleForTesting;
33 import androidx.appcompat.app.AlertDialog;
34 import androidx.fragment.app.DialogFragment;
35 import androidx.fragment.app.FragmentActivity;
36 
37 import com.android.settings.R;
38 import com.android.settings.Utils;
39 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
40 import com.android.settingslib.wifi.WifiPermissionChecker;
41 
42 /** This activity requests users permission to allow scanning even when Wi-Fi is turned off */
43 public class WifiScanModeActivity extends FragmentActivity {
44     private static final String TAG = "WifiScanModeActivity";
45     private DialogFragment mDialog;
46     @VisibleForTesting String mApp;
47     @VisibleForTesting WifiPermissionChecker mWifiPermissionChecker;
48 
49     @Override
onCreate(Bundle savedInstanceState)50     protected void onCreate(Bundle savedInstanceState) {
51         super.onCreate(savedInstanceState);
52         getWindow()
53                 .addSystemFlags(
54                         WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
55         Intent intent = getIntent();
56         if (savedInstanceState == null) {
57             if (intent != null
58                     && WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.equals(
59                             intent.getAction())) {
60                 refreshAppLabel();
61             } else {
62                 finish();
63                 return;
64             }
65         } else {
66             mApp = savedInstanceState.getString("app");
67         }
68         createDialog();
69     }
70 
71     @VisibleForTesting
refreshAppLabel()72     void refreshAppLabel() {
73         if (mWifiPermissionChecker == null) {
74             mWifiPermissionChecker = new WifiPermissionChecker(this);
75         }
76         String packageName = mWifiPermissionChecker.getLaunchedPackage();
77         if (TextUtils.isEmpty(packageName)) {
78             mApp = null;
79             return;
80         }
81         mApp = Utils.getApplicationLabel(getApplicationContext(), packageName).toString();
82     }
83 
84     @VisibleForTesting
createDialog()85     void createDialog() {
86         if (isGuestUser(getApplicationContext())) {
87             Log.e(TAG, "Guest user is not allowed to configure Wi-Fi Scan Mode!");
88             EventLog.writeEvent(0x534e4554, "235601169", -1 /* UID */, "User is a guest");
89             finish();
90             return;
91         }
92 
93         if (!isWifiScanModeConfigAllowed(getApplicationContext())) {
94             Log.e(TAG, "This user is not allowed to configure Wi-Fi Scan Mode!");
95             finish();
96             return;
97         }
98 
99         if (mDialog == null) {
100             mDialog = AlertDialogFragment.newInstance(mApp);
101             mDialog.show(getSupportFragmentManager(), "dialog");
102         }
103     }
104 
dismissDialog()105     private void dismissDialog() {
106         if (mDialog != null) {
107             mDialog.dismiss();
108             mDialog = null;
109         }
110     }
111 
doPositiveClick()112     private void doPositiveClick() {
113         getApplicationContext().getSystemService(WifiManager.class).setScanAlwaysAvailable(true);
114         setResult(RESULT_OK);
115         finish();
116     }
117 
doNegativeClick()118     private void doNegativeClick() {
119         setResult(RESULT_CANCELED);
120         finish();
121     }
122 
123     @Override
onSaveInstanceState(Bundle outState)124     public void onSaveInstanceState(Bundle outState) {
125         super.onSaveInstanceState(outState);
126         outState.putString("app", mApp);
127     }
128 
129     @Override
onPause()130     public void onPause() {
131         super.onPause();
132         dismissDialog();
133     }
134 
onResume()135     public void onResume() {
136         super.onResume();
137         createDialog();
138     }
139 
140     public static class AlertDialogFragment extends InstrumentedDialogFragment {
newInstance(String app)141         static AlertDialogFragment newInstance(String app) {
142             AlertDialogFragment frag = new AlertDialogFragment(app);
143             return frag;
144         }
145 
146         private final String mApp;
147 
AlertDialogFragment(String app)148         public AlertDialogFragment(String app) {
149             super();
150             mApp = app;
151         }
152 
AlertDialogFragment()153         public AlertDialogFragment() {
154             super();
155             mApp = null;
156         }
157 
158         @Override
getMetricsCategory()159         public int getMetricsCategory() {
160             return SettingsEnums.DIALOG_WIFI_SCAN_MODE;
161         }
162 
163         @Override
onCreateDialog(Bundle savedInstanceState)164         public Dialog onCreateDialog(Bundle savedInstanceState) {
165             return new AlertDialog.Builder(getActivity())
166                     .setMessage(
167                             TextUtils.isEmpty(mApp)
168                                     ? getString(R.string.wifi_scan_always_turn_on_message_unknown)
169                                     : getString(R.string.wifi_scan_always_turnon_message, mApp))
170                     .setPositiveButton(
171                             R.string.wifi_scan_always_confirm_allow,
172                             new DialogInterface.OnClickListener() {
173                                 public void onClick(DialogInterface dialog, int whichButton) {
174                                     ((WifiScanModeActivity) getActivity()).doPositiveClick();
175                                 }
176                             })
177                     .setNegativeButton(
178                             R.string.wifi_scan_always_confirm_deny,
179                             new DialogInterface.OnClickListener() {
180                                 public void onClick(DialogInterface dialog, int whichButton) {
181                                     ((WifiScanModeActivity) getActivity()).doNegativeClick();
182                                 }
183                             })
184                     .create();
185         }
186 
187         @Override
onCancel(DialogInterface dialog)188         public void onCancel(DialogInterface dialog) {
189             ((WifiScanModeActivity) getActivity()).doNegativeClick();
190         }
191     }
192 
193     private static boolean isGuestUser(Context context) {
194         final UserManager userManager = context.getSystemService(UserManager.class);
195         if (userManager == null) return false;
196         return userManager.isGuestUser();
197     }
198 
199     private static boolean isWifiScanModeConfigAllowed(Context context) {
200         final UserManager userManager = context.getSystemService(UserManager.class);
201         if (userManager == null) return true;
202         return !userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_LOCATION);
203     }
204 }
205