/*
IntentDConnectSDKTest.java
Copyright (c) 2016 NTT DOCOMO,INC.
Released under the MIT license
http://opensource.org/licenses/mit-license.php
*/
package org.deviceconnect.message;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.deviceconnect.message.entity.FileEntity;
import org.deviceconnect.message.entity.MultipartEntity;
import org.deviceconnect.message.entity.StringEntity;
import org.deviceconnect.message.intent.message.IntentDConnectMessage;
import org.deviceconnect.message.server.TestBroadcastReceiver;
import org.deviceconnect.message.server.TestService;
import org.deviceconnect.profile.AuthorizationProfileConstants;
import org.deviceconnect.profile.AvailabilityProfileConstants;
import org.deviceconnect.profile.DConnectProfileConstants;
import org.deviceconnect.profile.DeviceOrientationProfileConstants;
import org.deviceconnect.profile.ServiceDiscoveryProfileConstants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import static junit.framework.Assert.fail;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
/**
* IntentDConnectSDKのテスト.
*
* @author NTT DOCOMO, INC.
*/
@RunWith(AndroidJUnit4.class)
public class IntentDConnectSDKTest {
private TestService mService;
private CountDownLatch mCountDownLatch = new CountDownLatch(1);
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(final ComponentName className, final IBinder service) {
mService = ((TestService.BindServiceBinder) service).getService();
mCountDownLatch.countDown();
}
@Override
public void onServiceDisconnected(final ComponentName className) {
mService = null;
}
};
private void bind() {
Context context = InstrumentationRegistry.getTargetContext();
context.bindService(new Intent(context, TestService.class),
mConnection,
Context.BIND_AUTO_CREATE
);
try {
mCountDownLatch.await(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail("error.");
}
}
private void unbind() {
Context context = InstrumentationRegistry.getTargetContext();
context.unbindService(mConnection);
}
private DConnectSDK getSDK() {
Context context = InstrumentationRegistry.getTargetContext();
String packageName = context.getPackageName();
DConnectSDK sdk = DConnectSDKFactory.create(context, DConnectSDKFactory.Type.INTENT);
IntentDConnectSDK intentSDK = (IntentDConnectSDK)sdk;
intentSDK.setManagerPackageName(packageName);
intentSDK.setManagerClassName(TestBroadcastReceiver.class.getName());
return intentSDK;
}
private void writeFile(final File file, final byte[] data) {
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(data);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private byte[] getFile(final File file) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
int len;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
fis.close();
} catch (IOException e) {
return null;
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return out.toByteArray();
}
@Before
public void setUp() {
bind();
}
@After
public void tearDown() {
unbind();
}
/**
* availabilityを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・productにtest-managerが返却されること。
* ・versionに1.1が返却されること。
* ・nameにmanagerが返却されること。
* ・uuidにuuidが返却されること。
* </pre>
*/
@Test
public void availability() {
final String version = "1.1";
final String product = "test";
final String name = "name";
final String uuid = "uuid";
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AvailabilityProfileConstants.PARAM_NAME, name);
response.putExtra(AvailabilityProfileConstants.PARAM_UUID, uuid);
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
DConnectResponseMessage response = sdk.availability();
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(DConnectProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(DConnectProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_NAME), is(name));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_UUID), is(uuid));
}
/**
* 非同期にavailabilityを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・productにtest-managerが返却されること。
* ・versionに1.1が返却されること。
* ・nameにmanagerが返却されること。
* ・uuidにuuidが返却されること。
* </pre>
*/
@Test
public void availability_listener() {
final String version = "1.1";
final String product = "test";
final String name = "name";
final String uuid = "uuid";
final AtomicReference<DConnectResponseMessage> result = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AvailabilityProfileConstants.PARAM_NAME, name);
response.putExtra(AvailabilityProfileConstants.PARAM_UUID, uuid);
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
sdk.availability(new DConnectSDK.OnResponseListener() {
@Override
public void onResponse(final DConnectResponseMessage response) {
result.set(response);
latch.countDown();
}
});
try {
latch.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail("timeout");
}
DConnectResponseMessage response = result.get();
assertThat(response, is(notNullValue()));
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(DConnectProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(DConnectProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_NAME), is(name));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_UUID), is(uuid));
}
/**
* authorizationを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・OnResponseListenerにDConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・versionに1.1が返却されること。
* ・accessTokenにtest-accessTokeが返却されること。
* ・expireに1999が返却されること。
* ・scopesに配列が返却されること。
* </pre>
*/
@Test
public void authorization() {
final String appName = "test";
final String version = "1.1";
final String product = "test-manager";
final String clientId = "test-clientId";
final String accessToken = "test-accessToken";
final String profile = "battery";
final int expirePeriod = 1000;
final int expire = 1999;
final String[] scopes = {
"serviceDiscovery",
"serviceInformation",
"battery"
};
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
String p = intent.getStringExtra(IntentDConnectMessage.EXTRA_PROFILE);
String a = intent.getStringExtra(IntentDConnectMessage.EXTRA_ATTRIBUTE);
if (!AuthorizationProfileConstants.PROFILE_NAME.equalsIgnoreCase(p)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else if (AuthorizationProfileConstants.ATTRIBUTE_GRANT.equalsIgnoreCase(a)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AuthorizationProfileConstants.PARAM_CLIENT_ID, clientId);
} else if (AuthorizationProfileConstants.ATTRIBUTE_ACCESS_TOKEN.equalsIgnoreCase(a)) {
String cid = intent.getStringExtra(AuthorizationProfileConstants.PARAM_CLIENT_ID);
if (!clientId.equals(cid)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
List<Bundle> scopes = new ArrayList<>();
Bundle scope1 = new Bundle();
scope1.putString(AuthorizationProfileConstants.PARAM_SCOPE, profile);
scope1.putLong(AuthorizationProfileConstants.PARAM_EXPIRE_PERIOD, expirePeriod);
scopes.add(scope1);
Bundle[] s = new Bundle[scopes.size()];
scopes.toArray(s);
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AuthorizationProfileConstants.PARAM_ACCESS_TOKEN, accessToken);
response.putExtra(AuthorizationProfileConstants.PARAM_SCOPES, s);
response.putExtra(AuthorizationProfileConstants.PARAM_EXPIRE, expire);
}
}
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
DConnectResponseMessage response = sdk.authorization(appName, scopes);
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(DConnectProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(DConnectProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AuthorizationProfileConstants.PARAM_ACCESS_TOKEN), is(accessToken));
assertThat(response.getInt(AuthorizationProfileConstants.PARAM_EXPIRE), is(expire));
assertThat(response.getList(AuthorizationProfileConstants.PARAM_SCOPES), is(notNullValue()));
}
/**
* 非同期にauthorizationを呼び出し、clientIdとaccessTokenが取得できることを確認する。
* <pre>
* 【期待する動作】
* ・OnResponseListenerにDConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・versionに1.1が返却されること。
* ・accessTokenにtest-accessTokeが返却されること。
* ・expireに1999が返却されること。
* ・scopesに配列が返却されること。
* </pre>
*/
@Test
public void authorization_listener() {
final String appName = "test";
final String version = "1.1";
final String product = "test-manager";
final String clientId = "test-clientId";
final String accessToken = "test-accessToken";
final String profile = "battery";
final int expirePeriod = 1000;
final int expire = 1999;
final String[] scopes = {
"serviceDiscovery",
"serviceInformation",
"battery"
};
final AtomicReference<String> resultClientId = new AtomicReference<>();
final AtomicReference<String> resultAccessToken = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
String p = intent.getStringExtra(IntentDConnectMessage.EXTRA_PROFILE);
String a = intent.getStringExtra(IntentDConnectMessage.EXTRA_ATTRIBUTE);
if (!AuthorizationProfileConstants.PROFILE_NAME.equalsIgnoreCase(p)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else if (AuthorizationProfileConstants.ATTRIBUTE_GRANT.equalsIgnoreCase(a)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AuthorizationProfileConstants.PARAM_CLIENT_ID, clientId);
} else if (AuthorizationProfileConstants.ATTRIBUTE_ACCESS_TOKEN.equalsIgnoreCase(a)) {
String cid = intent.getStringExtra(AuthorizationProfileConstants.PARAM_CLIENT_ID);
if (!clientId.equals(cid)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
List<Bundle> scopes = new ArrayList<>();
Bundle scope1 = new Bundle();
scope1.putString(AuthorizationProfileConstants.PARAM_SCOPE, profile);
scope1.putLong(AuthorizationProfileConstants.PARAM_EXPIRE_PERIOD, expirePeriod);
scopes.add(scope1);
Bundle[] s = new Bundle[scopes.size()];
scopes.toArray(s);
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AuthorizationProfileConstants.PARAM_ACCESS_TOKEN, accessToken);
response.putExtra(AuthorizationProfileConstants.PARAM_SCOPES, s);
response.putExtra(AuthorizationProfileConstants.PARAM_EXPIRE, expire);
}
}
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
sdk.authorization(appName, scopes, new DConnectSDK.OnAuthorizationListener() {
@Override
public void onResponse(String clientId, String accessToken) {
resultClientId.set(clientId);
resultAccessToken.set(accessToken);
latch.countDown();
}
@Override
public void onError(int errorCode, String errorMessage) {
latch.countDown();
}
});
try {
latch.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail("timeout");
}
assertThat(resultClientId.get(), is(clientId));
assertThat(resultAccessToken.get(), is(accessToken));
}
/**
* serviceDiscoveryを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・versionに1.1が返却されること。
* ・servicesに配列が返却されること。
* ・servicesの中身に指定されたデバイス情報が格納されていること。
* </pre>
*/
@Test
public void serviceDiscovery() {
final String version = "1.1";
final String product = "test-manager";
final String accessToken = "test-accessToken";
final String[][] aservices = {
{
"serviceId1",
"test-service1",
ServiceDiscoveryProfileConstants.NetworkType.WIFI.getValue(),
"true",
"config1"
}
};
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
String p = intent.getStringExtra(IntentDConnectMessage.EXTRA_PROFILE);
if (!ServiceDiscoveryProfileConstants.PROFILE_NAME.equalsIgnoreCase(p)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
List<Bundle> services = new ArrayList<>();
for (String[] a : aservices) {
Bundle service = new Bundle();
service.putString(ServiceDiscoveryProfileConstants.PARAM_ID, a[0]);
service.putString(ServiceDiscoveryProfileConstants.PARAM_NAME, a[1]);
service.putString(ServiceDiscoveryProfileConstants.PARAM_TYPE, a[2]);
service.putBoolean(ServiceDiscoveryProfileConstants.PARAM_ONLINE, "true".equals(a[3]));
service.putString(ServiceDiscoveryProfileConstants.PARAM_CONFIG, a[4]);
services.add(service);
}
Bundle[] ss = new Bundle[services.size()];
services.toArray(ss);
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(ServiceDiscoveryProfileConstants.PARAM_SERVICES, ss);
}
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
sdk.setAccessToken(accessToken);
DConnectResponseMessage response = sdk.serviceDiscovery();
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getList(ServiceDiscoveryProfileConstants.PARAM_SERVICES), is(notNullValue()));
int idx = 0;
for (Object obj : response.getList(ServiceDiscoveryProfileConstants.PARAM_SERVICES)) {
Map service = (Map) obj;
String id = (String) service.get(ServiceDiscoveryProfileConstants.PARAM_ID);
String name = (String) service.get(ServiceDiscoveryProfileConstants.PARAM_NAME);
assertThat(id, is(aservices[idx][0]));
assertThat(name, is(aservices[idx][1]));
}
}
/**
* 非同期にserviceDiscoveryを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・versionに1.1が返却されること。
* ・servicesに配列が返却されること。
* ・servicesの中身に指定されたデバイス情報が格納されていること。
* </pre>
*/
@Test
public void serviceDiscovery_listener() {
final String version = "1.1";
final String product = "test-manager";
final String accessToken = "test-accessToken";
final String[][] aservices = {
{
"serviceId1",
"test-service1",
ServiceDiscoveryProfileConstants.NetworkType.WIFI.getValue(),
"true",
"config1"
}
};
final AtomicReference<DConnectResponseMessage> result = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
String p = intent.getStringExtra(IntentDConnectMessage.EXTRA_PROFILE);
if (!ServiceDiscoveryProfileConstants.PROFILE_NAME.equalsIgnoreCase(p)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
List<Bundle> services = new ArrayList<>();
for (String[] a : aservices) {
Bundle service = new Bundle();
service.putString(ServiceDiscoveryProfileConstants.PARAM_ID, a[0]);
service.putString(ServiceDiscoveryProfileConstants.PARAM_NAME, a[1]);
service.putString(ServiceDiscoveryProfileConstants.PARAM_TYPE, a[2]);
service.putBoolean(ServiceDiscoveryProfileConstants.PARAM_ONLINE, "true".equals(a[3]));
service.putString(ServiceDiscoveryProfileConstants.PARAM_CONFIG, a[4]);
services.add(service);
}
Bundle[] ss = new Bundle[services.size()];
services.toArray(ss);
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(ServiceDiscoveryProfileConstants.PARAM_SERVICES, ss);
}
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
sdk.setAccessToken(accessToken);
sdk.serviceDiscovery(new DConnectSDK.OnResponseListener() {
@Override
public void onResponse(final DConnectResponseMessage response) {
result.set(response);
latch.countDown();
}
});
try {
latch.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail("timeout");
}
DConnectResponseMessage response = result.get();
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getList(ServiceDiscoveryProfileConstants.PARAM_SERVICES), is(notNullValue()));
int idx = 0;
for (Object obj : response.getList(ServiceDiscoveryProfileConstants.PARAM_SERVICES)) {
Map service = (Map) obj;
String id = (String) service.get(ServiceDiscoveryProfileConstants.PARAM_ID);
String name = (String) service.get(ServiceDiscoveryProfileConstants.PARAM_NAME);
assertThat(id, is(aservices[idx][0]));
assertThat(name, is(aservices[idx][1]));
}
}
/**
* getを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・productにtest-managerが返却されること。
* ・versionに1.1が返却されること。
* ・nameにmanagerが返却されること。
* ・uuidにuuidが返却されること。
* </pre>
*/
@Test
public void get() {
final String version = "1.1";
final String product = "test";
final String name = "name";
final String uuid = "uuid";
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "action is invalid.");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AvailabilityProfileConstants.PARAM_NAME, name);
response.putExtra(AvailabilityProfileConstants.PARAM_UUID, uuid);
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
DConnectResponseMessage response = sdk.get("http://localhost:4035/gotapi/availability");
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(DConnectProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(DConnectProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_NAME), is(name));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_UUID), is(uuid));
}
/**
* uriにnullを設定して、getを呼び出す。
* <pre>
* 【期待する動作】
* ・NullPointerExceptionが発生すること。
* </pre>
*/
@Test(expected = NullPointerException.class)
public void get_uri_null() {
DConnectSDK sdk = getSDK();
sdk.get((Uri) null);
}
/**
* uriにから文字列を設定して、getを呼び出す。
* <pre>
* 【期待する動作】
* ・IllegalArgumentExceptionが発生すること。
* </pre>
*/
@Test(expected = IllegalArgumentException.class)
public void get_uri_empty() {
DConnectSDK sdk = getSDK();
sdk.get("");
}
/**
* uriにから不正なURIを設定して、getを呼び出す。
* <pre>
* 【期待する動作】
* ・IllegalArgumentExceptionが発生すること。
* </pre>
*/
@Test(expected = IllegalArgumentException.class)
public void get_uri_illegal() {
DConnectSDK sdk = getSDK();
sdk.get("test");
}
/**
* getを呼び出し、OnResponseListenerにレスポンスが通知されることを確認する。
* <pre>
* 【期待する動作】
* ・OnResponseListenerにDConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・productにtest-managerが返却されること。
* ・versionに1.1が返却されること。
* ・nameにmanagerが返却されること。
* ・uuidにuuidが返却されること。
* </pre>
*/
@Test
public void get_listener() {
final CountDownLatch latch = new CountDownLatch(1);
final String version = "1.1";
final String product = "test-manager";
final String name = "manager";
final String uuid = "uuid";
final AtomicReference<DConnectResponseMessage> result = new AtomicReference<>();
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_GET)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "action is invalid.");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AvailabilityProfileConstants.PARAM_NAME, name);
response.putExtra(AvailabilityProfileConstants.PARAM_UUID, uuid);
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
sdk.get("http://localhost:4035/gotapi/availability", new DConnectSDK.OnResponseListener() {
@Override
public void onResponse(final DConnectResponseMessage response) {
result.set(response);
latch.countDown();
}
});
try {
latch.await(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("timeout");
}
DConnectResponseMessage response = result.get();
assertThat(response, is(notNullValue()));
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_NAME), is(name));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_UUID), is(uuid));
}
/**
* postを呼び出し、レスポンスを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectResponseMessageが返却されること。
* ・resultに0が返却されること。
* ・productにtest-managerが返却されること。
* ・versionに1.1が返却されること。
* ・nameにmanagerが返却されること。
* ・uuidにuuidが返却されること。
* </pre>
*/
@Test
public void post() {
Context context = InstrumentationRegistry.getTargetContext();
String path = context.getFilesDir() + "/test.dat";
final byte[] fileData = "This is a test.".getBytes();
writeFile(new File(path), fileData);
final String version = "1.1";
final String product = "test-manager";
final String name = "manager";
final String uuid = "uuid";
final String key = "key";
final String value = "value";
final MultipartEntity data = new MultipartEntity();
data.add(key, new StringEntity(value));
data.add("data", new FileEntity(new File(path)));
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
File file = (File) intent.getExtras().get("data");
if (!file.isFile() || !Arrays.equals(fileData, getFile(file))) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "data is invalid.");
} else if (!method.equals(IntentDConnectMessage.ACTION_POST)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "action is invalid.");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
response.putExtra(AvailabilityProfileConstants.PARAM_NAME, name);
response.putExtra(AvailabilityProfileConstants.PARAM_UUID, uuid);
}
context.sendBroadcast(response);
}
});
DConnectSDK sdk = getSDK();
DConnectResponseMessage response = sdk.post("http://localhost:4035/gotapi/availability", data);
assertThat(response, notNullValue());
assertThat(response.getResult(), is(DConnectMessage.RESULT_OK));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_VERSION), is(version));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_PRODUCT), is(product));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_NAME), is(name));
assertThat(response.getString(AvailabilityProfileConstants.PARAM_UUID), is(uuid));
}
/**
* WebSocketを接続する。
* <pre>
* 【期待する動作】
* ・OnWebSocketListener#onOpenが呼び出されること。
* </pre>
*/
@Test
public void connectWebSocket() {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean result = new AtomicBoolean();
final String accessToken = "test-accessToken";
DConnectSDK sdk = getSDK();
sdk.setAccessToken(accessToken);
sdk.connectWebSocket(new DConnectSDK.OnWebSocketListener() {
@Override
public void onOpen() {
result.set(true);
latch.countDown();
}
@Override
public void onClose() {
}
@Override
public void onError(Exception e) {
latch.countDown();
}
});
try {
latch.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
sdk.disconnectWebSocket();
fail();
}
assertThat(result.get(), is(true));
}
/**
* OnWebSocketListenerにnullを設定してWebSocketを接続する。
* <pre>
* 【期待する動作】
* ・NullPointerExceptionが発生すること。
* </pre>
*/
@Test(expected = NullPointerException.class)
public void connectWebSocket_listener_null() {
final String accessToken = "test-accessToken";
DConnectSDK sdk = DConnectSDKFactory.create(InstrumentationRegistry.getTargetContext(), DConnectSDKFactory.Type.INTENT);
sdk.setAccessToken(accessToken);
sdk.connectWebSocket(null);
}
/**
* addEventListenerを行いイベントを受け取れることを確認する。
* <pre>
* 【期待する動作】
* ・DConnectEventMessageが受け取れること。
* </pre>
*/
@Test
public void addEventListener() {
final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final boolean[] result = new boolean[1];
final DConnectEventMessage[] event = new DConnectEventMessage[1];
final String version = "1.1";
final String product = "test-manager";
final String accessToken = "test-accessToken";
final String profile = DeviceOrientationProfileConstants.PROFILE_NAME;
final String attribute = DeviceOrientationProfileConstants.ATTRIBUTE_ON_DEVICE_ORIENTATION;
final String serviceId = "abc";
final float accelX = 1.0f;
final float accelY = 1.5f;
final float accelZ = 3.9f;
final int interval = 1001;
DConnectSDK sdk = getSDK();
sdk.setAccessToken(accessToken);
sdk.connectWebSocket(new DConnectSDK.OnWebSocketListener() {
@Override
public void onOpen() {
result[0] = true;
latch.countDown();
}
@Override
public void onClose() {
}
@Override
public void onError(Exception e) {
latch.countDown();
}
});
try {
latch.await(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
sdk.disconnectWebSocket();
fail();
}
assertThat(result[0], is(true));
mService.setServiceCallback(new TestService.ServiceCallback() {
@Override
public void onReceivedRequest(final Context context, final Intent intent) {
final ComponentName cn = (ComponentName) intent.getExtras().get(IntentDConnectMessage.EXTRA_RECEIVER);
int requestCode = intent.getIntExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, -1);
String method = intent.getAction();
Intent response = new Intent();
response.setComponent(cn);
response.setAction(IntentDConnectMessage.ACTION_RESPONSE);
response.putExtra(IntentDConnectMessage.EXTRA_REQUEST_CODE, requestCode);
if (!method.equals(IntentDConnectMessage.ACTION_PUT)) {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_ERROR);
response.putExtra(DConnectMessage.EXTRA_ERROR_CODE, 1);
response.putExtra(DConnectMessage.EXTRA_ERROR_MESSAGE, "");
} else {
response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
response.putExtra(DConnectProfileConstants.PARAM_VERSION, version);
response.putExtra(DConnectProfileConstants.PARAM_PRODUCT, product);
// 1秒後にイベントを送信
Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() {
@Override
public void run() {
Bundle orientation = new Bundle();
Bundle acceleration = new Bundle();
acceleration.putFloat(DeviceOrientationProfileConstants.PARAM_X, accelX);
acceleration.putFloat(DeviceOrientationProfileConstants.PARAM_Y, accelY);
acceleration.putFloat(DeviceOrientationProfileConstants.PARAM_Z, accelZ);
orientation.putBundle(DeviceOrientationProfileConstants.PARAM_ACCELERATION, acceleration);
orientation.putInt(DeviceOrientationProfileConstants.PARAM_INTERVAL, interval);
Intent jsonObject = new Intent();
jsonObject.setAction(IntentDConnectMessage.ACTION_EVENT);
jsonObject.setComponent(cn);
jsonObject.putExtra(DeviceOrientationProfileConstants.PARAM_ORIENTATION, orientation);
jsonObject.putExtra(DConnectMessage.EXTRA_API, "gotapi");
jsonObject.putExtra(DConnectMessage.EXTRA_PROFILE, profile);
jsonObject.putExtra(DConnectMessage.EXTRA_ATTRIBUTE, attribute);
jsonObject.putExtra(DConnectMessage.EXTRA_SERVICE_ID, serviceId);
context.sendBroadcast(jsonObject);
}
}, 1, TimeUnit.SECONDS);
}
context.sendBroadcast(response);
}
});
DConnectSDK.URIBuilder builder = sdk.createURIBuilder();
builder.setProfile(profile);
builder.setAttribute(attribute);
builder.setServiceId(serviceId);
sdk.addEventListener(builder.toASCIIString(), new DConnectSDK.OnEventListener() {
@Override
public void onMessage(final DConnectEventMessage message) {
event[0] = message;
latch2.countDown();
}
@Override
public void onResponse(final DConnectResponseMessage response) {
result[0] = true;
}
});
// イベントからのメッセージを待つ
try {
latch2.await(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("timeout");
} finally {
sdk.removeEventListener(builder.toASCIIString());
sdk.disconnectWebSocket();
}
assertThat(event[0], is(notNullValue()));
assertThat(event[0].getString(DConnectMessage.EXTRA_PROFILE), is(profile));
assertThat(event[0].getString(DConnectMessage.EXTRA_ATTRIBUTE), is(attribute));
assertThat(event[0].getString(DConnectMessage.EXTRA_SERVICE_ID), is(serviceId));
DConnectMessage orientation = event[0].getMessage(DeviceOrientationProfileConstants.PARAM_ORIENTATION);
assertThat(orientation, is(notNullValue()));
assertThat(orientation.getInt(DeviceOrientationProfileConstants.PARAM_INTERVAL), is(interval));
DConnectMessage acceleration = orientation.getMessage(DeviceOrientationProfileConstants.PARAM_ACCELERATION);
assertThat(acceleration, is(notNullValue()));
assertThat(acceleration.getFloat(DeviceOrientationProfileConstants.PARAM_X), is(accelX));
assertThat(acceleration.getFloat(DeviceOrientationProfileConstants.PARAM_Y), is(accelY));
assertThat(acceleration.getFloat(DeviceOrientationProfileConstants.PARAM_Z), is(accelZ));
}
/**
* OnEventListenerにnullを設定してaddEventListenerを行う。
* <pre>
* 【期待する動作】
* ・NullPointerExceptionが発生すること。
* </pre>
*/
@Test(expected = NullPointerException.class)
public void addEventListener_listener_null() {
DConnectSDK sdk = getSDK();
DConnectSDK.URIBuilder builder = sdk.createURIBuilder();
builder.setProfile("deviceOrientation");
builder.setAttribute("onDeviceOrientation");
builder.setServiceId("serviceId");
sdk.addEventListener(builder.toASCIIString(), null);
}
/**
* uriにnullを設定してaddEventListenerを行う。
* <pre>
* 【期待する動作】
* ・NullPointerExceptionが発生すること。
* </pre>
*/
@Test(expected = NullPointerException.class)
public void addEventListener_uri_null() {
DConnectSDK sdk = getSDK();
sdk.addEventListener((Uri) null, new DConnectSDK.OnEventListener() {
@Override
public void onMessage(final DConnectEventMessage message) {
}
@Override
public void onResponse(final DConnectResponseMessage response) {
}
});
}
/**
* uriにnullを設定してremoveEventListenerを行う。
* <pre>
* 【期待する動作】
* ・NullPointerExceptionが発生すること。
* </pre>
*/
@Test(expected = NullPointerException.class)
public void removeEventListener_uri_null() {
DConnectSDK sdk = getSDK();
sdk.removeEventListener((Uri) null);
}
}