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.settings.wifi; 18 19 import android.content.Context; 20 import android.os.Bundle; 21 22 import androidx.preference.PreferenceGroup; 23 import androidx.preference.PreferenceScreen; 24 25 import com.android.settings.R; 26 import com.android.settings.core.SubSettingLauncher; 27 import com.android.settings.wifi.details.WifiNetworkDetailsFragment; 28 import com.android.settingslib.core.AbstractPreferenceController; 29 import com.android.settingslib.core.lifecycle.Lifecycle; 30 import com.android.settingslib.wifi.AccessPoint; 31 import com.android.settingslib.wifi.AccessPointPreference; 32 import com.android.settingslib.wifi.WifiTracker; 33 import com.android.settingslib.wifi.WifiTrackerFactory; 34 35 // TODO(b/151133650): Replace AbstractPreferenceController with BasePreferenceController. 36 /** 37 * This places a preference into a PreferenceGroup owned by some parent 38 * controller class when there is a wifi connection present. 39 */ 40 public class WifiConnectionPreferenceController extends AbstractPreferenceController implements 41 WifiTracker.WifiListener { 42 43 private static final String TAG = "WifiConnPrefCtrl"; 44 45 private static final String KEY = "active_wifi_connection"; 46 47 private UpdateListener mUpdateListener; 48 private Context mPrefContext; 49 private String mPreferenceGroupKey; 50 private PreferenceGroup mPreferenceGroup; 51 private WifiTracker mWifiTracker; 52 private AccessPointPreference mPreference; 53 private AccessPointPreference.UserBadgeCache mBadgeCache; 54 private int order; 55 private int mMetricsCategory; 56 57 /** 58 * Used to notify a parent controller that this controller has changed in availability, or has 59 * updated the content in the preference that it manages. 60 */ 61 public interface UpdateListener { onChildrenUpdated()62 void onChildrenUpdated(); 63 } 64 65 /** 66 * @param context the context for the UI where we're placing the preference 67 * @param lifecycle for listening to lifecycle events for the UI 68 * @param updateListener for notifying a parent controller of changes 69 * @param preferenceGroupKey the key to use to lookup the PreferenceGroup where this controller 70 * will add its preference 71 * @param order the order that the preference added by this controller should use - 72 * useful when this preference needs to be ordered in a specific way 73 * relative to others in the PreferenceGroup 74 * @param metricsCategory - the category to use as the source when handling the click on the 75 * pref to go to the wifi connection detail page 76 */ WifiConnectionPreferenceController(Context context, Lifecycle lifecycle, UpdateListener updateListener, String preferenceGroupKey, int order, int metricsCategory)77 public WifiConnectionPreferenceController(Context context, Lifecycle lifecycle, 78 UpdateListener updateListener, String preferenceGroupKey, int order, 79 int metricsCategory) { 80 super(context); 81 mUpdateListener = updateListener; 82 mPreferenceGroupKey = preferenceGroupKey; 83 mWifiTracker = WifiTrackerFactory.create(context, this, lifecycle, true /* includeSaved */, 84 true /* includeScans */); 85 this.order = order; 86 mMetricsCategory = metricsCategory; 87 mBadgeCache = new AccessPointPreference.UserBadgeCache(context.getPackageManager()); 88 } 89 90 @Override isAvailable()91 public boolean isAvailable() { 92 return mWifiTracker.isConnected() && getCurrentAccessPoint() != null; 93 } 94 95 @Override getPreferenceKey()96 public String getPreferenceKey() { 97 return KEY; 98 } 99 100 @Override displayPreference(PreferenceScreen screen)101 public void displayPreference(PreferenceScreen screen) { 102 super.displayPreference(screen); 103 mPreferenceGroup = screen.findPreference(mPreferenceGroupKey); 104 mPrefContext = screen.getContext(); 105 update(); 106 } 107 getCurrentAccessPoint()108 private AccessPoint getCurrentAccessPoint() { 109 for (AccessPoint accessPoint : mWifiTracker.getAccessPoints()) { 110 if (accessPoint.isActive()) { 111 return accessPoint; 112 } 113 } 114 return null; 115 } 116 updatePreference(AccessPoint accessPoint)117 private void updatePreference(AccessPoint accessPoint) { 118 if (mPreference != null) { 119 mPreferenceGroup.removePreference(mPreference); 120 mPreference = null; 121 } 122 if (accessPoint == null) { 123 return; 124 } 125 if (mPrefContext != null) { 126 mPreference = new AccessPointPreference(accessPoint, mPrefContext, mBadgeCache, 127 R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */); 128 mPreference.setKey(KEY); 129 mPreference.refresh(); 130 mPreference.setOrder(order); 131 132 mPreference.setOnPreferenceClickListener(pref -> { 133 Bundle args = new Bundle(); 134 mPreference.getAccessPoint().saveWifiState(args); 135 new SubSettingLauncher(mPrefContext) 136 .setTitleRes(R.string.pref_title_network_details) 137 .setDestination(WifiNetworkDetailsFragment.class.getName()) 138 .setArguments(args) 139 .setSourceMetricsCategory(mMetricsCategory) 140 .launch(); 141 return true; 142 }); 143 mPreferenceGroup.addPreference(mPreference); 144 } 145 } 146 update()147 private void update() { 148 AccessPoint connectedAccessPoint = null; 149 if (mWifiTracker.isConnected()) { 150 connectedAccessPoint = getCurrentAccessPoint(); 151 } 152 if (connectedAccessPoint == null) { 153 updatePreference(null); 154 } else { 155 if (mPreference == null || !mPreference.getAccessPoint().equals(connectedAccessPoint)) { 156 updatePreference(connectedAccessPoint); 157 } else if (mPreference != null) { 158 mPreference.refresh(); 159 } 160 } 161 mUpdateListener.onChildrenUpdated(); 162 } 163 164 @Override onWifiStateChanged(int state)165 public void onWifiStateChanged(int state) { 166 update(); 167 } 168 169 @Override onConnectedChanged()170 public void onConnectedChanged() { 171 update(); 172 } 173 174 @Override onAccessPointsChanged()175 public void onAccessPointsChanged() { 176 update(); 177 } 178 } 179