/* PebbleDeviceService.java Copyright (c) 2014 NTT DOCOMO,INC. Released under the MIT license http://opensource.org/licenses/mit-license.php */ package org.deviceconnect.android.deviceplugin.pebble; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import com.getpebble.android.kit.PebbleKit; import com.getpebble.android.kit.util.PebbleDictionary; import org.deviceconnect.android.deviceplugin.pebble.profile.PebbleSystemProfile; import org.deviceconnect.android.deviceplugin.pebble.service.PebbleService; import org.deviceconnect.android.deviceplugin.pebble.util.PebbleManager; import org.deviceconnect.android.event.EventManager; import org.deviceconnect.android.event.cache.MemoryCacheController; import org.deviceconnect.android.message.DConnectMessageService; import org.deviceconnect.android.profile.SystemProfile; import org.deviceconnect.android.service.DConnectService; import java.util.Set; import java.util.logging.Logger; /** * Pebbleデバイスプロバイダ. * @author NTT DOCOMO, INC. */ public class PebbleDeviceService extends DConnectMessageService { /** ロガー. */ private final Logger mLogger = Logger.getLogger("pebble.dplugin"); /** * Pebbleとのインターフェースを管理するクラス. */ private PebbleManager mPebbleManager; @Override public void onCreate() { // super.onCreate() の前に初期化 mPebbleManager = new PebbleManager(this); super.onCreate(); // initialize of the EventManager EventManager.INSTANCE.setController(new MemoryCacheController()); if (PebbleKit.isWatchConnected(this)) { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { for (BluetoothDevice device : adapter.getBondedDevices()) { if (device.getName().contains("Pebble")) { DConnectService service = new PebbleService(device, PebbleDeviceService.this); service.setOnline(true); getServiceProvider().addService(service); break; } } } } mPebbleManager.addConnectStatusListener(new PebbleManager.OnConnectionStatusListener() { @Override public void onConnect(final String macAddress) { String serviceId = PebbleService.createServiceId(macAddress); DConnectService service = getServiceProvider().getService(serviceId); if (service == null) { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { for (BluetoothDevice device : adapter.getBondedDevices()) { if (device.getAddress().equalsIgnoreCase(macAddress)) { service = new PebbleService(device, PebbleDeviceService.this); getServiceProvider().addService(service); break; } } } } service.setOnline(true); } @Override public void onDisconnect(final String macAddress) { String serviceId = PebbleService.createServiceId(macAddress); DConnectService service = getServiceProvider().getService(serviceId); if (service != null) { service.setOnline(false); } } }); } @Override public void onDestroy() { // Pebbleの後始末を行う mPebbleManager.destory(); super.onDestroy(); } @Override protected void onManagerUninstalled() { // Managerアンインストール検知時の処理。 if (BuildConfig.DEBUG) { mLogger.info("Plug-in : onManagerUninstalled"); } } @Override protected void onManagerTerminated() { // Manager正常終了通知受信時の処理。 if (BuildConfig.DEBUG) { mLogger.info("Plug-in : onManagerTerminated"); } } @Override protected void onManagerEventTransmitDisconnected(final String origin) { // ManagerのEvent送信経路切断通知受信時の処理。 if (BuildConfig.DEBUG) { mLogger.info("Plug-in : onManagerEventTransmitDisconnected"); } if (origin != null) { EventManager.INSTANCE.removeEvents(origin); } else { EventManager.INSTANCE.removeAll(); } } @Override protected void onDevicePluginReset() { // Device Plug-inへのReset要求受信時の処理。 if (BuildConfig.DEBUG) { mLogger.info("Plug-in : onDevicePluginReset"); } resetPluginResource(); } /** * リソースリセット処理. */ private void resetPluginResource() { /** 全イベント削除. */ EventManager.INSTANCE.removeAll(); /** Pebble バッテリー関連 イベント解放. */ sendDeleteEventToPebble(PebbleManager.PROFILE_BATTERY, PebbleManager.BATTERY_ATTRIBUTE_ON_BATTERY_CHANGE); sendDeleteEventToPebble(PebbleManager.PROFILE_BATTERY, PebbleManager.BATTERY_ATTRIBUTE_ON_CHARGING_CHANGE); /** Pebble DeviceOrientation イベント解放. */ sendDeleteEventToPebble(PebbleManager.PROFILE_DEVICE_ORIENTATION, PebbleManager.DEVICE_ORIENTATION_ATTRIBUTE_ON_DEVICE_ORIENTATION); /** Pebble KeyEvent イベント解放. */ sendDeleteEventToPebble(PebbleManager.PROFILE_KEY_EVENT, PebbleManager.KEY_EVENT_ATTRIBUTE_ON_DOWN); sendDeleteEventToPebble(PebbleManager.PROFILE_KEY_EVENT, PebbleManager.KEY_EVENT_ATTRIBUTE_ON_UP); /** System イベント解放. */ sendDeleteEventToPebble(PebbleManager.PROFILE_SYSTEM, PebbleManager.SYSTEM_ATTRIBUTE_EVENTS); } /** * PebbleへEvent停止コマンドを送信する. * @param profile プロファイル. * @param attribute 属性. */ private void sendDeleteEventToPebble(final int profile, final int attribute) { if (mPebbleManager != null) { PebbleDictionary dic = new PebbleDictionary(); dic.addInt8(PebbleManager.KEY_PROFILE, (byte) profile); dic.addInt8(PebbleManager.KEY_ATTRIBUTE, (byte) attribute); dic.addInt8(PebbleManager.KEY_ACTION, (byte) PebbleManager.ACTION_DELETE); mPebbleManager.sendCommandToPebble(dic, new PebbleManager.OnSendCommandListener() { @Override public void onReceivedData(final PebbleDictionary dic) { // do nothing. } }); } } @Override protected SystemProfile getSystemProfile() { return new PebbleSystemProfile(); } /** * Pebble管理クラスを取得する. * * @return Pebble管理クラス */ public PebbleManager getPebbleManager() { return mPebbleManager; } /** * 現在接続されているPebbleのサービスIDを取得する. * <p> * 発見されない場合にはnullを返却する。 * </p> * <p> * Pebbleが複数台接続されたときの挙動が不明。<br/> * PebbleKitでは、命令を識別して出す機能はない。<br/> * 基本は1対1で考える。<br/> * </p> * @return サービスID */ public String getServiceId() { BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter(); Set<BluetoothDevice> bondedDevices = defaultAdapter.getBondedDevices(); if (bondedDevices.size() > 0) { for (BluetoothDevice device : bondedDevices) { String deviceName = device.getName(); if (deviceName.contains("Pebble")) { return PebbleService.createServiceId(device); } } } return null; } }