Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25704541 authored by Steve Kondik's avatar Steve Kondik Committed by Gerrit Code Review
Browse files

Merge "bluetooth networking (PAN)" into gingerbread

parents 9ecf3e88 573cdeaa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ LOCAL_SRC_FILES += \
	core/java/android/bluetooth/IBluetoothHeadset.aidl \
	core/java/android/bluetooth/IBluetoothHid.aidl \
	core/java/android/bluetooth/IBluetoothPbap.aidl \
	core/java/android/bluetooth/IBluetoothNetwork.aidl \
	core/java/android/content/IContentService.aidl \
	core/java/android/content/IIntentReceiver.aidl \
	core/java/android/content/IIntentSender.aidl \
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import android.server.BluetoothNetworkService;
import android.content.Context;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.os.IBinder;
import android.util.Log;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;

/**
 * Public API for controlling the Bluetooth Network Profile Service.
 *
 * BluetoothNetwork is a proxy object for controlling the Bluetooth Network
 * Service via IPC.
 *
 * @hide
 */
public final class BluetoothNetwork {
    private static final String TAG = "BluetoothNetwork";

    public static final int STATE_DISCONNECTED = 0;
    public static final int STATE_CONNECTING   = 1;
    public static final int STATE_CONNECTED    = 2;
    public static final int STATE_DISCONNECTING = 3;
        
    private final IBluetoothNetwork mService;

    /**
     * Create a BluetoothA2dp proxy object for interacting with the local
     * Bluetooth Network service.
     * @param c Context
     */
    public BluetoothNetwork(Context c) {
        IBinder b = ServiceManager.getService(BluetoothNetworkService.BLUETOOTH_NETWORK_SERVICE);
        if (b != null) {
            mService = IBluetoothNetwork.Stub.asInterface(b);
        } else {
            Log.w(TAG, "Bluetooth Network service not available!");
            
            // Instead of throwing an exception which prevents people from going
            // into Wireless settings in the emulator. Let it crash later when it is actually used.
            mService = null;
        }
    }

    /** Helper for converting a state to a string.
     * For debug use only - strings are not internationalized.
     * @hide
     */
    public static String stateToString(int state) {
        switch (state) {
        case STATE_DISCONNECTED:
            return "disconnected";
        case STATE_CONNECTING:
            return "connecting";
        case STATE_CONNECTED:
            return "connected";
        case STATE_DISCONNECTING:
            return "disconnecting";
        default:
            return "<unknown state " + state + ">";
        }
    }
}
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import android.bluetooth.BluetoothDevice;

/**
 * System private API for Bluetooth Network service
 *
 * {@hide}
 */
interface IBluetoothNetwork {

}
+9 −0
Original line number Diff line number Diff line
@@ -207,4 +207,13 @@ interface INetworkManagementService
     */
    int getInterfaceTxThrottle(String iface);

    /**
     * Start Bluetooth NAP service
     */
    void startPan();

    /**
     * Stop Bluetooth NAP service
     */
    void stopPan();
}
+192 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * TODO: Move this to services.jar
 * and make the contructor package private again.
 * @hide
 */

package android.server;

import java.util.ArrayList;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothNetwork;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.InterfaceConfiguration;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Slog;

public class BluetoothNetworkService extends IBluetoothNetwork.Stub {
    private static final String TAG = "BluetoothNetworkService";

    public static final String BLUETOOTH_NETWORK_SERVICE = "bluetooth_network";

    private final Context mContext;
    private final BluetoothService mBluetoothService;

    private INetworkManagementService mService;

    public BluetoothNetworkService(Context context, BluetoothService bluetoothService) {
        mContext = context;
        mBluetoothService = bluetoothService;
        if (mBluetoothService == null) {
            throw new RuntimeException("Platform does not support Bluetooth");
        }
        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        mService = INetworkManagementService.Stub.asInterface(b);

        mContext.registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {

                      ArrayList<String> available = intent.getStringArrayListExtra(
                              ConnectivityManager.EXTRA_AVAILABLE_TETHER);
                      ArrayList<String> active = intent.getStringArrayListExtra(
                              ConnectivityManager.EXTRA_ACTIVE_TETHER);
                      updateTetherState(available, active);

                    }
                },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));

        if (mBluetoothService.isEnabled())
            onBluetoothEnable();
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                               BluetoothAdapter.ERROR);
                switch (state) {
                case BluetoothAdapter.STATE_ON:
                    onBluetoothEnable();
                    break;
                case BluetoothAdapter.STATE_TURNING_OFF:
                    onBluetoothDisable();
                    break;
                }
            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                                                   BluetoothDevice.ERROR);
                switch(bondState) {
                case BluetoothDevice.BOND_BONDED:
                    break;
                case BluetoothDevice.BOND_BONDING:
                case BluetoothDevice.BOND_NONE:
                    break;
                }
            } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
            	synchronized (this) {

            	}
            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                synchronized (this) {
                }
            }
        }
    };

    private synchronized void onBluetoothEnable() {
        if(mService == null){
            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
            mService = INetworkManagementService.Stub.asInterface(b);
        }

        if(mService == null){
            log("cannot start NetworkManagementService");
            return;
        }

        try {
            mService.startPan();
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        }
    }

    private synchronized void onBluetoothDisable() {
        if(mService == null){
            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
            mService = INetworkManagementService.Stub.asInterface(b);
        }

        if(mService == null){
            log("cannot start NetworkManagementService");
            return;
        }

        try {
            mService.stopPan();
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        }
    }
    
    private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) {
        log("updating tether state");
        boolean wifiTethered = false;
        boolean wifiAvailable = false;

        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

        ConnectivityManager mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

        for (String intf : available) {
            log("interface " + intf);
            if (intf.equals("bnep0")) {
                log("configuring bnep0");
                InterfaceConfiguration ifcg = null;
                try {
                    ifcg = service.getInterfaceConfig(intf);
                    log("ifcg:" + ifcg.toString());
                    if (ifcg != null) {
                        /* IP/netmask: 192.168.43.1/255.255.255.0 */
                        ifcg.ipAddr = (192 << 24) + (168 << 16) + (43 << 8) + 1;
                        ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0;
                        ifcg.interfaceFlags = "[up broadcast multicast]";
                        service.setInterfaceConfig(intf, ifcg);
                    }
                } catch (Exception e) {
                    Slog.e(TAG, "Error configuring interface " + intf + ", :" + e);
                    return;
                }
                log("about to tether");
                if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                    Slog.e(TAG, "Error tethering "+intf);
                }
            }
        }
    }

    private static void log(String msg) {
        Log.d(TAG, msg);
    }
}
Loading