Home | History | Annotate | Download | only in policy
      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