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.wifitrackerlib; 18 19 import static android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS; 20 import static android.net.wifi.WifiInfo.sanitizeSsid; 21 22 import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription; 23 24 import android.content.Context; 25 import android.net.NetworkInfo; 26 import android.net.wifi.WifiInfo; 27 import android.net.wifi.WifiManager; 28 import android.net.wifi.WifiNetworkScoreCache; 29 import android.os.Handler; 30 import android.text.TextUtils; 31 import android.widget.Toast; 32 33 import androidx.annotation.NonNull; 34 import androidx.annotation.Nullable; 35 import androidx.annotation.WorkerThread; 36 37 import java.util.StringJoiner; 38 39 /** 40 * WifiEntry representation of merged carrier network, uniquely identified by subscription id. 41 */ 42 public class MergedCarrierEntry extends WifiEntry { 43 static final String KEY_PREFIX = "MergedCarrierEntry:"; 44 45 private final int mSubscriptionId; 46 @NonNull private final String mKey; 47 @NonNull private final Context mContext; 48 boolean mIsCellDefaultRoute; 49 MergedCarrierEntry(@onNull Handler callbackHandler, @NonNull WifiManager wifiManager, @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage, @NonNull Context context, int subscriptionId)50 MergedCarrierEntry(@NonNull Handler callbackHandler, 51 @NonNull WifiManager wifiManager, 52 @NonNull WifiNetworkScoreCache scoreCache, 53 boolean forSavedNetworksPage, 54 @NonNull Context context, 55 int subscriptionId) throws IllegalArgumentException { 56 super(callbackHandler, wifiManager, scoreCache, forSavedNetworksPage); 57 mContext = context; 58 mSubscriptionId = subscriptionId; 59 mKey = KEY_PREFIX + subscriptionId; 60 } 61 62 @Override getKey()63 public String getKey() { 64 return mKey; 65 } 66 67 @Override getSummary(boolean concise)68 public String getSummary(boolean concise) { 69 StringJoiner sj = new StringJoiner(mContext.getString( 70 R.string.wifitrackerlib_summary_separator)); 71 if (!concise) { 72 final String verboseLoggingDescription = getVerboseLoggingDescription(this); 73 if (!TextUtils.isEmpty(verboseLoggingDescription)) { 74 sj.add(verboseLoggingDescription); 75 } 76 } 77 return sj.toString(); 78 } 79 80 @Override getSsid()81 public synchronized String getSsid() { 82 if (mWifiInfo != null) { 83 return sanitizeSsid(mWifiInfo.getSSID()); 84 } 85 return null; 86 } 87 88 @Override getMacAddress()89 public synchronized String getMacAddress() { 90 if (mWifiInfo != null) { 91 final String wifiInfoMac = mWifiInfo.getMacAddress(); 92 if (!TextUtils.isEmpty(wifiInfoMac) 93 && !TextUtils.equals(wifiInfoMac, DEFAULT_MAC_ADDRESS)) { 94 return wifiInfoMac; 95 } 96 } 97 return null; 98 } 99 100 @Override canConnect()101 public synchronized boolean canConnect() { 102 return getConnectedState() == CONNECTED_STATE_DISCONNECTED && !mIsCellDefaultRoute; 103 } 104 105 /** 106 * Connect to this merged carrier network and show the "Wi-Fi won't autoconnect for now" toast. 107 * @param callback callback for the connect result 108 */ 109 @Override connect(@ullable ConnectCallback callback)110 public synchronized void connect(@Nullable ConnectCallback callback) { 111 connect(callback, true); 112 } 113 114 /** 115 * Connect to this merged carrier network. 116 * @param callback callback for the connect result 117 * @param showToast show the "Wi-Fi won't autoconnect for now" toast if {@code true} 118 */ connect(@ullable ConnectCallback callback, boolean showToast)119 public synchronized void connect(@Nullable ConnectCallback callback, boolean showToast) { 120 mConnectCallback = callback; 121 mWifiManager.startRestrictingAutoJoinToSubscriptionId(mSubscriptionId); 122 if (showToast) { 123 Toast.makeText(mContext, R.string.wifitrackerlib_wifi_wont_autoconnect_for_now, 124 Toast.LENGTH_SHORT).show(); 125 } 126 if (mConnectCallback != null) { 127 mCallbackHandler.post(() -> { 128 final ConnectCallback connectCallback = mConnectCallback; 129 if (connectCallback != null) { 130 connectCallback.onConnectResult(ConnectCallback.CONNECT_STATUS_SUCCESS); 131 } 132 }); 133 } 134 } 135 136 @Override canDisconnect()137 public boolean canDisconnect() { 138 return getConnectedState() == CONNECTED_STATE_CONNECTED; 139 } 140 141 @Override disconnect(@ullable DisconnectCallback callback)142 public synchronized void disconnect(@Nullable DisconnectCallback callback) { 143 mDisconnectCallback = callback; 144 mWifiManager.stopRestrictingAutoJoinToSubscriptionId(); 145 mWifiManager.startScan(); 146 if (mDisconnectCallback != null) { 147 mCallbackHandler.post(() -> { 148 final DisconnectCallback disconnectCallback = mDisconnectCallback; 149 if (disconnectCallback != null) { 150 disconnectCallback.onDisconnectResult( 151 DisconnectCallback.DISCONNECT_STATUS_SUCCESS); 152 } 153 }); 154 } 155 } 156 157 @WorkerThread connectionInfoMatches(@onNull WifiInfo wifiInfo, @NonNull NetworkInfo networkInfo)158 protected boolean connectionInfoMatches(@NonNull WifiInfo wifiInfo, 159 @NonNull NetworkInfo networkInfo) { 160 return wifiInfo.isCarrierMerged() && mSubscriptionId == wifiInfo.getSubscriptionId(); 161 } 162 163 /** Returns whether or not carrier network offload is enabled for this subscription **/ isEnabled()164 public boolean isEnabled() { 165 return mWifiManager.isCarrierNetworkOffloadEnabled(mSubscriptionId, true); 166 } 167 168 /** Enables/disables the carrier network */ setEnabled(boolean enabled)169 public void setEnabled(boolean enabled) { 170 mWifiManager.setCarrierNetworkOffloadEnabled(mSubscriptionId, true, enabled); 171 if (!enabled) { 172 mWifiManager.stopRestrictingAutoJoinToSubscriptionId(); 173 mWifiManager.startScan(); 174 } 175 } 176 getSubscriptionId()177 /* package */ int getSubscriptionId() { 178 return mSubscriptionId; 179 } 180 updateIsCellDefaultRoute(boolean isCellDefaultRoute)181 /* package */ synchronized void updateIsCellDefaultRoute(boolean isCellDefaultRoute) { 182 mIsCellDefaultRoute = isCellDefaultRoute; 183 notifyOnUpdated(); 184 } 185 } 186