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.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.wifi.WifiManager; 24 import android.os.UserHandle; 25 import android.util.Log; 26 27 import com.android.settingslib.TetherUtil; 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 private static final Intent TETHER_SERVICE_INTENT = new Intent() 38 .putExtra(TetherUtil.EXTRA_ADD_TETHER_TYPE, TetherUtil.TETHERING_WIFI) 39 .putExtra(TetherUtil.EXTRA_SET_ALARM, true) 40 .putExtra(TetherUtil.EXTRA_RUN_PROVISION, true) 41 .putExtra(TetherUtil.EXTRA_ENABLE_WIFI_TETHER, true) 42 .setComponent(TetherUtil.TETHER_SERVICE); 43 44 private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); 45 private final Receiver mReceiver = new Receiver(); 46 private final Context mContext; 47 48 private int mHotspotState; 49 50 public HotspotControllerImpl(Context context) { 51 mContext = context; 52 } 53 54 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 55 pw.println("HotspotController state:"); 56 pw.print(" mHotspotEnabled="); pw.println(stateToString(mHotspotState)); 57 } 58 59 private static String stateToString(int hotspotState) { 60 switch (hotspotState) { 61 case WifiManager.WIFI_AP_STATE_DISABLED: 62 return "DISABLED"; 63 case WifiManager.WIFI_AP_STATE_DISABLING: 64 return "DISABLING"; 65 case WifiManager.WIFI_AP_STATE_ENABLED: 66 return "ENABLED"; 67 case WifiManager.WIFI_AP_STATE_ENABLING: 68 return "ENABLING"; 69 case WifiManager.WIFI_AP_STATE_FAILED: 70 return "FAILED"; 71 } 72 return null; 73 } 74 75 public void addCallback(Callback callback) { 76 if (callback == null || mCallbacks.contains(callback)) return; 77 if (DEBUG) Log.d(TAG, "addCallback " + callback); 78 mCallbacks.add(callback); 79 mReceiver.setListening(!mCallbacks.isEmpty()); 80 } 81 82 public void removeCallback(Callback callback) { 83 if (callback == null) return; 84 if (DEBUG) Log.d(TAG, "removeCallback " + callback); 85 mCallbacks.remove(callback); 86 mReceiver.setListening(!mCallbacks.isEmpty()); 87 } 88 89 @Override 90 public boolean isHotspotEnabled() { 91 return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED; 92 } 93 94 @Override 95 public boolean isHotspotSupported() { 96 return TetherUtil.isTetheringSupported(mContext); 97 } 98 99 @Override 100 public void setHotspotEnabled(boolean enabled) { 101 // Call provisioning app which is called when enabling Tethering from Settings 102 if (enabled && TetherUtil.isProvisioningNeeded(mContext)) { 103 mContext.startServiceAsUser(TETHER_SERVICE_INTENT, UserHandle.CURRENT); 104 } else { 105 TetherUtil.setWifiTethering(enabled, mContext); 106 } 107 } 108 109 private void fireCallback(boolean isEnabled) { 110 for (Callback callback : mCallbacks) { 111 callback.onHotspotChanged(isEnabled); 112 } 113 } 114 115 private final class Receiver extends BroadcastReceiver { 116 private boolean mRegistered; 117 118 public void setListening(boolean listening) { 119 if (listening && !mRegistered) { 120 if (DEBUG) Log.d(TAG, "Registering receiver"); 121 final IntentFilter filter = new IntentFilter(); 122 filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 123 mContext.registerReceiver(this, filter); 124 mRegistered = true; 125 } else if (!listening && mRegistered) { 126 if (DEBUG) Log.d(TAG, "Unregistering receiver"); 127 mContext.unregisterReceiver(this); 128 mRegistered = false; 129 } 130 } 131 132 @Override 133 public void onReceive(Context context, Intent intent) { 134 if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction()); 135 int state = intent.getIntExtra( 136 WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED); 137 mHotspotState = state; 138 fireCallback(mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED); 139 } 140 } 141 } 142