Home | History | Annotate | Download | only in bluetooth
      1 /*
      2  * Copyright (C) 2017 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.googlecode.android_scripting.facade.bluetooth;
     18 
     19 import android.app.Service;
     20 import android.bluetooth.BluetoothAdapter;
     21 import android.bluetooth.BluetoothDevice;
     22 import android.bluetooth.BluetoothManager;
     23 import android.bluetooth.BluetoothHealth;
     24 import android.bluetooth.BluetoothHealthCallback;
     25 import android.bluetooth.BluetoothHealthAppConfiguration;
     26 import android.bluetooth.BluetoothProfile;
     27 import android.content.Context;
     28 import android.os.Bundle;
     29 import android.os.Handler;
     30 import android.os.Message;
     31 import android.os.Messenger;
     32 import android.os.ParcelFileDescriptor;
     33 import android.os.RemoteException;
     34 
     35 import com.googlecode.android_scripting.Log;
     36 import com.googlecode.android_scripting.MainThread;
     37 import com.googlecode.android_scripting.facade.EventFacade;
     38 import com.googlecode.android_scripting.facade.FacadeManager;
     39 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
     40 import com.googlecode.android_scripting.rpc.Rpc;
     41 import com.googlecode.android_scripting.rpc.RpcDeprecated;
     42 import com.googlecode.android_scripting.rpc.RpcParameter;
     43 import com.googlecode.android_scripting.rpc.RpcStopEvent;
     44 
     45 import java.lang.reflect.*;
     46 import java.util.ArrayList;
     47 import java.util.HashMap;
     48 import java.util.List;
     49 import java.util.UUID;
     50 import java.util.concurrent.Callable;
     51 
     52 public class BluetoothHealthFacade extends RpcReceiver {
     53     private final EventFacade mEventFacade;
     54     private BluetoothAdapter mBluetoothAdapter;
     55     private BluetoothManager mBluetoothManager;
     56     private final Service mService;
     57     private final Context mContext;
     58     private final HashMap<Integer, BluetoothHealthAppConfiguration> mConfigList;
     59     private static int ConfigCount;
     60     private static boolean sIsHealthReady = false;
     61     private static BluetoothHealth sHealthProfile = null;
     62 
     63     public BluetoothHealthFacade(FacadeManager manager) {
     64         super(manager);
     65         mService = manager.getService();
     66         mContext = mService.getApplicationContext();
     67         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     68         mBluetoothManager = (BluetoothManager) mContext.getSystemService(Service.BLUETOOTH_SERVICE);
     69         mBluetoothAdapter.getProfileProxy(mService, new HealthServiceListener(),
     70         BluetoothProfile.HEALTH);
     71         mEventFacade = manager.getReceiver(EventFacade.class);
     72         mConfigList = new HashMap<Integer, BluetoothHealthAppConfiguration>();
     73     }
     74 
     75 
     76     class HealthServiceListener implements BluetoothProfile.ServiceListener {
     77         @Override
     78         public void onServiceConnected(int profile, BluetoothProfile proxy) {
     79           sHealthProfile = (BluetoothHealth) proxy;
     80           sIsHealthReady = true;
     81         }
     82 
     83         @Override
     84         public void onServiceDisconnected(int profile) {
     85           sIsHealthReady = false;
     86         }
     87     }
     88 
     89     @Rpc(description = "Is Health profile ready.")
     90     public Boolean bluetoothHealthIsReady() {
     91         return sIsHealthReady;
     92     }
     93 
     94     @Rpc(description = "Connect to channel source")
     95     public boolean bluetoothHealthConnectChannelToSource(
     96             @RpcParameter(name = "configIndex") Integer configIndex,
     97             @RpcParameter(name = "macAddress") String macAddress)
     98             throws Exception {
     99         BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
    100         if (mConfigList.get(configIndex) != null) {
    101             return sHealthProfile.connectChannelToSource(mDevice, mConfigList.get(configIndex));
    102         } else {
    103             throw new Exception("Invalid configIndex input:" + Integer.toString(configIndex));
    104         }
    105     }
    106 
    107     @Rpc(description = "Connect to channel source")
    108     public boolean bluetoothHealthConnectChannelToSink(
    109             @RpcParameter(name = "configIndex") Integer configIndex,
    110             @RpcParameter(name = "macAddress") String macAddress,
    111             @RpcParameter(name = "channelType") Integer channelType)
    112             throws Exception {
    113         BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
    114         if (mConfigList.get(configIndex) != null) {
    115             return sHealthProfile.connectChannelToSink(mDevice, mConfigList.get(configIndex), channelType);
    116         } else {
    117             throw new Exception("Invalid configIndex input:" + Integer.toString(configIndex));
    118         }
    119     }
    120 
    121     @Rpc(description = "Create BluetoothHealthAppConfiguration config.")
    122     public int bluetoothHealthCreateConfig(
    123             @RpcParameter(name = "name") String name,
    124             @RpcParameter(name = "dataType") Integer dataType) throws Exception{
    125         Class btHealthAppConfigClass = Class.forName(
    126             "android.bluetooth.BluetoothHealthAppConfiguration");
    127         Constructor mConfigConstructor = btHealthAppConfigClass.getDeclaredConstructor(
    128             new Class[]{String.class, int.class});
    129         mConfigConstructor.setAccessible(true);
    130         BluetoothHealthAppConfiguration mConfig = (BluetoothHealthAppConfiguration) mConfigConstructor.newInstance(
    131             name, dataType);
    132         ConfigCount += 1;
    133         mConfigList.put(ConfigCount, mConfig);
    134         return ConfigCount;
    135     }
    136 
    137     @Rpc(description = "Register BluetoothHealthAppConfiguration config.")
    138     public int bluetoothHealthRegisterAppConfiguration(
    139             @RpcParameter(name = "name") String name,
    140             @RpcParameter(name = "dataType") Integer dataType,
    141             @RpcParameter(name = "role") Integer role) throws Exception{
    142         Class btHealthAppConfigClass = Class.forName(
    143             "android.bluetooth.BluetoothHealthAppConfiguration");
    144         Constructor[] cons = btHealthAppConfigClass.getConstructors();
    145         for (int i = 0; i < cons.length; i++) {
    146             System.out.println("constuctor: " + cons[i]);
    147         }
    148         Constructor[] cons2 = btHealthAppConfigClass.getDeclaredConstructors();
    149         for (int i = 0; i < cons2.length; i++) {
    150             System.out.println("constuctor: " + cons2[i]);
    151         }
    152         System.out.println(Integer.toString(cons.length));
    153         System.out.println(Integer.toString(cons2.length));
    154         Constructor mConfigConstructor = btHealthAppConfigClass.getDeclaredConstructor(
    155             new Class[]{String.class, int.class});
    156         mConfigConstructor.setAccessible(true);
    157         BluetoothHealthAppConfiguration mConfig = (BluetoothHealthAppConfiguration) mConfigConstructor.newInstance(
    158             name, dataType);
    159         ConfigCount += 1;
    160         mConfigList.put(ConfigCount, mConfig);
    161         return ConfigCount;
    162     }
    163 
    164     @Rpc(description = "BluetoothRegisterSinkAppConfiguration.")
    165     public void bluetoothHealthRegisterSinkAppConfiguration(
    166             @RpcParameter(name = "name") String name,
    167             @RpcParameter(name = "dataType") Integer dataType) throws Exception{
    168 
    169         sHealthProfile.registerSinkAppConfiguration(name, dataType, new MyBluetoothHealthCallback());
    170     }
    171 
    172     private class MyBluetoothHealthCallback extends BluetoothHealthCallback {
    173 
    174         @Override
    175         public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config,
    176                 int status) {
    177         }
    178 
    179         @Override
    180         public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config,
    181                 BluetoothDevice device,
    182                 int prevState,
    183                 int newState,
    184                 ParcelFileDescriptor fd,
    185                 int channelId) {
    186         }
    187     }
    188 
    189     @Override
    190     public void shutdown() {
    191         mConfigList.clear();
    192     }
    193 }
    194