• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.details;
18 
19 import static com.android.car.settings.common.ActionButtonsPreference.ActionButtons;
20 
21 import android.annotation.SuppressLint;
22 import android.car.drivingstate.CarUxRestrictions;
23 import android.content.Context;
24 import android.net.Network;
25 import android.net.NetworkCapabilities;
26 import android.net.Uri;
27 import android.net.wifi.EasyConnectStatusCallback;
28 import android.net.wifi.WifiManager;
29 import android.os.Build;
30 import android.widget.Toast;
31 
32 import androidx.annotation.NonNull;
33 
34 import com.android.car.settings.Flags;
35 import com.android.car.settings.R;
36 import com.android.car.settings.common.ActionButtonsPreference;
37 import com.android.car.settings.common.FragmentController;
38 import com.android.car.settings.common.Logger;
39 import com.android.car.settings.wifi.WifiUtil;
40 import com.android.wifitrackerlib.WifiEntry;
41 
42 /**
43  * Shows Wifi details action buttons (forget and connect).
44  */
45 public class WifiDetailsActionButtonsPreferenceController
46         extends WifiDetailsBasePreferenceController<ActionButtonsPreference>
47         implements WifiEntry.ConnectCallback {
48     private static final Logger LOG = new Logger(
49             WifiDetailsActionButtonsPreferenceController.class);
50     private String mUri;
51     private boolean mSupportEasyConnect;
52 
WifiDetailsActionButtonsPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)53     public WifiDetailsActionButtonsPreferenceController(Context context,
54             String preferenceKey, FragmentController fragmentController,
55             CarUxRestrictions uxRestrictions) {
56         super(context, preferenceKey, fragmentController, uxRestrictions);
57     }
58 
59     @Override
getPreferenceType()60     protected Class<ActionButtonsPreference> getPreferenceType() {
61         return ActionButtonsPreference.class;
62     }
63 
64     @Override
onCreateInternal()65     protected void onCreateInternal() {
66         super.onCreateInternal();
67         mSupportEasyConnect = getCarWifiManager() != null
68                 && getCarWifiManager().isEasyConnectSupported();
69         if (mSupportEasyConnect) {
70             setUpSharePageInfo();
71         }
72     }
73 
74     @Override
updateState(ActionButtonsPreference preference)75     protected void updateState(ActionButtonsPreference preference) {
76         getPreference()
77                 .getButton(ActionButtons.BUTTON1)
78                 .setText(R.string.forget)
79                 .setIcon(R.drawable.ic_delete)
80                 .setVisible(canForgetNetwork())
81                 .setOnClickListener(v -> {
82                     getWifiEntry().forget(/* callback= */ null);
83                     getFragmentController().goBack();
84                 });
85 
86         boolean canConnectOrDisconnect = getWifiEntry().canConnect()
87                 || getWifiEntry().canDisconnect();
88         preference
89                 .getButton(ActionButtons.BUTTON2)
90                 .setVisible(canConnectOrDisconnect || getWifiEntry().getConnectedState()
91                         == WifiEntry.CONNECTED_STATE_CONNECTING)
92                 .setEnabled(canConnectOrDisconnect)
93                 .setText(getConnectDisconnectButtonTextResource())
94                 .setIcon(getConnectDisconnectButtonIconResource())
95                 .setOnClickListener(v -> connectOrDisconnect());
96 
97         preference.getButton(ActionButtons.BUTTON3)
98                 .setVisible(mSupportEasyConnect && Flags.newFragmentForIntents())
99                 .setEnabled(mUri != null)
100                 .setText(R.string.wifi_detail_share)
101                 .setIcon(R.drawable.ic_qr)
102                 .setOnClickListener(v -> openSharePage());
103     }
104 
105     @Override
getDefaultAvailabilityStatus()106     protected int getDefaultAvailabilityStatus() {
107         if (!WifiUtil.isWifiAvailable(getContext())) {
108             return UNSUPPORTED_ON_DEVICE;
109         }
110         return AVAILABLE;
111     }
112 
113     @Override
onCapabilitiesChanged(Network network, NetworkCapabilities nc)114     public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
115         refreshUi();
116     }
117 
118     @Override
onConnectResult(@ifiEntry.ConnectCallback.ConnectStatus int status)119     public void onConnectResult(@WifiEntry.ConnectCallback.ConnectStatus int status) {
120         if (getWifiEntry().getLevel() == WifiEntry.WIFI_LEVEL_UNREACHABLE) {
121             Toast.makeText(getContext(),
122                     R.string.wifi_not_in_range_message,
123                     Toast.LENGTH_SHORT).show();
124         } else if (status != WifiEntry.ConnectCallback.CONNECT_STATUS_SUCCESS) {
125             Toast.makeText(getContext(),
126                     R.string.wifi_failed_connect_message,
127                     Toast.LENGTH_SHORT).show();
128         }
129     }
130 
canForgetNetwork()131     private boolean canForgetNetwork() {
132         return getWifiEntry().canForget()
133                 && !WifiUtil.isNetworkLockedDown(getContext(),
134                 getWifiEntry().getWifiConfiguration());
135     }
136 
connectOrDisconnect()137     private void connectOrDisconnect() {
138         if (!WifiUtil.isWifiEntryConnectedOrConnecting(getWifiEntry())) {
139             getWifiEntry().connect(/* callback= */ this);
140         } else {
141             getWifiEntry().disconnect(/* callback= */ null);
142         }
143     }
144 
getConnectDisconnectButtonTextResource()145     private int getConnectDisconnectButtonTextResource() {
146         switch (getWifiEntry().getConnectedState()) {
147             case WifiEntry.CONNECTED_STATE_DISCONNECTED:
148                 return R.string.wifi_setup_connect;
149             case WifiEntry.CONNECTED_STATE_CONNECTED:
150                 return R.string.disconnect;
151             case WifiEntry.CONNECTED_STATE_CONNECTING:
152                 return R.string.wifi_connecting;
153             default:
154                 throw new IllegalStateException("Invalid WifiEntry connected state");
155         }
156     }
157 
getConnectDisconnectButtonIconResource()158     private int getConnectDisconnectButtonIconResource() {
159         switch (getWifiEntry().getConnectedState()) {
160             case WifiEntry.CONNECTED_STATE_DISCONNECTED:
161             case WifiEntry.CONNECTED_STATE_CONNECTING:
162                 return R.drawable.ic_settings_wifi;
163             case WifiEntry.CONNECTED_STATE_CONNECTED:
164                 return R.drawable.ic_close;
165             default:
166                 throw new IllegalStateException("Invalid WifiEntry connected state");
167         }
168     }
169 
170     @SuppressLint("MissingPermission")
openSharePage()171     private void openSharePage() {
172         if (mUri != null) {
173             getFragmentController().launchFragment(
174                     WifiDetailsShareFragment.getInstance(mUri));
175         }
176     }
177 
178     @SuppressLint("MissingPermission")
setUpSharePageInfo()179     private void setUpSharePageInfo() {
180         getCarWifiManager().getWifiManager().startEasyConnectAsEnrolleeResponder(
181                 Build.DEVICE,
182                 WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1,
183                 getContext().getMainExecutor(),
184                 new SettingsEasyConnectStatusCallback());
185     }
186 
187     private class SettingsEasyConnectStatusCallback extends EasyConnectStatusCallback {
188 
189         @Override
onBootstrapUriGenerated(@onNull Uri dppUri)190         public void onBootstrapUriGenerated(@NonNull Uri dppUri) {
191             super.onBootstrapUriGenerated(dppUri);
192             if (!dppUri.toString().equals(mUri)) {
193                 mUri = dppUri.toString();
194                 refreshUi();
195             }
196         }
197 
198         @Override
onFailure(int code)199         public void onFailure(int code) {
200             super.onFailure(code);
201             LOG.w("Unable to generate Easy Connect Wifi QR code : " + code);
202             if (mUri != null) {
203                 mUri = null;
204                 refreshUi();
205             }
206         }
207 
208         @Override
onEnrolleeSuccess(int newNetworkId)209         public void onEnrolleeSuccess(int newNetworkId) {
210             // Do nothing.
211         }
212 
213         @Override
onConfiguratorSuccess(int code)214         public void onConfiguratorSuccess(int code) {
215             // Do nothing.
216         }
217 
218         @Override
onProgress(int code)219         public void onProgress(int code) {
220             // Do nothing.
221         }
222     }
223 }
224