1/*
2 * Copyright (C) 2014 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.systemui.statusbar.policy;
18
19import android.app.ActivityManager;
20import android.content.Context;
21import android.content.Intent;
22import android.net.wifi.WifiManager.ActionListener;
23import android.os.Looper;
24import android.os.UserHandle;
25import android.os.UserManager;
26import android.provider.Settings;
27import android.util.Log;
28
29import com.android.settingslib.wifi.AccessPoint;
30import com.android.settingslib.wifi.WifiTracker;
31import com.android.settingslib.wifi.WifiTracker.WifiListener;
32import com.android.systemui.R;
33
34import java.io.PrintWriter;
35import java.util.ArrayList;
36import java.util.List;
37
38public class AccessPointControllerImpl
39        implements NetworkController.AccessPointController, WifiListener {
40    private static final String TAG = "AccessPointController";
41    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
42
43    // This string extra specifies a network to open the connect dialog on, so the user can enter
44    // network credentials.  This is used by quick settings for secured networks.
45    private static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid";
46
47    private static final int[] ICONS = {
48        R.drawable.ic_qs_wifi_full_0,
49        R.drawable.ic_qs_wifi_full_1,
50        R.drawable.ic_qs_wifi_full_2,
51        R.drawable.ic_qs_wifi_full_3,
52        R.drawable.ic_qs_wifi_full_4,
53    };
54
55    private final Context mContext;
56    private final ArrayList<AccessPointCallback> mCallbacks = new ArrayList<AccessPointCallback>();
57    private final WifiTracker mWifiTracker;
58    private final UserManager mUserManager;
59
60    private int mCurrentUser;
61
62    public AccessPointControllerImpl(Context context, Looper bgLooper) {
63        mContext = context;
64        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
65        mWifiTracker = new WifiTracker(context, this, bgLooper, false, true);
66        mCurrentUser = ActivityManager.getCurrentUser();
67    }
68
69    public boolean canConfigWifi() {
70        return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI,
71                new UserHandle(mCurrentUser));
72    }
73
74    public void onUserSwitched(int newUserId) {
75        mCurrentUser = newUserId;
76    }
77
78    @Override
79    public void addAccessPointCallback(AccessPointCallback callback) {
80        if (callback == null || mCallbacks.contains(callback)) return;
81        if (DEBUG) Log.d(TAG, "addCallback " + callback);
82        mCallbacks.add(callback);
83        if (mCallbacks.size() == 1) {
84            mWifiTracker.startTracking();
85        }
86    }
87
88    @Override
89    public void removeAccessPointCallback(AccessPointCallback callback) {
90        if (callback == null) return;
91        if (DEBUG) Log.d(TAG, "removeCallback " + callback);
92        mCallbacks.remove(callback);
93        if (mCallbacks.isEmpty()) {
94            mWifiTracker.stopTracking();
95        }
96    }
97
98    @Override
99    public void scanForAccessPoints() {
100        if (DEBUG) Log.d(TAG, "scan!");
101        mWifiTracker.forceScan();
102    }
103
104    @Override
105    public int getIcon(AccessPoint ap) {
106        int level = ap.getLevel();
107        return ICONS[level >= 0 ? level : 0];
108    }
109
110    public boolean connect(AccessPoint ap) {
111        if (ap == null) return false;
112        if (DEBUG) Log.d(TAG, "connect networkId=" + ap.getConfig().networkId);
113        if (ap.isSaved()) {
114            mWifiTracker.getManager().connect(ap.getConfig().networkId, mConnectListener);
115        } else {
116            // Unknown network, need to add it.
117            if (ap.getSecurity() != AccessPoint.SECURITY_NONE) {
118                Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
119                intent.putExtra(EXTRA_START_CONNECT_SSID, ap.getSsidStr());
120                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
121                fireSettingsIntentCallback(intent);
122                return true;
123            } else {
124                ap.generateOpenNetworkConfig();
125                mWifiTracker.getManager().connect(ap.getConfig(), mConnectListener);
126            }
127        }
128        return false;
129    }
130
131    private void fireSettingsIntentCallback(Intent intent) {
132        for (AccessPointCallback callback : mCallbacks) {
133            callback.onSettingsActivityTriggered(intent);
134        }
135    }
136
137    private void fireAcccessPointsCallback(List<AccessPoint> aps) {
138        for (AccessPointCallback callback : mCallbacks) {
139            callback.onAccessPointsChanged(aps);
140        }
141    }
142
143    public void dump(PrintWriter pw) {
144        mWifiTracker.dump(pw);
145    }
146
147    @Override
148    public void onWifiStateChanged(int state) {
149    }
150
151    @Override
152    public void onConnectedChanged() {
153        fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
154    }
155
156    @Override
157    public void onAccessPointsChanged() {
158        fireAcccessPointsCallback(mWifiTracker.getAccessPoints());
159    }
160
161    private final ActionListener mConnectListener = new ActionListener() {
162        @Override
163        public void onSuccess() {
164            if (DEBUG) Log.d(TAG, "connect success");
165        }
166
167        @Override
168        public void onFailure(int reason) {
169            if (DEBUG) Log.d(TAG, "connect failure reason=" + reason);
170        }
171    };
172}
173