1 /* 2 * Copyright (C) 2018 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.settings.wifi; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.wifi.WifiManager; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.os.Looper; 27 import android.text.TextUtils; 28 import android.widget.Toast; 29 30 import androidx.annotation.VisibleForTesting; 31 import androidx.annotation.XmlRes; 32 import androidx.localbroadcastmanager.content.LocalBroadcastManager; 33 34 import com.android.car.settings.R; 35 import com.android.car.settings.common.Logger; 36 import com.android.car.settings.common.SettingsFragment; 37 import com.android.car.ui.toolbar.MenuItem; 38 import com.android.wifitrackerlib.WifiEntry; 39 40 import java.util.Collections; 41 import java.util.List; 42 43 /** 44 * Adds a hidden wifi network. The connect button on the fragment is only used for unsecure hidden 45 * networks. The remaining security types can be connected via pressing connect on the password 46 * dialog. 47 */ 48 public class AddWifiFragment extends SettingsFragment { 49 private static final Logger LOG = new Logger(AddWifiFragment.class); 50 private static final String KEY_NETWORK_NAME = "network_name"; 51 private static final String KEY_SECURITY_TYPE = "security_type"; 52 53 @VisibleForTesting 54 final BroadcastReceiver mNameChangeReceiver = new BroadcastReceiver() { 55 @Override 56 public void onReceive(Context context, Intent intent) { 57 mNetworkName = intent.getStringExtra( 58 NetworkNamePreferenceController.KEY_NETWORK_NAME); 59 setButtonEnabledState(); 60 } 61 }; 62 63 @VisibleForTesting 64 final BroadcastReceiver mSecurityChangeReceiver = new BroadcastReceiver() { 65 @Override 66 public void onReceive(Context context, Intent intent) { 67 mSecurityType = intent.getIntExtra( 68 NetworkSecurityPreferenceController.KEY_SECURITY_TYPE, 69 WifiEntry.SECURITY_NONE); 70 setButtonEnabledState(); 71 } 72 }; 73 74 private final Handler mUiHandler = new Handler(Looper.getMainLooper()); 75 private final WifiManager.ActionListener mConnectionListener = 76 new WifiManager.ActionListener() { 77 @Override 78 public void onSuccess() { 79 LOG.d("connected to network"); 80 mUiHandler.post(() -> goBack()); 81 } 82 83 @Override 84 public void onFailure(int reason) { 85 LOG.d("Failed to connect to network. Failure code: " + reason); 86 Toast.makeText(getContext(), R.string.wifi_failed_connect_message, 87 Toast.LENGTH_SHORT).show(); 88 } 89 }; 90 91 private MenuItem mAddWifiButton; 92 private String mNetworkName; 93 private int mSecurityType = WifiEntry.SECURITY_NONE; 94 95 @Override getToolbarMenuItems()96 public List<MenuItem> getToolbarMenuItems() { 97 return Collections.singletonList(mAddWifiButton); 98 } 99 100 @Override 101 @XmlRes getPreferenceScreenResId()102 protected int getPreferenceScreenResId() { 103 return R.xml.add_wifi_fragment; 104 } 105 106 @Override onCreate(Bundle savedInstanceState)107 public void onCreate(Bundle savedInstanceState) { 108 super.onCreate(savedInstanceState); 109 if (savedInstanceState != null) { 110 mNetworkName = savedInstanceState.getString(KEY_NETWORK_NAME); 111 mSecurityType = savedInstanceState.getInt(KEY_SECURITY_TYPE, WifiEntry.SECURITY_NONE); 112 } 113 114 mAddWifiButton = new MenuItem.Builder(getContext()) 115 .setTitle(R.string.wifi_setup_connect) 116 .setOnClickListener(i -> { 117 // This only needs to handle hidden/unsecure networks. 118 WifiUtil.connectToWifiEntry(getContext(), mNetworkName, 119 mSecurityType, /* password= */ null, /* hidden= */ true, 120 mConnectionListener); 121 }) 122 .build(); 123 LocalBroadcastManager.getInstance(getContext()).registerReceiver(mNameChangeReceiver, 124 new IntentFilter(NetworkNamePreferenceController.ACTION_NAME_CHANGE)); 125 LocalBroadcastManager.getInstance(getContext()).registerReceiver(mSecurityChangeReceiver, 126 new IntentFilter(NetworkSecurityPreferenceController.ACTION_SECURITY_CHANGE)); 127 } 128 129 @Override onDestroy()130 public void onDestroy() { 131 super.onDestroy(); 132 LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mNameChangeReceiver); 133 LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mSecurityChangeReceiver); 134 } 135 136 @Override onSaveInstanceState(Bundle outState)137 public void onSaveInstanceState(Bundle outState) { 138 super.onSaveInstanceState(outState); 139 outState.putString(KEY_NETWORK_NAME, mNetworkName); 140 outState.putInt(KEY_SECURITY_TYPE, mSecurityType); 141 } 142 143 @Override onStart()144 public void onStart() { 145 super.onStart(); 146 setButtonEnabledState(); 147 } 148 149 @Override onStop()150 public void onStop() { 151 super.onStop(); 152 if (mAddWifiButton != null) { 153 mAddWifiButton.setEnabled(false); 154 } 155 } 156 setButtonEnabledState()157 private void setButtonEnabledState() { 158 if (mAddWifiButton != null) { 159 mAddWifiButton.setEnabled( 160 !TextUtils.isEmpty(mNetworkName) && WifiUtil.isOpenNetwork(mSecurityType)); 161 } 162 } 163 } 164