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