/*
RegisterNetworkServiceDiscovery.java
Copyright (c) 2014 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.android.manager.request;
import android.content.Intent;
import org.deviceconnect.android.manager.DevicePlugin;
import org.deviceconnect.android.manager.event.EventProtocol;
import org.deviceconnect.message.DConnectMessage;
import org.deviceconnect.message.intent.message.IntentDConnectMessage;
import java.util.UUID;
import java.util.logging.Logger;
/**
* Network Service Discovery Status Change Event 登録用リクエスト.
* @author NTT DOCOMO, INC.
*/
public class RegisterNetworkServiceDiscovery extends DConnectRequest {
/** ロガー. */
private final Logger mLogger = Logger.getLogger("dconnect.manager");
/** 送信先のデバイスプラグイン. */
private DevicePlugin mDevicePlugin;
/** ロックオブジェクト. */
private final Object mLockObj = new Object();
/** リクエストコード. */
private int mRequestCode;
/**
* 送信先のデバイスプラグインを設定する.
* @param plugin デバイスプラグイン
*/
public void setDestination(final DevicePlugin plugin) {
mDevicePlugin = plugin;
}
@Override
public void setResponse(final Intent response) {
super.setResponse(response);
synchronized (mLockObj) {
mLockObj.notifyAll();
}
}
@Override
public boolean hasRequestCode(final int requestCode) {
return mRequestCode == requestCode;
}
@Override
public void run() {
// リクエストコードを作成する
mRequestCode = UUID.randomUUID().hashCode();
// リクエストを作成
Intent request = EventProtocol.createRegistrationRequestForServiceChange(mContext, mDevicePlugin);
request.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, mRequestCode);
mRequest = request;
// リクエスト送信
mContext.sendBroadcast(request);
if (mResponse == null) {
// 各デバイスのレスポンスを待つ
waitForResponse();
}
// レスポンスを解析して、処理を行う
if (mResponse != null) {
// リカバリ不可能なのでログだけ出して終了
// ここで、登録できなかった場合には、デバイス発見イベントは使用することができない。
// ただし、Service Discoveryは使用できるので問題はないと考える。
int result = getResult(mResponse);
if (result == DConnectMessage.RESULT_ERROR) {
int errorCode = getErrorCode(mResponse);
String errorMsg = getErrorMessage(mResponse);
mLogger.severe("Failed to register onservicechange event."
+ "errorCode=" + errorCode + " errorMessage=" + errorMsg);
}
} else {
sendTimeout();
}
}
/**
* resultの値をレスポンスのIntentから取得する.
* @param response レスポンスのIntent
* @return resultの値
*/
private int getResult(final Intent response) {
int result = response.getIntExtra(DConnectMessage.EXTRA_RESULT,
DConnectMessage.RESULT_ERROR);
return result;
}
/**
* エラーコードを取得する.
* @param response レスポンス
* @return エラーコード
*/
private int getErrorCode(final Intent response) {
int code = response.getIntExtra(DConnectMessage.EXTRA_ERROR_CODE,
DConnectMessage.ErrorCode.UNKNOWN.getCode());
return code;
}
/**
* エラーメッセージを取得する.
* @param response レスポンス
* @return エラーメッセージ
*/
private String getErrorMessage(final Intent response) {
String msg = response.getStringExtra(DConnectMessage.EXTRA_ERROR_MESSAGE);
return msg;
}
/**
* 各デバイスからのレスポンスを待つ.
*
* この関数から返答があるのは以下の条件になる。
* <ul>
* <li>デバイスプラグインからレスポンスがあった場合
* <li>指定された時間無いにレスポンスが返ってこない場合
* </ul>
*/
private void waitForResponse() {
synchronized (mLockObj) {
try {
mLockObj.wait(mTimeout);
} catch (InterruptedException e) {
return;
}
}
}
}