QS: Wifi control panel.
Create first example of an inline detail view with line
items, bind to new access-point controller.
Move the common bits of all control panels into a
common abstraction. Share common parts of layout
(More settings / done button).
Change-Id: I14a1bf548f3291dc628f97bf09dd4e38ac2fb2dc
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiAccessPointController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiAccessPointController.java
new file mode 100644
index 0000000..09e7472
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiAccessPointController.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.ActionListener;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController.AccessPoint;
+import com.android.systemui.statusbar.policy.NetworkController.AccessPointCallback;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class WifiAccessPointController {
+ private static final String TAG = "WifiAccessPointController";
+ private static final boolean DEBUG = false;
+
+ private static final int[] ICONS = {
+ R.drawable.ic_qs_wifi_0,
+ R.drawable.ic_qs_wifi_full_1,
+ R.drawable.ic_qs_wifi_full_2,
+ R.drawable.ic_qs_wifi_full_3,
+ R.drawable.ic_qs_wifi_full_4,
+ };
+
+ private final Context mContext;
+ private final ArrayList<AccessPointCallback> mCallbacks = new ArrayList<AccessPointCallback>();
+ private final WifiManager mWifiManager;
+ private final Receiver mReceiver = new Receiver();
+
+ private boolean mScanning;
+
+ public WifiAccessPointController(Context context) {
+ mContext = context;
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ }
+
+ public void addCallback(AccessPointCallback callback) {
+ if (callback == null || mCallbacks.contains(callback)) return;
+ if (DEBUG) Log.d(TAG, "addCallback " + callback);
+ mCallbacks.add(callback);
+ mReceiver.setListening(!mCallbacks.isEmpty());
+ }
+
+ public void removeCallback(AccessPointCallback callback) {
+ if (callback == null) return;
+ if (DEBUG) Log.d(TAG, "removeCallback " + callback);
+ mCallbacks.remove(callback);
+ mReceiver.setListening(!mCallbacks.isEmpty());
+ }
+
+ public void scan() {
+ if (mScanning) return;
+ if (DEBUG) Log.d(TAG, "scan!");
+ mScanning = mWifiManager.startScan();
+ }
+
+ public void connect(AccessPoint ap) {
+ if (ap == null || ap.networkId < 0) return;
+ if (DEBUG) Log.d(TAG, "connect networkId=" + ap.networkId);
+ mWifiManager.connect(ap.networkId, new ActionListener() {
+ @Override
+ public void onSuccess() {
+ if (DEBUG) Log.d(TAG, "connect success");
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ if (DEBUG) Log.d(TAG, "connect failure reason=" + reason);
+ }
+ });
+ }
+
+ private void fireCallback(AccessPoint[] aps) {
+ for (AccessPointCallback callback : mCallbacks) {
+ callback.onAccessPointsChanged(aps);
+ }
+ }
+
+ private static String trimDoubleQuotes(String v) {
+ return v != null && v.length() >= 2 && v.charAt(0) == '\"'
+ && v.charAt(v.length() - 1) == '\"' ? v.substring(1, v.length() - 1) : v;
+ }
+
+ private int getConnectedNetworkId() {
+ final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+ return wifiInfo != null ? wifiInfo.getNetworkId() : AccessPoint.NO_NETWORK;
+ }
+
+ private ArrayMap<String, WifiConfiguration> getConfiguredNetworksBySsid() {
+ final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+ if (configs == null || configs.size() == 0) return ArrayMap.EMPTY;
+ final ArrayMap<String, WifiConfiguration> rt = new ArrayMap<String, WifiConfiguration>();
+ for (WifiConfiguration config : configs) {
+ rt.put(trimDoubleQuotes(config.SSID), config);
+ }
+ return rt;
+ }
+
+ private void updateAccessPoints() {
+ final int connectedNetworkId = getConnectedNetworkId();
+ if (DEBUG) Log.d(TAG, "connectedNetworkId: " + connectedNetworkId);
+ final List<ScanResult> scanResults = mWifiManager.getScanResults();
+ final ArrayMap<String, WifiConfiguration> configured = getConfiguredNetworksBySsid();
+ if (DEBUG) Log.d(TAG, "scanResults: " + scanResults);
+ final List<AccessPoint> aps = new ArrayList<AccessPoint>(scanResults.size());
+ final ArraySet<String> ssids = new ArraySet<String>();
+ for (ScanResult scanResult : scanResults) {
+ final String ssid = scanResult.SSID;
+ if (TextUtils.isEmpty(ssid) || ssids.contains(ssid)) continue;
+ if (!configured.containsKey(ssid)) continue;
+ ssids.add(ssid);
+ final WifiConfiguration config = configured.get(ssid);
+ final int level = WifiManager.calculateSignalLevel(scanResult.level, ICONS.length);
+ final AccessPoint ap = new AccessPoint();
+ ap.networkId = config != null ? config.networkId : AccessPoint.NO_NETWORK;
+ ap.ssid = ssid;
+ ap.iconId = ICONS[level];
+ ap.isConnected = ap.networkId != AccessPoint.NO_NETWORK
+ && ap.networkId == connectedNetworkId;
+ ap.level = level;
+ aps.add(ap);
+ }
+ Collections.sort(aps, mByStrength);
+ fireCallback(aps.toArray(new AccessPoint[aps.size()]));
+ }
+
+ private final Comparator<AccessPoint> mByStrength = new Comparator<AccessPoint> () {
+ @Override
+ public int compare(AccessPoint lhs, AccessPoint rhs) {
+ return -Integer.compare(score(lhs), score(rhs));
+ }
+
+ private int score(AccessPoint ap) {
+ return ap.level + (ap.isConnected ? 10 : 0);
+ }
+ };
+
+ private final class Receiver extends BroadcastReceiver {
+ private boolean mRegistered;
+
+ public void setListening(boolean listening) {
+ if (listening && !mRegistered) {
+ if (DEBUG) Log.d(TAG, "Registering receiver");
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+ filter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
+ filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
+ filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+ mContext.registerReceiver(this, filter);
+ mRegistered = true;
+ } else if (!listening && mRegistered) {
+ if (DEBUG) Log.d(TAG, "Unregistering receiver");
+ mContext.unregisterReceiver(this);
+ mRegistered = false;
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction());
+ if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
+ updateAccessPoints();
+ mScanning = false;
+ }
+ }
+ }
+}