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