AccessPoint.java revision d36699282cbd0a6897f425106081d3f2c0db55d4
1/*
2 * Copyright (C) 2010 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
17package com.android.settings.wifi;
18
19import android.content.Context;
20import android.net.NetworkInfo.DetailedState;
21import android.net.wifi.ScanResult;
22import android.net.wifi.WifiConfiguration;
23import android.net.wifi.WifiConfiguration.KeyMgmt;
24import android.net.wifi.WifiInfo;
25import android.net.wifi.WifiManager;
26import android.preference.Preference;
27import android.view.View;
28import android.widget.ImageView;
29
30import com.android.settings.R;
31
32import java.util.Comparator;
33
34class AccessPoint extends Preference {
35    private static final int[] STATE_SECURED = {R.attr.state_encrypted};
36    private static final int[] STATE_NONE = {};
37
38    public static final class Comparater
39            implements Comparator<AccessPoint> {
40        @Override
41        public int compare(AccessPoint accessPoint1, AccessPoint accessPoint2) {
42            // Active one goes first.
43            if (accessPoint1.mInfo != accessPoint2.mInfo) {
44                return (accessPoint1.mInfo != null) ? -1 : 1;
45            }
46
47            // Reachable one goes before unreachable one.
48            if ((accessPoint1.mRssi ^ accessPoint2.mRssi) < 0) {
49                return (accessPoint1.mRssi != Integer.MAX_VALUE) ? -1 : 1;
50            }
51            // Configured one goes before unconfigured one.
52            if ((accessPoint1.networkId ^ accessPoint2.networkId) < 0) {
53                return (accessPoint1.networkId != -1) ? -1 : 1;
54            }
55            // Sort by signal strength.
56            int difference = WifiManager.compareSignalLevel(
57                    accessPoint2.mRssi, accessPoint1.mRssi);
58            if (difference != 0) {
59                return difference;
60            }
61            // Sort by ssid.
62            return accessPoint1.ssid.compareToIgnoreCase(accessPoint2.ssid);
63        }
64    }
65
66    static final int SECURITY_NONE = 0;
67    static final int SECURITY_WEP = 1;
68    static final int SECURITY_PSK = 2;
69    static final int SECURITY_EAP = 3;
70
71    final String ssid;
72    final int security;
73    final int networkId;
74
75    private WifiConfiguration mConfig;
76    private int mRssi;
77    private WifiInfo mInfo;
78    private DetailedState mState;
79    private ImageView mSignal;
80
81    static int getSecurity(WifiConfiguration config) {
82        if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
83            return SECURITY_PSK;
84        }
85        if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
86                config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
87            return SECURITY_EAP;
88        }
89        return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
90    }
91
92    private static int getSecurity(ScanResult result) {
93        if (result.capabilities.contains("WEP")) {
94            return SECURITY_WEP;
95        } else if (result.capabilities.contains("PSK")) {
96            return SECURITY_PSK;
97        } else if (result.capabilities.contains("EAP")) {
98            return SECURITY_EAP;
99        }
100        return SECURITY_NONE;
101    }
102
103    AccessPoint(Context context, WifiConfiguration config) {
104        super(context);
105        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
106        ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
107        security = getSecurity(config);
108        networkId = config.networkId;
109        mConfig = config;
110        mRssi = Integer.MAX_VALUE;
111    }
112
113    AccessPoint(Context context, ScanResult result) {
114        super(context);
115        setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
116        ssid = result.SSID;
117        security = getSecurity(result);
118        networkId = -1;
119        mRssi = result.level;
120    }
121
122    @Override
123    protected void onBindView(View view) {
124        setTitle(ssid);
125        mSignal = (ImageView) view.findViewById(R.id.signal);
126        if (mRssi == Integer.MAX_VALUE) {
127            mSignal.setImageDrawable(null);
128        } else {
129            mSignal.setImageResource(R.drawable.wifi_signal);
130            mSignal.setImageState((security != SECURITY_NONE) ?
131                    STATE_SECURED : STATE_NONE, true);
132        }
133        refresh();
134        super.onBindView(view);
135    }
136
137
138    boolean update(ScanResult result) {
139        // We do not call refresh() since this is called before onBindView().
140        if (ssid.equals(result.SSID) && security == getSecurity(result)) {
141            if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) {
142                mRssi = result.level;
143            }
144            return true;
145        }
146        return false;
147    }
148
149    void update(WifiInfo info, DetailedState state) {
150        boolean reorder = false;
151        if (info != null && networkId != -1 && networkId == info.getNetworkId()) {
152            reorder = (mInfo == null);
153            mRssi = info.getRssi();
154            mInfo = info;
155            mState = state;
156            refresh();
157        } else if (mInfo != null) {
158            reorder = true;
159            mInfo = null;
160            mState = null;
161            refresh();
162        }
163        if (reorder) {
164            notifyHierarchyChanged();
165        }
166    }
167
168    int getLevel() {
169        if (mRssi == Integer.MAX_VALUE) {
170            return -1;
171        }
172        return WifiManager.calculateSignalLevel(mRssi, 4);
173    }
174
175    WifiConfiguration getConfig() {
176        return mConfig;
177    }
178
179    WifiInfo getInfo() {
180        return mInfo;
181    }
182
183    DetailedState getState() {
184        return mState;
185    }
186
187    static String removeDoubleQuotes(String string) {
188        int length = string.length();
189        if ((length > 1) && (string.charAt(0) == '"')
190                && (string.charAt(length - 1) == '"')) {
191            return string.substring(1, length - 1);
192        }
193        return string;
194    }
195
196    static String convertToQuotedString(String string) {
197        return "\"" + string + "\"";
198    }
199
200    private void refresh() {
201        if (mSignal == null) {
202            return;
203        }
204        Context context = getContext();
205        mSignal.setImageLevel(getLevel());
206
207        if (mState != null) {
208            setSummary(Summary.get(context, mState));
209        } else {
210            String status = null;
211            if (mRssi == Integer.MAX_VALUE) {
212                status = context.getString(R.string.wifi_not_in_range);
213            } else if (mConfig != null) {
214                status = context.getString((mConfig.status == WifiConfiguration.Status.DISABLED) ?
215                        R.string.wifi_disabled : R.string.wifi_remembered);
216            }
217
218            if (security == SECURITY_NONE) {
219                setSummary(status);
220            } else {
221                String format = context.getString((status == null) ?
222                        R.string.wifi_secured : R.string.wifi_secured_with_status);
223                String[] type = context.getResources().getStringArray(R.array.wifi_security);
224                setSummary(String.format(format, type[security], status));
225            }
226        }
227    }
228}
229