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 17 package com.android.systemui.statusbar.policy; 18 19 import android.app.ActivityManager; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.net.ConnectivityManager; 25 import android.net.wifi.WifiManager; 26 import android.os.UserManager; 27 import android.util.Log; 28 29 import java.io.FileDescriptor; 30 import java.io.PrintWriter; 31 import java.util.ArrayList; 32 33 public class HotspotControllerImpl implements HotspotController { 34 35 private static final String TAG = "HotspotController"; 36 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 37 38 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); 39 private final Receiver mReceiver = new Receiver(); 40 private final ConnectivityManager mConnectivityManager; 41 private final Context mContext; 42 43 private int mHotspotState; 44 45 public HotspotControllerImpl(Context context) { 46 mContext = context; 47 mConnectivityManager = (ConnectivityManager) context.getSystemService( 48 Context.CONNECTIVITY_SERVICE); 49 } 50 51 @Override 52 public boolean isHotspotSupported() { 53 return mConnectivityManager.isTetheringSupported() 54 && mConnectivityManager.getTetherableWifiRegexs().length != 0 55 && UserManager.get(mContext).isUserAdmin(ActivityManager.getCurrentUser()); 56 } 57 58 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 59 pw.println("HotspotController state:"); 60 pw.print(" mHotspotEnabled="); pw.println(stateToString(mHotspotState)); 61 } 62 63 private static String stateToString(int hotspotState) { 64 switch (hotspotState) { 65 case WifiManager.WIFI_AP_STATE_DISABLED: 66 return "DISABLED"; 67 case WifiManager.WIFI_AP_STATE_DISABLING: 68 return "DISABLING"; 69 case WifiManager.WIFI_AP_STATE_ENABLED: 70 return "ENABLED"; 71 case WifiManager.WIFI_AP_STATE_ENABLING: 72 return "ENABLING"; 73 case WifiManager.WIFI_AP_STATE_FAILED: 74 return "FAILED"; 75 } 76 return null; 77 } 78 79 @Override 80 public void addCallback(Callback callback) { 81 synchronized (mCallbacks) { 82 if (callback == null || mCallbacks.contains(callback)) return; 83 if (DEBUG) Log.d(TAG, "addCallback " + callback); 84 mCallbacks.add(callback); 85 mReceiver.setListening(!mCallbacks.isEmpty()); 86 } 87 } 88 89 @Override 90 public void removeCallback(Callback callback) { 91 if (callback == null) return; 92 if (DEBUG) Log.d(TAG, "removeCallback " + callback); 93 synchronized (mCallbacks) { 94 mCallbacks.remove(callback); 95 mReceiver.setListening(!mCallbacks.isEmpty()); 96 } 97 } 98 99 @Override 100 public boolean isHotspotEnabled() { 101 return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED; 102 } 103 104 static final class OnStartTetheringCallback extends 105 ConnectivityManager.OnStartTetheringCallback { 106 @Override 107 public void onTetheringStarted() {} 108 @Override 109 public void onTetheringFailed() { 110 // TODO: Show error. 111 } 112 } 113 114 @Override 115 public void setHotspotEnabled(boolean enabled) { 116 if (enabled) { 117 OnStartTetheringCallback callback = new OnStartTetheringCallback(); 118 mConnectivityManager.startTethering( 119 ConnectivityManager.TETHERING_WIFI, false, callback); 120 } else { 121 mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI); 122 } 123 } 124 125 private void fireCallback(boolean isEnabled) { 126 synchronized (mCallbacks) { 127 for (Callback callback : mCallbacks) { 128 callback.onHotspotChanged(isEnabled); 129 } 130 } 131 } 132 133 private final class Receiver extends BroadcastReceiver { 134 private boolean mRegistered; 135 136 public void setListening(boolean listening) { 137 if (listening && !mRegistered) { 138 if (DEBUG) Log.d(TAG, "Registering receiver"); 139 final IntentFilter filter = new IntentFilter(); 140 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 141 mContext.registerReceiver(this, filter); 142 mRegistered = true; 143 } else if (!listening && mRegistered) { 144 if (DEBUG) Log.d(TAG, "Unregistering receiver"); 145 mContext.unregisterReceiver(this); 146 mRegistered = false; 147 } 148 } 149 150 @Override 151 public void onReceive(Context context, Intent intent) { 152 if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction()); 153 int state = intent.getIntExtra( 154 WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED); 155 mHotspotState = state; 156 fireCallback(mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED); 157 } 158 } 159 } 160