• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.bluetooth;
18 
19 import android.content.Context;
20 import android.net.ConnectivityManager;
21 import android.net.DhcpInfoInternal;
22 import android.net.LinkCapabilities;
23 import android.net.LinkProperties;
24 import android.net.NetworkInfo;
25 import android.net.NetworkInfo.DetailedState;
26 import android.net.NetworkStateTracker;
27 import android.net.NetworkUtils;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.util.Log;
31 
32 import java.util.concurrent.atomic.AtomicBoolean;
33 import java.util.concurrent.atomic.AtomicInteger;
34 
35 /**
36  * This class tracks the data connection associated with Bluetooth
37  * reverse tethering. This is a singleton class and an instance will be
38  * created by ConnectivityService. BluetoothService will call into this
39  * when a reverse tethered connection needs to be activated.
40  *
41  * @hide
42  */
43 public class BluetoothTetheringDataTracker implements NetworkStateTracker {
44     private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
45     private static final String TAG = "BluetoothTethering";
46 
47     private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
48     private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
49     private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
50     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
51 
52     private LinkProperties mLinkProperties;
53     private LinkCapabilities mLinkCapabilities;
54     private NetworkInfo mNetworkInfo;
55 
56     private BluetoothPan mBluetoothPan;
57     private BluetoothDevice mDevice;
58     private static String mIface;
59 
60     /* For sending events to connectivity service handler */
61     private Handler mCsHandler;
62     private Context mContext;
63     public static BluetoothTetheringDataTracker sInstance;
64 
BluetoothTetheringDataTracker()65     private BluetoothTetheringDataTracker() {
66         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_BLUETOOTH, 0, NETWORKTYPE, "");
67         mLinkProperties = new LinkProperties();
68         mLinkCapabilities = new LinkCapabilities();
69 
70         mNetworkInfo.setIsAvailable(false);
71         setTeardownRequested(false);
72     }
73 
getInstance()74     public static synchronized BluetoothTetheringDataTracker getInstance() {
75         if (sInstance == null) sInstance = new BluetoothTetheringDataTracker();
76         return sInstance;
77     }
78 
Clone()79     public Object Clone() throws CloneNotSupportedException {
80         throw new CloneNotSupportedException();
81     }
82 
setTeardownRequested(boolean isRequested)83     public void setTeardownRequested(boolean isRequested) {
84         mTeardownRequested.set(isRequested);
85     }
86 
isTeardownRequested()87     public boolean isTeardownRequested() {
88         return mTeardownRequested.get();
89     }
90 
91     /**
92      * Begin monitoring connectivity
93      */
startMonitoring(Context context, Handler target)94     public void startMonitoring(Context context, Handler target) {
95         mContext = context;
96         mCsHandler = target;
97         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
98         if (adapter != null) {
99             adapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.PAN);
100         }
101     }
102 
103     private BluetoothProfile.ServiceListener mProfileServiceListener =
104         new BluetoothProfile.ServiceListener() {
105         public void onServiceConnected(int profile, BluetoothProfile proxy) {
106             mBluetoothPan = (BluetoothPan) proxy;
107         }
108         public void onServiceDisconnected(int profile) {
109             mBluetoothPan = null;
110         }
111     };
112 
113     /**
114      * Disable connectivity to a network
115      * TODO: do away with return value after making MobileDataStateTracker async
116      */
teardown()117     public boolean teardown() {
118         mTeardownRequested.set(true);
119         if (mBluetoothPan != null) {
120             for (BluetoothDevice device: mBluetoothPan.getConnectedDevices()) {
121                 mBluetoothPan.disconnect(device);
122             }
123         }
124         return true;
125     }
126 
127     /**
128      * Re-enable connectivity to a network after a {@link #teardown()}.
129      */
reconnect()130     public boolean reconnect() {
131         mTeardownRequested.set(false);
132         //Ignore
133         return true;
134     }
135 
136     /**
137      * Turn the wireless radio off for a network.
138      * @param turnOn {@code true} to turn the radio on, {@code false}
139      */
setRadio(boolean turnOn)140     public boolean setRadio(boolean turnOn) {
141         return true;
142     }
143 
144     /**
145      * @return true - If are we currently tethered with another device.
146      */
isAvailable()147     public synchronized boolean isAvailable() {
148         return mNetworkInfo.isAvailable();
149     }
150 
151     /**
152      * Tells the underlying networking system that the caller wants to
153      * begin using the named feature. The interpretation of {@code feature}
154      * is completely up to each networking implementation.
155      * @param feature the name of the feature to be used
156      * @param callingPid the process ID of the process that is issuing this request
157      * @param callingUid the user ID of the process that is issuing this request
158      * @return an integer value representing the outcome of the request.
159      * The interpretation of this value is specific to each networking
160      * implementation+feature combination, except that the value {@code -1}
161      * always indicates failure.
162      * TODO: needs to go away
163      */
startUsingNetworkFeature(String feature, int callingPid, int callingUid)164     public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
165         return -1;
166     }
167 
168     /**
169      * Tells the underlying networking system that the caller is finished
170      * using the named feature. The interpretation of {@code feature}
171      * is completely up to each networking implementation.
172      * @param feature the name of the feature that is no longer needed.
173      * @param callingPid the process ID of the process that is issuing this request
174      * @param callingUid the user ID of the process that is issuing this request
175      * @return an integer value representing the outcome of the request.
176      * The interpretation of this value is specific to each networking
177      * implementation+feature combination, except that the value {@code -1}
178      * always indicates failure.
179      * TODO: needs to go away
180      */
stopUsingNetworkFeature(String feature, int callingPid, int callingUid)181     public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
182         return -1;
183     }
184 
185     @Override
setUserDataEnable(boolean enabled)186     public void setUserDataEnable(boolean enabled) {
187         Log.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
188     }
189 
190     @Override
setPolicyDataEnable(boolean enabled)191     public void setPolicyDataEnable(boolean enabled) {
192         Log.w(TAG, "ignoring setPolicyDataEnable(" + enabled + ")");
193     }
194 
195     /**
196      * Check if private DNS route is set for the network
197      */
isPrivateDnsRouteSet()198     public boolean isPrivateDnsRouteSet() {
199         return mPrivateDnsRouteSet.get();
200     }
201 
202     /**
203      * Set a flag indicating private DNS route is set
204      */
privateDnsRouteSet(boolean enabled)205     public void privateDnsRouteSet(boolean enabled) {
206         mPrivateDnsRouteSet.set(enabled);
207     }
208 
209     /**
210      * Fetch NetworkInfo for the network
211      */
getNetworkInfo()212     public synchronized NetworkInfo getNetworkInfo() {
213         return mNetworkInfo;
214     }
215 
216     /**
217      * Fetch LinkProperties for the network
218      */
getLinkProperties()219     public synchronized LinkProperties getLinkProperties() {
220         return new LinkProperties(mLinkProperties);
221     }
222 
223    /**
224      * A capability is an Integer/String pair, the capabilities
225      * are defined in the class LinkSocket#Key.
226      *
227      * @return a copy of this connections capabilities, may be empty but never null.
228      */
getLinkCapabilities()229     public LinkCapabilities getLinkCapabilities() {
230         return new LinkCapabilities(mLinkCapabilities);
231     }
232 
233     /**
234      * Fetch default gateway address for the network
235      */
getDefaultGatewayAddr()236     public int getDefaultGatewayAddr() {
237         return mDefaultGatewayAddr.get();
238     }
239 
240     /**
241      * Check if default route is set
242      */
isDefaultRouteSet()243     public boolean isDefaultRouteSet() {
244         return mDefaultRouteSet.get();
245     }
246 
247     /**
248      * Set a flag indicating default route is set for the network
249      */
defaultRouteSet(boolean enabled)250     public void defaultRouteSet(boolean enabled) {
251         mDefaultRouteSet.set(enabled);
252     }
253 
254     /**
255      * Return the system properties name associated with the tcp buffer sizes
256      * for this network.
257      */
getTcpBufferSizesPropName()258     public String getTcpBufferSizesPropName() {
259         return "net.tcp.buffersize.wifi";
260     }
261 
262 
startReverseTether(String iface, BluetoothDevice device)263     public synchronized void startReverseTether(String iface, BluetoothDevice device) {
264         mIface = iface;
265         mDevice = device;
266         Thread dhcpThread = new Thread(new Runnable() {
267             public void run() {
268                 //TODO(): Add callbacks for failure and success case.
269                 //Currently this thread runs independently.
270                 DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
271                 if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
272                     Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
273                     return;
274                 }
275                 mLinkProperties = dhcpInfoInternal.makeLinkProperties();
276                 mLinkProperties.setInterfaceName(mIface);
277 
278                 mNetworkInfo.setIsAvailable(true);
279                 mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
280 
281                 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
282                 msg.sendToTarget();
283 
284                 msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
285                 msg.sendToTarget();
286             }
287         });
288         dhcpThread.start();
289     }
290 
stopReverseTether(String iface)291     public synchronized void stopReverseTether(String iface) {
292         NetworkUtils.stopDhcp(iface);
293 
294         mLinkProperties.clear();
295         mNetworkInfo.setIsAvailable(false);
296         mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
297 
298         Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
299         msg.sendToTarget();
300 
301         msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
302         msg.sendToTarget();
303     }
304 
setDependencyMet(boolean met)305     public void setDependencyMet(boolean met) {
306         // not supported on this network
307     }
308 }
309