1 /*
2  * Copyright (C) 2014 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.tv.settings.connectivity;
18 
19 import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.os.UserHandle;
25 import android.os.UserManager;
26 import android.util.Log;
27 
28 import androidx.fragment.app.Fragment;
29 import androidx.fragment.app.FragmentTransaction;
30 import androidx.lifecycle.ViewModelProviders;
31 
32 import com.android.settingslib.RestrictedLockUtils;
33 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
34 import com.android.settingslib.RestrictedLockUtilsInternal;
35 import com.android.tv.settings.R;
36 import com.android.tv.settings.connectivity.setup.AdvancedWifiOptionsFlow;
37 import com.android.tv.settings.connectivity.setup.ChooseSecurityState;
38 import com.android.tv.settings.connectivity.setup.ConnectFailedState;
39 import com.android.tv.settings.connectivity.setup.ConnectState;
40 import com.android.tv.settings.connectivity.setup.EasyConnectQRState;
41 import com.android.tv.settings.connectivity.setup.EnterPasswordState;
42 import com.android.tv.settings.connectivity.setup.EnterSsidState;
43 import com.android.tv.settings.connectivity.setup.OptionsOrConnectState;
44 import com.android.tv.settings.connectivity.setup.SuccessState;
45 import com.android.tv.settings.connectivity.setup.UserChoiceInfo;
46 import com.android.tv.settings.connectivity.util.State;
47 import com.android.tv.settings.connectivity.util.StateMachine;
48 import com.android.tv.settings.core.instrumentation.InstrumentedActivity;
49 
50 /**
51  * Manual-style add wifi network (the kind you'd use for adding a hidden or out-of-range network.)
52  */
53 public class AddWifiNetworkActivity extends InstrumentedActivity
54         implements State.FragmentChangeListener {
55     private static final String TAG = "AddWifiNetworkActivity";
56 
57     private static final String EXTRA_TYPE = "com.android.tv.settings.connectivity.type";
58     private static final String EXTRA_TYPE_EASYCONNECT = "easyconnect";
59 
60     /**
61      * Create an intent to launch this activity in EasyConnect mode.
62      */
createEasyConnectIntent(Context context)63     public static Intent createEasyConnectIntent(Context context) {
64         return new Intent(context, AddWifiNetworkActivity.class)
65                 .putExtra(EXTRA_TYPE, EXTRA_TYPE_EASYCONNECT);
66     }
67 
68     private final StateMachine.Callback mStateMachineCallback = new StateMachine.Callback() {
69         @Override
70         public void onFinish(int result) {
71             setResult(result);
72             finish();
73         }
74     };
75     private State mChooseSecurityState;
76     private State mConnectFailedState;
77     private State mConnectState;
78     private State mEnterPasswordState;
79     private State mEnterSsidState;
80     private State mEasyConnectQrState;
81     private State mSuccessState;
82     private State mOptionsOrConnectState;
83     private State mFinishState;
84     private StateMachine mStateMachine;
85 
86     @Override
onCreate(Bundle savedInstanceState)87     protected void onCreate(Bundle savedInstanceState) {
88         super.onCreate(savedInstanceState);
89 
90 
91         if (!isAddWifiAllowed()) {
92             EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(this,
93                     UserManager.DISALLOW_CONFIG_WIFI, UserHandle.myUserId());
94             if (admin != null) {
95                 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(this, admin);
96             }
97             finish();
98             return;
99         }
100 
101         setContentView(R.layout.wifi_container);
102         mStateMachine = ViewModelProviders.of(this).get(StateMachine.class);
103         mStateMachine.setCallback(mStateMachineCallback);
104         UserChoiceInfo userChoiceInfo = ViewModelProviders.of(this).get(UserChoiceInfo.class);
105         userChoiceInfo.getWifiConfiguration().hiddenSSID = true;
106 
107         boolean isEasyConnectFlow = EXTRA_TYPE_EASYCONNECT.equals(
108                 getIntent().getStringExtra(EXTRA_TYPE));
109 
110         mEnterSsidState = new EnterSsidState(this);
111         mEasyConnectQrState = new EasyConnectQRState(this);
112         mChooseSecurityState = new ChooseSecurityState(this);
113         mEnterPasswordState = new EnterPasswordState(this);
114         mConnectState = new ConnectState(this);
115         mConnectFailedState = new ConnectFailedState(this);
116         mSuccessState = new SuccessState(this);
117         mOptionsOrConnectState = new OptionsOrConnectState(this);
118         mFinishState = new FinishState(this);
119         AdvancedWifiOptionsFlow.createFlow(
120                 this, true, true, null, mOptionsOrConnectState,
121                 mConnectState, AdvancedWifiOptionsFlow.START_DEFAULT_PAGE);
122 
123         /* Enter SSID */
124         mStateMachine.addState(
125                 mEnterSsidState,
126                 StateMachine.CONTINUE,
127                 mChooseSecurityState
128         );
129 
130         /* Choose security */
131         mStateMachine.addState(
132                 mChooseSecurityState,
133                 StateMachine.OPTIONS_OR_CONNECT,
134                 mOptionsOrConnectState
135         );
136         mStateMachine.addState(
137                 mChooseSecurityState,
138                 StateMachine.CONTINUE,
139                 mEnterPasswordState
140         );
141 
142         /* Enter Password */
143         mStateMachine.addState(
144                 mEnterPasswordState,
145                 StateMachine.OPTIONS_OR_CONNECT,
146                 mOptionsOrConnectState
147         );
148 
149         /* EasyConnect QR code */
150         mStateMachine.addState(
151                 mEasyConnectQrState,
152                 StateMachine.CONNECT,
153                 mConnectState
154         );
155         mStateMachine.addState(
156                 mEasyConnectQrState,
157                 StateMachine.RESULT_FAILURE,
158                 mConnectFailedState
159         );
160 
161         /* Options or Connect */
162         mStateMachine.addState(
163                 mOptionsOrConnectState,
164                 StateMachine.CONNECT,
165                 mConnectState
166         );
167         mStateMachine.addState(
168                 mOptionsOrConnectState,
169                 StateMachine.RESTART,
170                 mEnterSsidState
171         );
172 
173         /* Connect */
174         mStateMachine.addState(
175                 mConnectState,
176                 StateMachine.RESULT_FAILURE,
177                 mConnectFailedState
178         );
179         mStateMachine.addState(
180                 mConnectState,
181                 StateMachine.RESULT_SUCCESS,
182                 mSuccessState
183         );
184 
185         /* Connect Failed */
186         mStateMachine.addState(
187                 mConnectFailedState,
188                 StateMachine.TRY_AGAIN,
189                 isEasyConnectFlow ? mEasyConnectQrState : mOptionsOrConnectState
190         );
191 
192         mStateMachine.addState(
193                 mConnectFailedState,
194                 StateMachine.SELECT_WIFI,
195                 mFinishState
196         );
197 
198         if (isEasyConnectFlow) {
199             mStateMachine.setStartState(mEasyConnectQrState);
200         } else {
201             mStateMachine.setStartState(mEnterSsidState);
202         }
203 
204         mStateMachine.start(true);
205     }
206 
207     @Override
onBackPressed()208     public void onBackPressed() {
209         mStateMachine.back();
210     }
211 
updateView(Fragment fragment, boolean movingForward)212     private void updateView(Fragment fragment, boolean movingForward) {
213         if (fragment != null) {
214             FragmentTransaction updateTransaction = getSupportFragmentManager().beginTransaction();
215             if (movingForward) {
216                 updateTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
217             } else {
218                 updateTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
219             }
220             updateTransaction.replace(R.id.wifi_container, fragment, TAG);
221             updateTransaction.commitAllowingStateLoss();
222         }
223     }
224 
225     @Override
onFragmentChange(Fragment newFragment, boolean movingForward)226     public void onFragmentChange(Fragment newFragment, boolean movingForward) {
227         updateView(newFragment, movingForward);
228     }
229 
isAddWifiAllowed()230     private boolean isAddWifiAllowed() {
231         final UserManager userManager = UserManager.get(this);
232         if(userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)) {
233             Log.e(TAG, "The user is not allowed to configure Wi-Fi.");
234             return false;
235         }
236         if (userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
237             Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
238             return false;
239         }
240         return true;
241     }
242 }
243