1 /* 2 * Copyright (C) 2021 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.settings.wifi; 18 19 import android.content.Context; 20 import android.net.wifi.WifiManager; 21 import android.os.Handler; 22 import android.os.HandlerThread; 23 import android.os.Looper; 24 import android.os.PersistableBundle; 25 import android.os.Process; 26 import android.os.SimpleClock; 27 import android.os.SystemClock; 28 import android.telephony.CarrierConfigManager; 29 import android.util.Log; 30 31 import androidx.annotation.NonNull; 32 import androidx.annotation.Nullable; 33 import androidx.lifecycle.Lifecycle; 34 import androidx.lifecycle.LifecycleObserver; 35 import androidx.lifecycle.OnLifecycleEvent; 36 37 import com.android.internal.annotations.VisibleForTesting; 38 import com.android.settings.overlay.FeatureFactory; 39 import com.android.wifitrackerlib.MergedCarrierEntry; 40 import com.android.wifitrackerlib.WifiEntry; 41 import com.android.wifitrackerlib.WifiPickerTracker; 42 43 import java.time.Clock; 44 import java.time.ZoneOffset; 45 46 public class WifiPickerTrackerHelper implements LifecycleObserver { 47 48 private static final String TAG = "WifiPickerTrackerHelper"; 49 50 // Max age of tracked WifiEntries 51 private static final long MAX_SCAN_AGE_MILLIS = 15_000; 52 // Interval between initiating WifiPickerTracker scans 53 private static final long SCAN_INTERVAL_MILLIS = 10_000; 54 // Clock used for evaluating the age of scans 55 private static final Clock ELAPSED_REALTIME_CLOCK = new SimpleClock(ZoneOffset.UTC) { 56 @Override 57 public long millis() { 58 return SystemClock.elapsedRealtime(); 59 } 60 }; 61 62 protected WifiPickerTracker mWifiPickerTracker; 63 // Worker thread used for WifiPickerTracker work 64 protected HandlerThread mWorkerThread; 65 66 protected final WifiManager mWifiManager; 67 protected final CarrierConfigManager mCarrierConfigManager; 68 WifiPickerTrackerHelper(@onNull Lifecycle lifecycle, @NonNull Context context, @Nullable WifiPickerTracker.WifiPickerTrackerCallback listener)69 public WifiPickerTrackerHelper(@NonNull Lifecycle lifecycle, @NonNull Context context, 70 @Nullable WifiPickerTracker.WifiPickerTrackerCallback listener) { 71 if (lifecycle == null) { 72 throw new IllegalArgumentException("lifecycle must be non-null."); 73 } 74 lifecycle.addObserver(this); 75 mWorkerThread = new HandlerThread(TAG 76 + "{" + Integer.toHexString(System.identityHashCode(this)) + "}", 77 Process.THREAD_PRIORITY_BACKGROUND); 78 mWorkerThread.start(); 79 80 mWifiPickerTracker = FeatureFactory.getFactory(context) 81 .getWifiTrackerLibProvider() 82 .createWifiPickerTracker(lifecycle, context, 83 new Handler(Looper.getMainLooper()), 84 mWorkerThread.getThreadHandler(), 85 ELAPSED_REALTIME_CLOCK, 86 MAX_SCAN_AGE_MILLIS, 87 SCAN_INTERVAL_MILLIS, 88 listener); 89 90 mWifiManager = context.getSystemService(WifiManager.class); 91 mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); 92 } 93 94 /** @OnLifecycleEvent(ON_DESTROY) */ 95 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) onDestroy()96 public void onDestroy() { 97 mWorkerThread.quit(); 98 } 99 100 /** Return the WifiPickerTracker class */ getWifiPickerTracker()101 public @NonNull WifiPickerTracker getWifiPickerTracker() { 102 return mWifiPickerTracker; 103 } 104 105 /** Return the enabled/disabled state of the carrier network provision */ isCarrierNetworkProvisionEnabled(int subId)106 public boolean isCarrierNetworkProvisionEnabled(int subId) { 107 final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); 108 if (config == null) { 109 Log.e(TAG, "Could not get carrier config, subId:" + subId); 110 return false; 111 } 112 final boolean enabled = config.getBoolean( 113 CarrierConfigManager.KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL); 114 Log.i(TAG, "isCarrierNetworkProvisionEnabled:" + enabled); 115 return enabled; 116 } 117 118 /** Return the enabled/disabled state of the carrier network */ isCarrierNetworkEnabled(int subId)119 public boolean isCarrierNetworkEnabled(int subId) { 120 return mWifiManager.isCarrierNetworkOffloadEnabled(subId, true /* merged */); 121 } 122 123 /** Enables/disables the carrier network */ setCarrierNetworkEnabled(boolean enabled)124 public void setCarrierNetworkEnabled(boolean enabled) { 125 final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry(); 126 if (mergedCarrierEntry == null) { 127 return; 128 } 129 mergedCarrierEntry.setEnabled(enabled); 130 } 131 132 /** Connect to the carrier network */ connectCarrierNetwork(@ullable WifiEntry.ConnectCallback callback)133 public boolean connectCarrierNetwork(@Nullable WifiEntry.ConnectCallback callback) { 134 final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry(); 135 if (mergedCarrierEntry == null || !mergedCarrierEntry.canConnect()) { 136 return false; 137 } 138 mergedCarrierEntry.connect(callback); 139 return true; 140 } 141 142 /** Confirms connection of the carrier network connected with the internet access */ isCarrierNetworkActive()143 public boolean isCarrierNetworkActive() { 144 final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry(); 145 return (mergedCarrierEntry != null && mergedCarrierEntry.isDefaultNetwork()); 146 } 147 148 /** Return the carrier network ssid */ getCarrierNetworkSsid()149 public String getCarrierNetworkSsid() { 150 final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry(); 151 if (mergedCarrierEntry == null) { 152 return null; 153 } 154 return mergedCarrierEntry.getSsid(); 155 } 156 157 @VisibleForTesting setWifiPickerTracker(@onNull WifiPickerTracker wifiPickerTracker)158 void setWifiPickerTracker(@NonNull WifiPickerTracker wifiPickerTracker) { 159 mWifiPickerTracker = wifiPickerTracker; 160 } 161 162 @VisibleForTesting setWorkerThread(@onNull HandlerThread workerThread)163 void setWorkerThread(@NonNull HandlerThread workerThread) { 164 mWorkerThread = workerThread; 165 } 166 } 167