diff --git a/.gitignore b/.gitignore
index cd8838ac6..ac1222119 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,10 @@ target
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+# Android Studio
+.gradle
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle
new file mode 100644
index 000000000..1fd0aa818
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle
@@ -0,0 +1,46 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.1'
+ defaultConfig {
+ applicationId "agent.sense.android.iot.carbon.wso2.org.wso2_senseagent"
+ minSdkVersion 19
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ def newName = output.outputFile.name
+ newName = newName.replace("app-", "androidsense")
+ newName = newName.replace("release", "")
+ //noinspection GroovyAssignabilityCheck
+ output.outputFile = new File(output.outputFile.parent, newName)
+ }
+ }
+ }
+ }
+ packagingOptions {
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/LICENSE'
+ }
+ productFlavors {
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.2.1'
+ compile 'com.android.support:design:22.2.1'
+ compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'
+ compile 'com.github.rholder:snowball-stemmer:1.3.0.581.1'
+ compile 'commons-codec:commons-codec:1.4'
+ compile 'com.netflix.feign:feign-jaxrs:8.16.0'
+ compile 'com.netflix.feign:feign-jackson:8.16.0'
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..5a799fbda
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java
new file mode 100644
index 000000000..fceeeeede
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherReceiver;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.AndroidSenseMQTTHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.event.SenseScheduleReceiver;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.ActivitySelectSensor;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.AvailableSensorsInDevice;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+import org.wso2.carbon.iot.android.sense.util.SenseClient;
+import org.wso2.carbon.iot.android.sense.util.SenseUtils;
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+
+/**
+ * A login screen that offers to register the device.
+ */
+public class RegisterActivity extends Activity {
+
+ private EditText mUsernameView;
+ private EditText mPasswordView;
+ private EditText mHostView;
+ private EditText mMqttPortView;
+ private View mProgressView;
+ private View mLoginFormView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getSharedPreferences(SupportedSensors.SELECTED_SENSORS, 0).edit().clear().apply();
+
+ if (LocalRegistry.isExist(getApplicationContext())) {
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ setContentView(R.layout.activity_register);
+ mUsernameView = (EditText) findViewById(R.id.username);
+ mPasswordView = (EditText) findViewById(R.id.password);
+ mHostView = (EditText) findViewById(R.id.hostname);
+ mMqttPortView = (EditText) findViewById(R.id.mqttPort);
+ AvailableSensorsInDevice availableSensorsInDevice = new AvailableSensorsInDevice(getApplicationContext());
+ availableSensorsInDevice.setContent();
+
+ Button deviceRegisterButton = (Button) findViewById(R.id.device_register_button);
+
+
+ deviceRegisterButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ attemptLogin();
+ }
+ });
+
+ mLoginFormView = findViewById(R.id.login_form);
+ mProgressView = findViewById(R.id.login_progress);
+ }
+
+ public void attemptLogin() {
+ showProgress(true);
+ // Reset errors.
+ mUsernameView.setError(null);
+ mPasswordView.setError(null);
+
+ // Store values at the time of the login attempt.
+ String username = mUsernameView.getText().toString();
+ String password = mPasswordView.getText().toString();
+ String hostname = mHostView.getText().toString();
+ String mqttPort = mMqttPortView.getText().toString();
+ boolean cancel = false;
+ View focusView = null;
+
+ // Check for a valid password, if the user entered one.
+ if (!TextUtils.isEmpty(password)) {
+ // mPasswordView.setError(getString(R.string.error_invalid_password));
+ focusView = mPasswordView;
+ //cancel = true;
+ }
+ // Check for a valid username .
+ if (TextUtils.isEmpty(username)) {
+ mUsernameView.setError(getString(R.string.error_field_required));
+ focusView = mUsernameView;
+ cancel = true;
+ }
+ if (TextUtils.isEmpty(username)) {
+ mHostView.setError(getString(R.string.error_field_required));
+ focusView = mHostView;
+ cancel = true;
+ }
+
+ if (cancel) {
+ focusView.requestFocus();
+ } else {
+ SenseClient client = new SenseClient(getApplicationContext());
+ LocalRegistry.addServerURL(getBaseContext(), hostname);
+ String deviceId = SenseUtils.generateDeviceId(getBaseContext(), getContentResolver());
+ boolean registerStatus = client.register(username, password, deviceId);
+ if (registerStatus) {
+ LocalRegistry.addUsername(getApplicationContext(), username);
+ LocalRegistry.addDeviceId(getApplicationContext(), deviceId);
+ LocalRegistry.addMqttPort(getApplicationContext(), Integer.parseInt(mqttPort));
+ MQTTTransportHandler mqttTransportHandler = AndroidSenseMQTTHandler.getInstance(this);
+ if (!mqttTransportHandler.isConnected()) {
+ mqttTransportHandler.connect();
+ }
+ SenseScheduleReceiver senseScheduleReceiver = new SenseScheduleReceiver();
+ senseScheduleReceiver.clearAbortBroadcast();
+ senseScheduleReceiver.onReceive(this, null);
+
+ DataPublisherReceiver dataUploaderReceiver = new DataPublisherReceiver();
+ dataUploaderReceiver.clearAbortBroadcast();
+ dataUploaderReceiver.onReceive(this, null);
+
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ showProgress(false);
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ public void showProgress(final boolean show) {
+ // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+ // for very easy animations. If available, use these APIs to fade-in
+ // the progress spinner.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+ int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
+
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ mLoginFormView.animate().setDuration(shortAnimTime).alpha(
+ show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ });
+
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mProgressView.animate().setDuration(shortAnimTime).alpha(
+ show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ });
+ } else {
+ // The ViewPropertyAnimator APIs are not available, so simply show
+ // and hide the relevant UI components.
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ }
+
+}
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java
new file mode 100644
index 000000000..70d847802
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.constants;
+
+public class SenseConstants {
+ public final static String DEVICE_TYPE = "android_sense";
+ public final static String REGISTER_CONTEXT = "/android_sense_mgt";
+ public final static String DCR_CONTEXT = "/dynamic-client-web";
+ public final static String TOKEN_ISSUER_CONTEXT = "/oauth2";
+ public final static String API_APPLICATION_REGISTRATION_CONTEXT = "/api-application-registration";
+
+ public static final int MQTT_BROKER_PORT = 1883;
+ public static final String EVENT_LISTENER_STARTED = "xxStartedxx";
+ public static final String EVENT_LISTENER_FINISHED = "xxFinishedxx";
+ public static final String EVENT_LISTENER_ONGOING = "xxOngoingxx";
+
+ public final class Request {
+ public final static String REQUEST_SUCCESSFUL = "200";
+ public final static String REQUEST_CONFLICT = "409";
+ public final static int MAX_ATTEMPTS = 2;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java
new file mode 100644
index 000000000..b09d15a88
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.data.publisher;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * This creates and AlarmManagerService that triggers the data uploader service with a 30 seconds interval.
+ */
+public class DataPublisherReceiver extends BroadcastReceiver {
+ private static int ALARM_INTERVAL = 30000;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent i = new Intent(context, DataPublisherService.class);
+ PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
+ service.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, pending);
+ }
+
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java
new file mode 100644
index 000000000..41853f8cd
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.data.publisher;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.AndroidSenseMQTTHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.TransportHandlerException;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorData;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryData;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+//import org.wso2.carbon.iot.android.sense.util.SenseClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is an android service which publishes the data to the server.
+ */
+public class DataPublisherService extends Service {
+ private static final String TAG = "Data Publisher";
+ private static String KEY_TAG = "key";
+ private static String TIME_TAG = "time";
+ private static String VALUE_TAG = "value";
+ public static Context context;
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ context = this;
+ Log.d(TAG, "service started");
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ List events = new ArrayList<>();
+ //retreive sensor data.
+ List sensorDataMap = SenseDataHolder.getSensorDataHolder();
+ for (SensorData sensorData : sensorDataMap) {
+ Event event = new Event();
+ event.setTimestamp(sensorData.getTimestamp());
+
+ switch (sensorData.getSensorType()) {
+ case Sensor.TYPE_ACCELEROMETER:
+ event.setAccelerometer(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ event.setMagnetic(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_GYROSCOPE:
+ event.setGyroscope(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_LIGHT:
+ event.setLight(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_PRESSURE:
+ event.setPressure(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_PROXIMITY:
+ event.setProximity(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_GRAVITY:
+ event.setGravity(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_ROTATION_VECTOR:
+ event.setGravity(sensorData.getSensorValues());
+ break;
+ }
+ events.add(event);
+ }
+ SenseDataHolder.resetSensorDataHolder();
+
+ //retreive batter data.
+ List batteryDataMap = SenseDataHolder.getBatteryDataHolder();
+ for (BatteryData batteryData : batteryDataMap) {
+ Event event = new Event();
+ event.setTimestamp(batteryData.getTimestamp());
+ event.setBattery(batteryData.getLevel());
+ events.add(event);
+ }
+ SenseDataHolder.resetBatteryDataHolder();
+ //retreive location data.
+ List locationDataMap = SenseDataHolder.getLocationDataHolder();
+ for (LocationData locationData : locationDataMap) {
+ Event event = new Event();
+ event.setTimestamp(locationData.getTimeStamp());
+ event.setGps(new double[]{locationData.getLatitude(), locationData.getLongitude()});
+ events.add(event);
+ }
+ SenseDataHolder.resetLocationDataHolder();
+
+ //retreive words
+ ProcessWords.cleanAndPushToWordMap();
+ List wordDatMap = SenseDataHolder.getWordDataHolder();
+ for (WordData wordData : wordDatMap) {
+ if (wordData.getOccurences() == 0) {
+ continue;
+ }
+ for (int i = 0; i < wordData.getOccurences(); i++) {
+ Event event = new Event();
+ event.setTimestamp(wordData.getTimestamp());
+ event.setWord(wordData.getWord());
+ String word = wordData.getWord();
+ String status = word;
+ if ((!word.equals(SenseConstants.EVENT_LISTENER_STARTED)) && (!word.equals(SenseConstants
+ .EVENT_LISTENER_FINISHED))) {
+ status = SenseConstants.EVENT_LISTENER_ONGOING;
+ }
+ event.setWordStatus(status);
+ events.add(event);
+ }
+ }
+ SenseDataHolder.resetWordDataHolder();
+ //publish the data
+ if (events.size() > 0) {
+ String user = LocalRegistry.getUsername(context);
+ String deviceId = LocalRegistry.getDeviceId(context);
+ JSONArray jsonArray = new JSONArray();
+ for (Event event : events) {
+ event.setOwner(user);
+ event.setDeviceId(deviceId);
+ jsonArray.put(event.getEvent());
+ }
+ MQTTTransportHandler mqttTransportHandler = AndroidSenseMQTTHandler.getInstance(context);
+ if (!mqttTransportHandler.isConnected()) {
+ mqttTransportHandler.connect();
+ }
+ mqttTransportHandler.publishDeviceData(user, deviceId, jsonArray.toString());
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "Json Data Parsing Exception", e);
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "Data Publish Failed", e);
+ }
+ }
+ };
+ Thread dataUploaderThread = new Thread(runnable);
+ dataUploaderThread.start();
+ return Service.START_NOT_STICKY;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java
new file mode 100644
index 000000000..e7ceea063
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java
@@ -0,0 +1,219 @@
+package org.wso2.carbon.iot.android.sense.data.publisher;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class Event {
+
+ private String owner;
+ private String deviceId;
+ private String type;
+ private float battery;
+ private double gps[]; //lat,long
+ private float accelerometer[]; //x,y,z
+ private float magnetic[]; //x,y,z
+ private float gyroscope[]; //x,y,z
+ private float light;
+ private float pressure;
+ private float proximity;
+ private float gravity[];
+ private float rotation[];
+ private String wordSessionId;
+ private String word;
+ private String wordStatus;
+ private long timestamp;
+
+ private float getBattery() {
+ return battery;
+ }
+
+ public void setBattery(float battery) {
+ this.type = "battery";
+ this.battery = battery;
+ }
+
+ private double[] getGps() {
+ return gps != null ? gps : new double[]{0, 0};
+ }
+
+ public void setGps(double[] gps) {
+ this.type = "gps";
+ this.gps = gps;
+ }
+
+ private float[] getAccelerometer() {
+ return accelerometer != null ? accelerometer : new float[]{0, 0, 0};
+ }
+
+ public void setAccelerometer(float[] accelerometer) {
+ this.type = "accelerometer";
+ this.accelerometer = accelerometer;
+ }
+
+ private float[] getMagnetic() {
+ return magnetic != null ? magnetic : new float[]{0, 0, 0};
+ }
+
+ public void setMagnetic(float[] magnetic) {
+ this.type = "magnetic";
+ this.magnetic = magnetic;
+ }
+
+ private float[] getGyroscope() {
+ return gyroscope != null ? gyroscope : new float[]{0, 0, 0};
+ }
+
+ public void setGyroscope(float[] gyroscope) {
+ this.type = "gyroscope";
+ this.gyroscope = gyroscope;
+ }
+
+ public float getLight() {
+ return light;
+ }
+
+ public void setLight(float light) {
+ this.type = "light";
+ this.light = light;
+ }
+
+ public float getPressure() {
+ return pressure;
+ }
+
+ public void setPressure(float pressure) {
+ this.type = "pressure";
+ this.pressure = pressure;
+ }
+
+ public float getProximity() {
+ return proximity;
+ }
+
+ public void setProximity(float proximity) {
+ this.type = "proximity";
+ this.proximity = proximity;
+ }
+
+ private float[] getGravity() {
+ return gravity != null ? gravity : new float[]{0, 0, 0};
+ }
+
+ public void setGravity(float gravity[]) {
+ this.type = "gravity";
+ this.gravity = gravity;
+ }
+
+ private float[] getRotation() {
+ return rotation != null ? rotation : new float[]{0, 0, 0};
+ }
+
+ public void setRotation(float rotation[]) {
+ this.type = "rotation";
+ this.rotation = rotation;
+ }
+
+ private String getWordSessionId() {
+ return wordSessionId != null ? wordSessionId : "";
+ }
+
+ public void setWordSessionId(String wordSessionId) {
+ this.wordSessionId = wordSessionId;
+ }
+
+ private String getWord() {
+ return word != null ? word : "";
+ }
+
+ public void setWord(String word) {
+ this.type = "word";
+ this.word = word;
+ }
+
+ private long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ private String getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ private String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public String getWordStatus() {
+ return wordStatus != null ? wordStatus : "";
+ }
+
+ public void setWordStatus(String wordStatus) {
+ this.wordStatus = wordStatus;
+ }
+
+ public JSONObject getEvent() throws JSONException {
+ JSONObject jsonEvent = new JSONObject();
+ JSONObject jsonMetaData = new JSONObject();
+ jsonMetaData.put("owner", getOwner());
+ jsonMetaData.put("deviceId", getDeviceId());
+ jsonMetaData.put("type", type);
+ jsonMetaData.put("timestamp", getTimestamp());
+ jsonEvent.put("metaData", jsonMetaData);
+
+ JSONObject jsonPayloadData = new JSONObject();
+ jsonPayloadData.put("battery", getBattery());
+ //gps
+ double gpsEvents[] = getGps();
+ jsonPayloadData.put("gps_lat", gpsEvents[0]);
+ jsonPayloadData.put("gps_long", gpsEvents[1]);
+ //acceleromter
+ float events[] = getAccelerometer();
+ jsonPayloadData.put("accelerometer_x", events[0]);
+ jsonPayloadData.put("accelerometer_y", events[1]);
+ jsonPayloadData.put("accelerometer_z", events[2]);
+ //magnetic
+ events = getMagnetic();
+ jsonPayloadData.put("magnetic_x", events[0]);
+ jsonPayloadData.put("magnetic_y", events[1]);
+ jsonPayloadData.put("magnetic_z", events[2]);
+ //gyroscope
+ events = getGyroscope();
+ jsonPayloadData.put("gyroscope_x", events[0]);
+ jsonPayloadData.put("gyroscope_y", events[1]);
+ jsonPayloadData.put("gyroscope_z", events[2]);
+
+ jsonPayloadData.put("light", getLight());
+ jsonPayloadData.put("pressure", getPressure());
+ jsonPayloadData.put("proximity", getProximity());
+ //gravity
+ events = getGravity();
+ jsonPayloadData.put("gravity_x", events[0]);
+ jsonPayloadData.put("gravity_y", events[1]);
+ jsonPayloadData.put("gravity_z", events[2]);
+ //rotation
+ events = getRotation();
+ jsonPayloadData.put("rotation_x", events[0]);
+ jsonPayloadData.put("rotation_y", events[1]);
+ jsonPayloadData.put("rotation_z", events[2]);
+ //word
+ jsonPayloadData.put("word", getWord());
+ jsonPayloadData.put("word_sessionId", getWordSessionId());
+ jsonPayloadData.put("word_status", getWordStatus());
+
+ jsonEvent.put("payloadData", jsonPayloadData);
+
+ return jsonEvent;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java
new file mode 100644
index 000000000..5ae9b3739
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.iot.android.sense.data.publisher.mqtt;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.TransportHandlerException;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+/**
+ * This is an example for the use of the MQTT capabilities provided by the IoT-Server. This example depicts the use
+ * of MQTT Transport for the Android Sense device-type. This class extends the abstract class
+ * "MQTTTransportHandler". "MQTTTransportHandler" consists of the MQTT client specific functionality and implements
+ * the "TransportHandler" interface. The actual functionality related to the "TransportHandler" interface is
+ * implemented here, in this concrete class. Whilst the abstract class "MQTTTransportHandler" is intended to provide
+ * the common MQTT functionality, this class (which is its extension) provides the implementation specific to the
+ * MQTT communication of the Device-Type (Android Sense) in concern.
+ *
+ * Hence, the methods of this class are implementation of the "TransportHandler" interface which handles the device
+ * specific logic to connect-to, publish-to, process-incoming-messages-from and disconnect-from the MQTT broker
+ * listed in the configurations.
+ */
+public class AndroidSenseMQTTHandler extends MQTTTransportHandler {
+ private static final String TAG = "AndroidSenseMQTTHandler";
+ private static volatile AndroidSenseMQTTHandler mInstance;
+
+
+ /**
+ * return a sigleton Instance
+ * @param context is the android context object.
+ * @return AndroidSenseMQTTHandler.
+ */
+ public static AndroidSenseMQTTHandler getInstance(Context context) {
+ if (mInstance == null) {
+ Class clazz = AndroidSenseMQTTHandler.class;
+ synchronized (clazz) {
+ if (mInstance == null) {
+ mInstance = new AndroidSenseMQTTHandler(context);
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ /**
+ * Default constructor for the AndroidSenseMQTTHandler.
+ */
+ private AndroidSenseMQTTHandler(Context context) {
+ super(context);
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to connect to the MQTT broker and subscribe to a topic.
+ * This method is called to initiate a MQTT communication.
+ */
+ @Override
+ public void connect() {
+ Runnable connector = new Runnable() {
+ public void run() {
+ while (!isConnected()) {
+ try {
+ connectToQueue();
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ try {
+ Thread.sleep(timeoutInterval);
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, "MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
+ }
+ }
+
+ try {
+ subscribeToQueue();
+ } catch (TransportHandlerException e) {
+ Log.w(TAG, "Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ }
+ }
+ }
+ };
+
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to process incoming messages. This is the specific
+ * method signature of the overloaded "processIncomingMessage" method that gets called from the messageArrived()
+ * callback of the "MQTTTransportHandler".
+ */
+ @Override
+ public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) {
+ if (messageParams.length != 0) {
+ // owner and the deviceId are extracted from the MQTT topic to which the message was received.
+ // = [ServerName/Owner/DeviceType/DeviceId/#]
+ String topic = messageParams[0];
+ String[] topicParams = topic.split("/");
+ String owner = topicParams[1];
+ String deviceId = topicParams[3];
+
+ Log.d(TAG, "Received MQTT message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]");
+
+ String msg;
+ msg = mqttMessage.toString();
+ Log.d(TAG, "MQTT: Received Message [" + msg + "] topic: [" + topic + "]");
+ if (topic.contains("threshold")) {
+ try {
+ ProcessWords.setThreshold(Integer.parseInt(msg));
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Invalid threshold value " + msg);
+ }
+ } else if (topic.contains("words")) {
+ String words[] = msg.split(" ");
+ ProcessWords.addWords(Arrays.asList(words));
+ } else if (topic.contains("remove")) {
+ String words[] = msg.split(" ");
+ for (String word: words) {
+ ProcessWords.removeWord(word);
+ }
+ }
+ } else {
+ String errorMsg =
+ "MQTT message [" + mqttMessage.toString() + "] was received without the topic information.";
+ Log.w(TAG, errorMsg);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to publish data to the device. This method calls the
+ * {@link #publishToQueue(String, MqttMessage)} method of the "MQTTTransportHandler" class.
+ */
+ @Override
+ public void publishDeviceData(String... publishData) throws TransportHandlerException {
+ if (publishData.length != 3) {
+ String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
+ "Need to be [owner, deviceId, content]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg);
+ }
+
+ String deviceOwner = publishData[0];
+ String deviceId = publishData[1];
+ String resource = publishData[2];
+
+ MqttMessage pushMessage = new MqttMessage();
+ String publishTopic = "wso2/" + SenseConstants.DEVICE_TYPE + "/" + deviceId + "/data";
+ String actualMessage = resource;
+ pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8));
+ pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
+ pushMessage.setRetained(false);
+ publishToQueue(publishTopic, pushMessage);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * Android Sense device-type specific implementation to disconnect from the MQTT broker.
+ */
+ @Override
+ public void disconnect() {
+ Runnable stopConnection = new Runnable() {
+ public void run() {
+ while (isConnected()) {
+ try {
+ closeConnection();
+ } catch (MqttException e) {
+ Log.w(TAG, "Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint
+ + " for device-type - " + SenseConstants.DEVICE_TYPE, e);
+
+ try {
+ Thread.sleep(timeoutInterval);
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, "MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " +
+ SenseConstants.DEVICE_TYPE, e1);
+ }
+ }
+ }
+ }
+ };
+
+ Thread terminatorThread = new Thread(stopConnection);
+ terminatorThread.setDaemon(true);
+ terminatorThread.start();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void publishDeviceData() {
+ // nothing to do
+ }
+
+ @Override
+ public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void processIncomingMessage() {
+ // nothing to do
+ }
+
+ @Override
+ public void processIncomingMessage(MqttMessage message) throws TransportHandlerException {
+
+ }
+
+}
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java
new file mode 100644
index 000000000..689138d72
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+import android.content.Context;
+import android.util.Log;
+import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
+ * the core functionality with regards to device-server communication regardless of the Transport protocol. This
+ * specific class contains the MQTT-Transport specific implementations. The class implements utility methods for the
+ * case of a MQTT communication. However, this "abstract class", even-though it implements the "TransportHandler"
+ * interface, does not contain the logic relevant to the interface methods. The specific functionality of the
+ * interface methods are intended to be implemented by the concrete class that extends this abstract class and
+ * utilizes the MQTT specific functionality (ideally a device API writer who would like to communicate to the device
+ * via MQTT Protocol).
+ *
+ * This class contains the Device-Management specific implementation for all the MQTT functionality. This includes
+ * connecting to a MQTT Broker & subscribing to the appropriate MQTT-topic, action plan upon losing connection or
+ * successfully delivering a message to the broker and upon receiving a MQTT message. Makes use of the 'Paho-MQTT'
+ * library provided by Eclipse Org.
+ */
+public abstract class MQTTTransportHandler implements MqttCallback, TransportHandler {
+ private static final String TAG = "MQTTTransportHandler";
+
+ private MqttClient client;
+ private String clientId;
+ private MqttConnectOptions options; // options to be set to the client-connection.
+ // topic to which a will-message is automatically published by the broker upon the device losing its connection.
+ private String clientWillTopic;
+
+ protected String mqttBrokerEndPoint;
+ protected int timeoutInterval; // interval to use for reconnection attempts etc.
+ protected String subscribeTopic;
+
+ // Quality of Service Levels for MQTT Subscription and Publishing.
+ public static final int QoS_0 = 0; // At-Most Once
+ @SuppressWarnings("unused")
+ public static final int QoS_1 = 1; // At-Least Once
+ public static final int QoS_2 = 2; // Exactly Once
+
+ public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = QoS_0;
+ // Prefix to the Will-Topic to which a message is published if client loses its connection.
+ private static final String DISCONNECTION_WILL_TOPIC_PREFIX = "Disconnection/";
+ // Will-Message of the client to be published if connection is lost.
+ private static final String DISCONNECTION_WILL_MSG = "Lost-Connection";
+ /**
+ * Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
+ * and the topic to subscribe.
+ * @param context activity context.
+ */
+ protected MQTTTransportHandler(Context context) {
+ String username = LocalRegistry.getUsername(context);
+ String deviceId = LocalRegistry.getDeviceId(context);
+ this.clientId = deviceId + ":" + SenseConstants.DEVICE_TYPE;
+ this.subscribeTopic = "wso2/" + SenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/#";
+ this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + SenseConstants.DEVICE_TYPE;
+ this.mqttBrokerEndPoint = "tcp://" + LocalRegistry.getServerHost(context) + ":" + LocalRegistry.getMqttPort(context);
+ this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
+ setUsernameAndPassword(LocalRegistry.getAccessToken(context), "");
+ this.initMQTTClient();
+ }
+
+ /**
+ * Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
+ * and the topic to subscribe. Additionally this constructor takes in the reconnection-time interval between
+ * successive attempts to connect to the broker.
+ *
+ * @param deviceOwner the owner of the device.
+ * @param deviceType the CDMF Device-Type of the device.
+ * @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
+ * @param subscribeTopic the MQTT topic to which the client is to be subscribed
+ * @param intervalInMillis the time interval in MILLI-SECONDS between attempts to connect to the broker.
+ */
+ protected MQTTTransportHandler(String deviceOwner, String deviceType,
+ String mqttBrokerEndPoint, String subscribeTopic, int intervalInMillis) {
+ this.clientId = deviceOwner + ":" + deviceType;
+ this.subscribeTopic = subscribeTopic;
+ this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType;
+ this.mqttBrokerEndPoint = mqttBrokerEndPoint;
+ this.timeoutInterval = intervalInMillis;
+ this.initMQTTClient();
+ }
+
+
+ /**
+ * Initializes the MQTT-Client. Creates a client using the given MQTT-broker endpoint and the clientId (which is
+ * constructed by a concatenation of [deviceOwner]:[deviceType]). Also sets the client's options parameter with
+ * the clientWillTopic (in-case of connection failure) and other info. Also sets the callback to this current class.
+ */
+ private void initMQTTClient() {
+ try {
+ client = new MqttClient(this.mqttBrokerEndPoint, clientId, null);
+ Log.i(TAG, "MQTT client was created with ClientID : " + clientId);
+ } catch (MqttException ex) {
+ String errorMsg = "Initializing the MQTT Client failed.";
+ Log.e(TAG, errorMsg, ex);
+ }
+
+ options = new MqttConnectOptions();
+ options.setKeepAliveInterval(120); // set the keep alive interval to 120 seconds by default.
+ options.setCleanSession(true); // sets clean session to true by default.
+ setDisconnectionWillForClient(QoS_2, true); // sets default will-topic & msg with QoS 2 and retained true.
+ client.setCallback(this); // callback for MQTT events are set to `this` object.
+ }
+
+ /**
+ * @param qos the Quality of Service at which the last-will-message is to be published.
+ * @param isRetained indicate whether to retain the last-will-message.
+ * @see MQTTTransportHandler#setDisconnectionWillForClient(String, String, int, boolean). Uses the default values
+ * for Will-Topic and Will-Message.
+ */
+ protected void setDisconnectionWillForClient(int qos, boolean isRetained) {
+ this.setDisconnectionWillForClient(clientWillTopic, DISCONNECTION_WILL_MSG, qos, isRetained);
+ }
+
+ /**
+ * Sets the [Will] option in the default options-set of the MQTT Client. A will-topic, will-message is parsed
+ * along with the QoS and the retained flag. When the client loses its connection to the broker, the broker
+ * publishes the will-message to the will-topic, to itself.
+ *
+ * @param willTopic the topic to which the last will message is to be published when client exists ungracefully.
+ * @param willMsg the message to be published upon client's ungraceful exit from the broker.
+ * @param qos the Quality of Service at which the last-will-message is to be published.
+ * @param isRetained indicate whether to retain the last-will-message.
+ */
+ protected void setDisconnectionWillForClient(String willTopic, String willMsg, int qos, boolean isRetained) {
+ this.options.setWill(willTopic, willMsg.getBytes(StandardCharsets.UTF_8), qos, isRetained);
+ }
+
+ /**
+ * Sets the [Clean-Session] option in the default options-set of the MQTT Client. It is set to `true` by default.
+ *
+ * @param setCleanSession `true` indicates that the session details can be cleared/cleaned upon disconnection,
+ * `false` indicates that the session details are to be persisted if the client disconnects.
+ */
+ @SuppressWarnings("unused")
+ protected void setClientCleanSession(boolean setCleanSession) {
+ this.options.setCleanSession(setCleanSession);
+ }
+
+ /**
+ * Sets the [Username] & [Password] options in the default options-set of the MQTT Client. By default these
+ * values are not set.
+ *
+ * @param username the username to be used by the client to connect to the broker.
+ * @param password the password to be used by the client to connect to the broker.
+ */
+ @SuppressWarnings("unused")
+ protected void setUsernameAndPassword(String username, String password) {
+ this.options.setUserName(username);
+ this.options.setPassword(password.toCharArray());
+ }
+
+ /**
+ * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using default the
+ * MQTT-options.
+ *
+ * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
+ */
+ protected void connectToQueue() throws TransportHandlerException {
+ this.connectToQueue(options);
+ }
+
+ /**
+ * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using the MQTT-Options
+ * passed.
+ *
+ * @param options options to be used by the client for this connection. (username, password, clean-session, etc)
+ * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
+ */
+ protected void connectToQueue(MqttConnectOptions options) throws TransportHandlerException {
+ try {
+ client.connect(options);
+ Log.d(TAG, "MQTT Client connected to queue at: " + this.mqttBrokerEndPoint);
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Exception occured whilst connecting to queue at [" + this.mqttBrokerEndPoint + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
+ * @see MQTTTransportHandler#subscribeToQueue(int). Uses default QoS of 1.
+ */
+ protected void subscribeToQueue() throws TransportHandlerException {
+ this.subscribeToQueue(QoS_0);
+ }
+
+ /**
+ * Subscribes to the MQTT-Topic specified in the constructor to this class.
+ *
+ * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
+ */
+ protected void subscribeToQueue(int qos) throws TransportHandlerException {
+ try {
+ client.subscribe(subscribeTopic, qos);
+ Log.d(TAG, "Client [" + clientId + "] subscribed to topic: " + subscribeTopic);
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Exception occurred whilst client [" + clientId + "] tried to subscribe to " +
+ "topic: [" + subscribeTopic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * @param topic the topic to which the message is to be published.
+ * @param payLoad the message (payload) of the MQTT publish action.
+ * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
+ */
+ @SuppressWarnings("unused")
+ protected void publishToQueue(String topic, String payLoad) throws TransportHandlerException {
+ publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false);
+ }
+
+ /**
+ * @param topic the topic to which the message is to be published.
+ * @param message the message (payload) of the MQTT publish action as a `MQTTMessage`.
+ * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
+ * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
+ */
+ protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException {
+ try {
+ client.publish(topic, message);
+ Log.d(TAG, "Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via
+ * publishing to this broker that the messages are communicated to the device. This is an overloaded method with
+ * different parameter combinations. This method invokes the publish method provided by the MQTT-Client library.
+ *
+ * @param topic the topic to which the message is to be published.
+ * @param payLoad the message (payload) of the MQTT publish action.
+ * @param qos the Quality-of-Service of the current publish action.
+ * Could be 0(At-most once), 1(At-least once) or 2(Exactly once)
+ * @param retained indicate whether to retain the publish-message in the event of no subscribers.
+ * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
+ */
+ protected void publishToQueue(String topic, String payLoad, int qos, boolean retained)
+ throws TransportHandlerException {
+ try {
+ client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
+ Log.d(TAG, "Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully");
+
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * Checks whether the connection to the MQTT-Broker exists.
+ *
+ * @return `true` if the client is connected to the MQTT-Broker, else `false`.
+ */
+ @Override
+ public boolean isConnected() {
+ return client.isConnected();
+ }
+
+ /**
+ * Callback method which is triggered once the MQTT client losers its connection to the broker. Spawns a new
+ * thread that executes necessary actions to try and reconnect to the endpoint.
+ *
+ * @param throwable a Throwable Object containing the details as to why the failure occurred.
+ */
+ @Override
+ public void connectionLost(Throwable throwable) {
+ Log.w(TAG, "Connection for client: " + this.clientId + " to " + this.mqttBrokerEndPoint + " was lost." +
+ "\nThis was due to - " + throwable.getMessage());
+ Thread reconnectThread = new Thread() {
+ public void run() {
+ connect();
+ }
+ };
+ reconnectThread.setDaemon(true);
+ reconnectThread.start();
+ }
+
+ /**
+ * Callback method which is triggered upon receiving a MQTT Message from the broker. Spawns a new thread that
+ * executes any actions to be taken with the received message.
+ *
+ * @param topic the MQTT-Topic to which the received message was published to and the client subscribed to.
+ * @param mqttMessage the actual MQTT-Message that was received from the broker.
+ */
+ @Override
+ public void messageArrived(final String topic, final MqttMessage mqttMessage) {
+ Log.d(TAG, "Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic + "'.");
+
+ Thread messageProcessorThread = new Thread() {
+ public void run() {
+ try {
+ processIncomingMessage(mqttMessage, topic);
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "An error occurred when trying to process received MQTT message [" + mqttMessage + "] " +
+ "for topic [" + topic + "].", e);
+ }
+ }
+ };
+ messageProcessorThread.setDaemon(true);
+ messageProcessorThread.start();
+ }
+
+ /**
+ * Callback method which gets triggered upon successful completion of a message delivery to the broker.
+ *
+ * @param iMqttDeliveryToken the MQTT-DeliveryToken which includes the details about the specific message delivery.
+ */
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
+ String topic = iMqttDeliveryToken.getTopics()[0];
+ String client = iMqttDeliveryToken.getClient().getClientId();
+
+ try {
+ if (iMqttDeliveryToken.isComplete()) {
+ if (iMqttDeliveryToken.getMessage() != null) {
+ String message = iMqttDeliveryToken.getMessage().toString();
+ Log.d(TAG, "Message to client [" + client + "] under topic (" + topic +
+ ") was delivered successfully with the delivery message: '" + message + "'");
+ } else {
+ Log.d(TAG, "Message to client [" + client + "] under topic (" + topic +
+ ") was delivered successfully.");
+ }
+ } else {
+ Log.w(TAG, "FAILED: Delivery of MQTT message to [" + client + "] under topic [" + topic + "] failed.");
+ }
+ } catch (MqttException e) {
+ Log.w(TAG, "Error occurred whilst trying to read the message from the MQTT delivery token.");
+ }
+ }
+
+ /**
+ * Closes the connection to the MQTT Broker.
+ */
+ public void closeConnection() throws MqttException {
+ if (client != null && isConnected()) {
+ client.disconnect();
+ }
+ }
+
+ /**
+ * Fetches the default options set for the MQTT Client
+ *
+ * @return the options that are currently set for the client.
+ */
+ public MqttConnectOptions getOptions() {
+ return options;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java
new file mode 100644
index 000000000..88efba9a4
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+
+/**
+ * This interface consists of the core functionality related to the transport between any device and the server. The
+ * interface is an abstraction, regardless of the underlying protocol used for the transport. Implementation of this
+ * interface by any class that caters a specific protocol (ex: HTTP, XMPP, MQTT, CoAP) would ideally have methods
+ * specific to the protocol used for communication and other methods that implement the logic related to the devices
+ * using the protocol. The methods of the interface are identified as generic ones for implementing transport
+ * protocols for device communication. The implementation can utilize the appropriate method signatures applicable for
+ * intended protocol.
+ *
+ * @param an object of the message type specific to the protocol implemented. To be set to 'String' if there
+ * isn't anything specific.
+ */
+public interface TransportHandler {
+ // a default timeout interval to be used for the protocol specific connections
+ int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 5 sec
+
+ /**
+ * Implements the underlying connect mechanism specific to the protocol enabled by the interface. An object of a
+ * class that implements this interface would call this method before any communication is started via the
+ * intended protocol.
+ */
+ void connect();
+
+ /**
+ * Used to check whether a connection (via the implemented protocol) to the external-endpoint exists. Ideally
+ * used to verify that the connection persists and to spawn a reconnection attempt if not.
+ *
+ * @return 'true' if connection is already made & exists, else 'false'.
+ */
+ boolean isConnected();
+
+ /**
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
+ * @see TransportHandler#processIncomingMessage(Object, String...)
+ */
+ void processIncomingMessage() throws TransportHandlerException;
+
+ /**
+ * @param message the message (of the type specific to the protocol) received from the device.
+ * @throws TransportHandlerException
+ * @see TransportHandler#processIncomingMessage(Object, String...)
+ */
+ void processIncomingMessage(T message) throws TransportHandlerException;
+
+ /**
+ * This is an overloaded method with three different method-signatures. This method is used to process any
+ * incoming messages via the implemented protocol. It would ideally be invoked at a point where a message
+ * received event is activated (Ex: `MessageArrived` callback in Eclipse-Paho-MQTT Client & `PacketListener`(s)
+ * in XMPP).
+ *
+ *
+ * @param message the message (of the type specific to the protocol) received from the device.
+ * @param messageParams one or more other parameters received as part-of & relevant-to the message (Ex: MQTT Topic).
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
+ */
+ void processIncomingMessage(T message, String... messageParams) throws TransportHandlerException;
+
+ /**
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ * @see TransportHandler#publishDeviceData(String...)
+ */
+ void publishDeviceData() throws TransportHandlerException;
+
+ /**
+ * @param publishData the message (of the type specific to the protocol) to be sent to the device.
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ * @see TransportHandler#publishDeviceData(String...)
+ */
+ void publishDeviceData(T publishData) throws TransportHandlerException;
+
+ /**
+ * This is an overloaded method with three different method-signatures. This method is used to publish messages
+ * to an external-endpoint/device via the implemented protocol. It could in itself call the (communicating)
+ * external-endpoint or invoke any method provided by the protocol specific library.
+ *
+ *
+ * @param publishData one or more parameters specific to the message and the data to be sent.
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ */
+ void publishDeviceData(String... publishData) throws TransportHandlerException;
+
+ /**
+ * Implements the underlying disconnect mechanism specific to the protocol enabled by the interface. An object of a
+ * class that implements this interface would call this method upon completion of all communication. In the case of
+ * the IoT-Server invoking this would only be required if the server shuts-down.
+ */
+ void disconnect();
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java
new file mode 100644
index 000000000..c52ca2ed0
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+
+public class TransportHandlerException extends Exception {
+ private static final long serialVersionUID = 2736466230451105440L;
+
+ private String errorMessage;
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public TransportHandlerException(String msg, Exception nestedEx) {
+ super(msg, nestedEx);
+ setErrorMessage(msg);
+ }
+
+ public TransportHandlerException(String message, Throwable cause) {
+ super(message, cause);
+ setErrorMessage(message);
+ }
+
+ public TransportHandlerException(String msg) {
+ super(msg);
+ setErrorMessage(msg);
+ }
+
+ public TransportHandlerException() {
+ super();
+ }
+
+ public TransportHandlerException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java
new file mode 100644
index 000000000..41ff9feff
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+
+/**
+ * This is a service which triggers to collect
+ */
+public class SenseScheduleReceiver extends BroadcastReceiver {
+ private static final int ALARM_INTERVAL = 5000;
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent i = new Intent(context, SenseService.class);
+ PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
+
+ Calendar cal = Calendar.getInstance();
+
+ cal.add(Calendar.SECOND, 30);
+ service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), ALARM_INTERVAL, pending);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java
new file mode 100644
index 000000000..69285234f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import org.wso2.carbon.iot.android.sense.event.streams.SenseDataCollector;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryDataReceiver;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+import org.wso2.carbon.iot.android.sense.util.SenseWakeLock;
+
+/**
+ * This service caters to initiate the data collection.
+ */
+public class SenseService extends Service {
+
+ public static Context context;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ SenseWakeLock.acquireWakeLock(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ context = this;
+ if (!LocalRegistry.isExist(context)) return Service.START_NOT_STICKY;
+ //Below triggers the data collection for sensors,location and battery.
+ SenseDataCollector Sensor = new SenseDataCollector(this, SenseDataCollector.DataType.SENSOR);
+ SenseDataCollector Location = new SenseDataCollector(this, SenseDataCollector.DataType.LOCATION);
+ registerReceiver(new BatteryDataReceiver(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+ //service will not be stopped until we manually stop the service
+ return Service.START_NOT_STICKY;
+
+ }
+
+ @Override
+ public void onDestroy() {
+ SenseWakeLock.releaseCPUWakeLock();
+ super.onDestroy();
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java
new file mode 100644
index 000000000..1d8e42204
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams;
+
+/**
+ * this class extended by each data reader implementation, where the data store logic is implemented in thread.
+ */
+public abstract class DataReader implements Runnable {
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java
new file mode 100644
index 000000000..3f5de2888
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.Location;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the location data that is been collected.
+ */
+public class LocationData {
+ private double latitude; // latitude
+ private double longitude; // longitude
+ private long timestamp;
+
+ LocationData(double latitude, double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ timestamp = new Date().getTime();
+
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ public long getTimeStamp() {
+ return timestamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ timestamp = timeStamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java
new file mode 100644
index 000000000..b8d3a4e58
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.Location;
+
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.util.Log;
+import org.wso2.carbon.iot.android.sense.event.streams.DataReader;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This is used to retrieve the location data using GPS and used Network connection to increase the accuracy.
+ */
+public class LocationDataReader extends DataReader implements LocationListener {
+ protected LocationManager locationManager;
+ private Context mContext;
+ private boolean canGetLocation = false;
+ private static final String TAG = "Location Data";
+
+ Location location; // location
+ double latitude; // latitude
+ double longitude; // longitude
+
+ public LocationDataReader(Context context) {
+ mContext = context;
+ getLocation();
+ }
+
+ public Location getLocation() {
+ locationManager = (LocationManager) mContext.getSystemService(mContext.LOCATION_SERVICE);
+
+ // getting GPS status
+ boolean isGPSEnabled = locationManager
+ .isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ // getting network status
+ boolean isNetworkEnabled = locationManager
+ .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+
+ if (!isGPSEnabled && !isNetworkEnabled) {
+ // no network provider is enabled
+ } else {
+ this.canGetLocation = true;
+ // First get location from Network Provider
+ if (isNetworkEnabled) {
+ locationManager.requestLocationUpdates(
+ LocationManager.NETWORK_PROVIDER, 0, 0, this);
+ // MIN_TIME_BW_UPDATES,
+ // MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ if (locationManager != null) {
+ location = locationManager
+ .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ if (location != null) {
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ }
+ }
+ }
+ // if GPS Enabled get lat/long using GPS Services
+ if (isGPSEnabled) {
+ if (location == null) {
+ locationManager.requestLocationUpdates(
+ LocationManager.GPS_PROVIDER, 0, 0, this);
+ //MIN_TIME_BW_UPDATES,
+ //MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ Log.d(TAG, "GPS Enabled");
+ if (locationManager != null) {
+ location = locationManager
+ .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (location != null) {
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ }
+ }
+ }
+ }
+ }
+ return location;
+ }
+
+ public boolean canGetLocation() {
+ return this.canGetLocation;
+ }
+
+ public void stopUsingGPS() {
+ if (locationManager != null) {
+ locationManager.removeUpdates(LocationDataReader.this);
+ }
+ }
+
+ public double getLatitude() {
+ if (location != null) {
+ latitude = location.getLatitude();
+ }
+ // return latitude
+ return latitude;
+ }
+
+ /**
+ * Function to get longitude
+ */
+ public double getLongitude() {
+ if (location != null) {
+ longitude = location.getLongitude();
+ }
+ // return longitude
+ return longitude;
+ }
+
+ @Override
+ public void onLocationChanged(Location arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderDisabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderEnabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void run() {
+ Log.d(TAG, "running -Location");
+ try {
+ TimeUnit.MILLISECONDS.sleep(10000);
+ double lat = getLatitude();
+ double longit = getLongitude();
+ if (lat != 0 && longit != 0) {
+ SenseDataHolder.getLocationDataHolder().add(new LocationData(getLatitude(), getLongitude()));
+ }
+ } catch (InterruptedException e) {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ Log.e(TAG, " Location Data Retrieval Failed");
+ }
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java
new file mode 100644
index 000000000..2febb8ba2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams;
+
+import android.content.Context;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationDataReader;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorDataReader;
+
+/**
+ * This class triggered by service to collect the sensor data.
+ */
+public class SenseDataCollector {
+ public enum DataType {
+ SENSOR, LOCATION
+ }
+
+ public SenseDataCollector(Context ctx, DataType dt) {
+ DataReader dr = null;
+ switch (dt) {
+ case SENSOR:
+ dr = new SensorDataReader(ctx);
+ break;
+ case LOCATION:
+ dr = new LocationDataReader(ctx);
+ break;
+ }
+ if (dr != null) {
+ Thread DataCollector = new Thread(dr);
+ DataCollector.start();
+ }
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java
new file mode 100644
index 000000000..abdfeb155
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.Sensor;
+
+import android.hardware.SensorEvent;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the sensor data that is been collected.
+ * look at http://developer.android.com/guide/topics/sensors/sensors_overview.html for field description.
+ */
+public class SensorData {
+ private int sensorType;
+ private String sensorName;
+ private String sensorVendor;
+ private float sensorValues[];
+ private int accuracyStatus;
+ private long timestamp;
+ private String collectTimestamp;
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ SensorData(SensorEvent event) {
+ sensorValues = event.values;
+ accuracyStatus = event.accuracy;
+ collectTimestamp = String.valueOf(event.timestamp);
+ timestamp = new Date().getTime();
+ sensorName = supportedSensors.getType(event.sensor.getType()).toUpperCase();
+ sensorVendor = event.sensor.getVendor();
+ sensorType = event.sensor.getType();
+ }
+
+ public int getSensorType() {
+ return sensorType;
+ }
+
+ public void setSensorType(int sensorType) {
+ this.sensorType = sensorType;
+ }
+
+ public String getSensorName() {
+ return sensorName;
+ }
+
+ public void setSensorName(String sensorName) {
+ this.sensorName = sensorName;
+ }
+
+ public String getSensorVendor() {
+ return sensorVendor;
+ }
+
+ public void setSensorVendor(String sensorVendor) {
+ this.sensorVendor = sensorVendor;
+ }
+
+ public float[] getSensorValues() {
+ return sensorValues;
+ }
+
+ public void setSensorValues(float sensorValues[]) {
+ this.sensorValues = sensorValues;
+ }
+
+ public int getAccuracyStatus() {
+ return accuracyStatus;
+ }
+
+ public void setAccuracyStatus(int accuracyStatus) {
+ this.accuracyStatus = accuracyStatus;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getCollectTimestamp() {
+ return collectTimestamp;
+ }
+
+ public void setCollectTimestamp(String collectTimestamp) {
+ this.collectTimestamp = collectTimestamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java
new file mode 100644
index 000000000..4f4697e50
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.Sensor;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.event.streams.DataReader;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This is used to retrieve the sensor data.
+ */
+public class SensorDataReader extends DataReader implements SensorEventListener {
+ private SensorManager mSensorManager;
+ private Map senseDataStruct = new HashMap<>();
+ private Vector sensorVector = new Vector<>();
+ Context ctx;
+ private List sensorList = new ArrayList<>();
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ public SensorDataReader(Context context) {
+ ctx = context;
+ SharedPreferences sharedPreferences = ctx.getSharedPreferences(SupportedSensors.SELECTED_SENSORS, Context
+ .MODE_MULTI_PROCESS);
+ Set selectedSet = sharedPreferences.getStringSet(SupportedSensors.SELECTED_SENSORS_BY_USER, null);
+ mSensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
+ selectedSensorList(selectedSet);
+ for (Sensor sensor : sensorList) {
+ mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ }
+
+ private void collectSensorData() {
+ for (Sensor sensor : sensorList) {
+ try {
+ if (senseDataStruct.containsKey(sensor.getName())) {
+ SensorData sensorInfo = senseDataStruct.get(sensor.getName());
+ sensorVector.add(sensorInfo);
+ Log.d(this.getClass().getName(), "Sensor Name " + sensor.getName() + ", Type " + sensor.getType() + " " +
+ ", sensorValue :" + sensorInfo.getSensorValues());
+ }
+ } catch (Throwable e) {
+ Log.d(this.getClass().getName(), "error on sensors");
+ }
+
+ }
+ mSensorManager.unregisterListener(this);
+ }
+
+ public Vector getSensorData() {
+ try {
+ TimeUnit.MILLISECONDS.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ Log.e(SensorDataReader.class.getName(), e.getMessage());
+ }
+ collectSensorData();
+ return sensorVector;
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ senseDataStruct.put(event.sensor.getName(), new SensorData(event));
+ }
+
+ @Override
+ public void run() {
+ Log.d(this.getClass().getName(), "running -sensorDataMap");
+ Vector sensorDatas = getSensorData();
+ for (SensorData data : sensorDatas) {
+ SenseDataHolder.getSensorDataHolder().add(data);
+ }
+ }
+
+ public void selectedSensorList(Set set) {
+ if (set != null) {
+ String[] sensorsSet = set.toArray(new String[set.size()]);
+ for (String s : sensorsSet) {
+ sensorList.add(mSensorManager.getDefaultSensor(supportedSensors.getType(s.toLowerCase())));
+ }
+ }
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java
new file mode 100644
index 000000000..666e02a85
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.battery;
+
+import android.content.Intent;
+import android.os.BatteryManager;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the battery data that is been collected.
+ * look at http://developer.android.com/reference/android/os/BatteryManager.html for field description.
+ */
+public class BatteryData {
+
+ private int health;
+ private int level;
+ private int plugged;
+ private int present;
+ private int scale;
+ private int status;
+ private int temperature;
+ private int voltage;
+ private long timestamp;
+
+ BatteryData(Intent intent) {
+ timestamp = new Date().getTime();
+ health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);
+ level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ present = intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT) ? 1 : 0;
+ scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
+ status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
+ String technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY);
+ temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+ voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
+
+ }
+
+ public int getHealth() {
+ return health;
+ }
+
+ public void setHealth(int health) {
+ this.health = health;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public int getPlugged() {
+ return plugged;
+ }
+
+ public void setPlugged(int plugged) {
+ this.plugged = plugged;
+ }
+
+ public int getPresent() {
+ return present;
+ }
+
+ public void setPresent(int present) {
+ this.present = present;
+ }
+
+ public int getScale() {
+ return scale;
+ }
+
+ public void setScale(int scale) {
+ this.scale = scale;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(int temperature) {
+ this.temperature = temperature;
+ }
+
+ public int getVoltage() {
+ return voltage;
+ }
+
+ public void setVoltage(int voltage) {
+ this.voltage = voltage;
+ }
+
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java
new file mode 100644
index 000000000..9fffa1c15
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.event.streams.battery;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+/**
+ * Whenever the battery level changes This receiver will be triggered.
+ */
+public class BatteryDataReceiver extends BroadcastReceiver {
+
+ /**
+ * when the data is retreived then its added to a inmemory map.
+ *
+ * @param context of the reciever.
+ * @param intent of the reciver
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent));
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java
new file mode 100644
index 000000000..053b7e38c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.NavigationView;
+import android.support.design.widget.Snackbar;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.RegisterActivity;
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherReceiver;
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherService;
+import org.wso2.carbon.iot.android.sense.event.SenseScheduleReceiver;
+import org.wso2.carbon.iot.android.sense.event.SenseService;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.RealTimeSensorChangeReceiver;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensorReader;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.sensor.selector.SelectSensorDialog;
+import org.wso2.carbon.iot.android.sense.speech.detector.WordRecognitionActivity;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * Activity for selecting sensors available in the device
+ */
+
+public class ActivitySelectSensor extends AppCompatActivity
+ implements NavigationView.OnNavigationItemSelectedListener, SelectSensorDialog.SensorListListener {
+
+ private SharedPreferences sharedPreferences;
+ private SelectSensorDialog sensorDialog = new SelectSensorDialog();
+ private Set selectedSensorSet = new HashSet<>();
+ private ListView listView;
+ private SensorManager sensorManager;
+ private ArrayList sensors = new ArrayList<>();
+
+ private RealTimeSensorReader sensorReader = null;
+ private RealTimeSensorChangeReceiver realTimeSensorChangeReceiver = new RealTimeSensorChangeReceiver();
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_activity_select_sensor);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+
+ listView = (ListView) findViewById(R.id.senseListContainer);
+
+ registerReceiver(realTimeSensorChangeReceiver, new IntentFilter("sensorDataMap"));
+
+ //Publish data
+ FloatingActionButton fbtnPublishData = (FloatingActionButton) findViewById(R.id.publish);
+
+ fbtnPublishData.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Snackbar.make(view, "Publishing data started", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+
+ DataPublisherReceiver dataPublisherReceiver = new DataPublisherReceiver();
+ dataPublisherReceiver.clearAbortBroadcast();
+ dataPublisherReceiver.onReceive(getApplicationContext(), null);
+ }
+ });
+
+ FloatingActionButton fbtnAddSensors = (FloatingActionButton) findViewById(R.id.addSensors);
+ fbtnAddSensors.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ sensorDialog.show(getFragmentManager(), "Sensor List");
+ }
+ });
+
+ FloatingActionButton fbtnSpeechRecongnizer = (FloatingActionButton) findViewById(R.id.speech);
+ fbtnSpeechRecongnizer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ EditText sessionIdText = (EditText) findViewById(R.id.sessionId);
+ String sessionId = sessionIdText.getText().toString();
+ if (!sessionId.isEmpty()) {
+ Intent intent = new Intent(getApplicationContext(), WordRecognitionActivity.class);
+ intent.putExtra("sessionId", sessionId);
+ startActivity(intent);
+ } else {
+ Toast.makeText(ActivitySelectSensor.this, "Please type a session id value", Toast.LENGTH_SHORT)
+ .show();
+ }
+
+ }
+ });
+
+ sharedPreferences = getSharedPreferences(SupportedSensors.SELECTED_SENSORS, 0);
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.activity_select_sensor, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_deEnroll) {
+
+ /**
+ * unregister the sensors and broadcast receivers.
+ * */
+ unregisterSensors();
+ unregisterReceivers();
+
+ if (!LocalRegistry.isExist(getApplicationContext())) {
+ Intent activity = new Intent(getApplicationContext(), RegisterActivity.class);
+ startActivity(activity);
+ }
+
+ LocalRegistry.removeUsername(getApplicationContext());
+ LocalRegistry.removeDeviceId(getApplicationContext());
+ LocalRegistry.removeServerURL(getApplicationContext());
+ LocalRegistry.setExist(false);
+ //Stop the current running background services.
+ stopService(new Intent(this, SenseService.class)); //Stop sensor reading service
+ stopService(new Intent(this, DataPublisherService.class)); //Stop data uploader service
+
+ Intent registerActivity = new Intent(getApplicationContext(), RegisterActivity.class);
+ registerActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(registerActivity);
+ finish();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+
+ if (id == R.id.select) {
+ sensorDialog.show(getFragmentManager(), "Sensor List");
+ }
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+
+ @Override
+ public void onDialogPositiveClick(SelectSensorDialog dialog) {
+
+ Log.d("Selected sensors", dialog.getSet().toString());
+ selectedSensorSet = dialog.getSet();
+ update();
+ unregisterSensors();
+
+ SenseScheduleReceiver senseScheduleReceiver = new SenseScheduleReceiver();
+ senseScheduleReceiver.clearAbortBroadcast();
+ senseScheduleReceiver.onReceive(this, null);
+
+ /**
+ * Get the selected sensors
+ * Register them
+ * */
+ SensorViewAdaptor adaptor1 = new SensorViewAdaptor(getApplicationContext(), TempStore.sensorArrayList);
+ adaptor1.notifyDataSetChanged();
+
+ sensorReader = new RealTimeSensorReader(this, adaptor1);
+ getSensors();
+
+ for (Sensor s : sensors) {
+ sensorManager.registerListener(sensorReader, s, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ realTimeSensorChangeReceiver.updateOnChange(adaptor1);
+ listView.setAdapter(adaptor1);
+
+ }
+
+ public void update() {
+ Log.d("Update", "Set the values to Shared Preferences");
+
+ TempStore.sensorArrayList.clear();
+ TempStore.sensorDataMap.clear();
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putStringSet(SupportedSensors.SELECTED_SENSORS_BY_USER, selectedSensorSet);
+ editor.apply();
+ }
+
+ public void getSensors() {
+ sensors.clear();
+ for (String sensor : selectedSensorSet.toArray(new String[selectedSensorSet.size()])) {
+ sensors.add(sensorManager.getDefaultSensor(supportedSensors.getType(sensor.toLowerCase())));
+ }
+ }
+
+ /**
+ * This method will unregister all the registered sensors.
+ */
+ public void unregisterSensors() {
+ if (sensors.size() > 0) {
+ for (Sensor s : sensors) {
+ System.out.println(s.getName() + " Unregistered!");
+ sensorManager.unregisterListener(sensorReader, s);
+ }
+ }
+ }
+
+ /**
+ * This method unregisters the real-time broadcast receiver.
+ */
+ public void unregisterReceivers() {
+ unregisterReceiver(realTimeSensorChangeReceiver);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java
new file mode 100644
index 000000000..2e5343834
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.datastore;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensor;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Class to store the real time sensor readings.
+ */
+public class TempStore {
+
+ /**
+ * Hash map which is used to store sensor values with the sensor names.
+ */
+ public static ConcurrentMap sensorDataMap = new ConcurrentHashMap<>();
+
+ /**
+ * Array List which is used to populate the List view.
+ */
+ public static ArrayList sensorArrayList = new ArrayList<>();
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java
new file mode 100644
index 000000000..c231ac87e
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.event;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+
+/**
+ * This class is to detect the sensor change event and update the sensor array list.
+ * And update the view adaptor which is used to show the sensors list in the Android List view.
+ */
+public class RealTimeSensorChangeReceiver extends BroadcastReceiver {
+
+ SensorViewAdaptor adaptor;
+
+ public void updateOnChange(SensorViewAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ TempStore.sensorArrayList.clear();
+ TempStore.sensorArrayList.addAll(TempStore.sensorDataMap.values());
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java
new file mode 100644
index 000000000..6a71739dc
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor;
+
+import android.support.annotation.NonNull;
+
+/**
+ * The class to store the sensor data captured by the RealTimeSensorReader.
+ */
+public class RealTimeSensor implements Comparable {
+
+
+ /**
+ * Name of the sensor.
+ */
+ private String name;
+
+ /**
+ * The X value reading of the sensor.
+ */
+ private String valueX;
+
+ /**
+ * The Y value reading of the sensor.
+ */
+ private String valueY;
+
+ /**
+ * The Y value reading of the sensor.
+ */
+ private String valueZ;
+
+ public RealTimeSensor() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getValueX() {
+ return valueX;
+ }
+
+ public void setValueX(String valueX) {
+ this.valueX = valueX;
+ }
+
+ public String getValueY() {
+ return valueY;
+ }
+
+ public void setValueY(String valueY) {
+ this.valueY = valueY;
+ }
+
+ public String getValueZ() {
+ return valueZ;
+ }
+
+ public void setValueZ(String valueZ) {
+ this.valueZ = valueZ;
+ }
+
+ @Override
+ public String toString() {
+ return this.valueX + ", " + valueY + ", " + valueZ;
+ }
+
+ @Override
+ public int compareTo(@NonNull Object another) {
+ return this.toString().contains(another.toString()) ? 1 : 0;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java
new file mode 100644
index 000000000..fc4b474e6
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+
+/**
+ * This class reads the sensor values in real time.
+ */
+public class RealTimeSensorReader implements SensorEventListener {
+
+ private Context context;
+ private SensorViewAdaptor adaptor;
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ public RealTimeSensorReader(Context context, SensorViewAdaptor adaptor) {
+ this.context = context;
+ this.adaptor = adaptor;
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ RealTimeSensor realTimeSensor = new RealTimeSensor();
+ realTimeSensor.setName(supportedSensors.getType(event.sensor.getType()).toUpperCase());
+
+ realTimeSensor.setValueX(event.values[0] + "");
+ realTimeSensor.setValueY(event.values[1] + "");
+ realTimeSensor.setValueZ(event.values[2] + "");
+
+ TempStore.sensorDataMap.put(supportedSensors.getType(event.sensor.getType()), realTimeSensor);
+
+ Intent intent = new Intent();
+ intent.setAction("sensorDataMap");
+ context.sendBroadcast(intent);
+
+ adaptor.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java
new file mode 100644
index 000000000..726c8cded
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Class to save the list of sensors that are available in the device, which are supported by the iot server.
+ * This list will be saved in Shared preferences so that app can use this data when needed.
+ */
+public class AvailableSensorsInDevice {
+
+ private SharedPreferences sensorPreference;
+
+ /**
+ * The Android sensor manager which is used to get the sensors available in device.
+ */
+ private SensorManager mSensorManager;
+
+ public AvailableSensorsInDevice(Context context) {
+ this.sensorPreference = context.getSharedPreferences(SupportedSensors.AVAILABLE_SENSORS, 0);
+ this.mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ }
+
+ /**
+ * This method filters the pre defined sensor types from sensors available in device and sets them in Shared
+ * preferences.
+ */
+ public void setContent() {
+ SupportedSensors supportedSensors = SupportedSensors.getInstance();
+ List sensor_List = supportedSensors.getSensorList();
+ Set sensorSet = new HashSet<>();
+ List sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+
+ for (String sen : sensor_List) {
+ if (sensors.contains(mSensorManager.getDefaultSensor(supportedSensors.getType(sen.toLowerCase())))) {
+ sensorSet.add(sen);
+ }
+ }
+
+ SharedPreferences.Editor editor = this.sensorPreference.edit();
+ editor.putStringSet(SupportedSensors.GET_AVAILABLE_SENSORS, sensorSet);
+ editor.apply();
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java
new file mode 100644
index 000000000..6d57e6d70
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting;
+
+import android.hardware.Sensor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Class to store the supported sensorDataMap types.
+ */
+public class SupportedSensors {
+
+ //For set user selected sensors. Will be used by sensorDataMap reading and dialog
+ public static String SELECTED_SENSORS = "Selected";
+ public static String SELECTED_SENSORS_BY_USER = "userSelection";
+
+ //For setting the available sensors in the device in dialog and AvailableSensorsInDevice
+ public static String AVAILABLE_SENSORS = "Sensors";
+ public static String GET_AVAILABLE_SENSORS = "getAvailableSensors";
+
+ public static final int SUPPORTED_SENSOR_COUNT = 10;
+ private static List sensorList = new ArrayList<>();
+ private static HashMap sensorTypeMap = new HashMap<>();
+ private static HashMap typeSensorMap = new HashMap<>();
+ private static SupportedSensors supportedSensors = new SupportedSensors();
+
+ private SupportedSensors() {
+ this.setList();
+ this.setSensorTypeMap();
+ this.setTypeSensorMap();
+ }
+
+ public static SupportedSensors getInstance() {
+ return supportedSensors;
+ }
+
+ /**
+ * Set the supported sensor types by the IOT server.
+ */
+ private void setList() {
+ sensorList.add("Accelerometer");
+ sensorList.add("Magnetometer");
+ sensorList.add("Gravity");
+ sensorList.add("Rotation Vector");
+ sensorList.add("Pressure");
+ sensorList.add("Light");
+ sensorList.add("Gyroscope");
+ sensorList.add("Proximity");
+ }
+
+ /**
+ * Populate the hash map which has Sensor name as the key and the sensor type as the value.
+ */
+ private void setSensorTypeMap() {
+ sensorTypeMap.put("accelerometer", Sensor.TYPE_ACCELEROMETER);
+ sensorTypeMap.put("magnetometer", Sensor.TYPE_MAGNETIC_FIELD);
+ sensorTypeMap.put("gravity", Sensor.TYPE_GRAVITY);
+ sensorTypeMap.put("rotation vector", Sensor.TYPE_GAME_ROTATION_VECTOR);
+ sensorTypeMap.put("pressure", Sensor.TYPE_PRESSURE);
+ sensorTypeMap.put("gyroscope", Sensor.TYPE_GYROSCOPE);
+ sensorTypeMap.put("light", Sensor.TYPE_LIGHT);
+ sensorTypeMap.put("proximity", Sensor.TYPE_PROXIMITY);
+ }
+
+ /**
+ * Populates the hash map which has Sensor type as the key and sensor name as the value.
+ */
+ private void setTypeSensorMap() {
+ typeSensorMap.put(Sensor.TYPE_ACCELEROMETER, "accelerometer");
+ typeSensorMap.put(Sensor.TYPE_MAGNETIC_FIELD, "magnetometer");
+ typeSensorMap.put(Sensor.TYPE_GRAVITY, "gravity");
+ typeSensorMap.put(Sensor.TYPE_GAME_ROTATION_VECTOR, "rotation vector");
+ typeSensorMap.put(Sensor.TYPE_PRESSURE, "pressure");
+ typeSensorMap.put(Sensor.TYPE_GYROSCOPE, "gyroscope");
+ typeSensorMap.put(Sensor.TYPE_LIGHT, "light");
+ typeSensorMap.put(Sensor.TYPE_PROXIMITY, "proximity");
+ }
+
+ /**
+ * Method to get the supported sensor list.
+ *
+ * @return the list of sensors supported by the iot server.
+ */
+ public List getSensorList() {
+ return sensorList;
+ }
+
+
+ /**
+ * @param sensor The name of the sensor.
+ * @return The integer representing the type of the sensor,
+ */
+ public int getType(String sensor) {
+ return sensorTypeMap.get(sensor);
+ }
+
+
+ /**
+ * @param type The type of the sensor.
+ * @return The sensor name related to the given sensor type.
+ */
+ public String getType(int type) {
+ return typeSensorMap.get(type);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java
new file mode 100644
index 000000000..d2d852226
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensor;
+
+import java.util.List;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * Adaptor for populate the ListView.
+ * Takes list of Sensor readings
+ */
+
+//TODO : Add the location and battery data sections.
+public class SensorViewAdaptor extends BaseAdapter {
+
+ private Context context;
+ private List data;
+
+ public SensorViewAdaptor(Context context, List data) {
+ this.context = context;
+ this.data = data;
+ }
+
+ @Override
+ public int getCount() {
+ return data.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return data.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view;
+
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.display_sensor_values, parent, false);
+ holder = new ViewHolder();
+ holder.name = (TextView) view.findViewById(R.id.name);
+ holder.valuesX = (TextView) view.findViewById(R.id.X);
+ holder.valuesY = (TextView) view.findViewById(R.id.Y);
+ holder.valuesZ = (TextView) view.findViewById(R.id.Z);
+ view.setTag(holder);
+ } else {
+ view = convertView;
+ holder = (ViewHolder) view.getTag();
+ }
+
+ RealTimeSensor data = this.data.get(position);
+
+ holder.name.setText(data.getName());
+ holder.valuesX.setText(data.getValueX());
+ holder.valuesY.setText(data.getValueY());
+ holder.valuesZ.setText(data.getValueZ());
+
+ return view;
+
+ }
+
+ private class ViewHolder {
+ public TextView name;
+ public TextView valuesX;
+ public TextView valuesY;
+ public TextView valuesZ;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java
new file mode 100644
index 000000000..5c163c802
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.realtimeviewer.view.sensor.selector;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Functionality
+ *
+ * Show the list of available sensors in a list
+ * Get the user selections
+ * Put them in to shared preferences
+ */
+
+public class SelectSensorDialog extends DialogFragment {
+
+ protected boolean[] selections = new boolean[SupportedSensors.SUPPORTED_SENSOR_COUNT];
+ Activity activity;
+ SensorListListener sensorListListener;
+ private Set selectedSensorSet = new HashSet<>();
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle("Select Sensors");
+ activity = getActivity();
+
+ SharedPreferences preferences = getActivity().getSharedPreferences(SupportedSensors.AVAILABLE_SENSORS, Context.
+ MODE_MULTI_PROCESS);
+
+ Set set = preferences.getStringSet(SupportedSensors.GET_AVAILABLE_SENSORS, null);
+ final CharSequence[] sequence = getSequence(set);
+
+ final boolean[] pos = new boolean[selections.length];
+ final boolean[] neg = new boolean[selections.length];
+
+ builder.setMultiChoiceItems(sequence, selections, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ selectedSensorSet.add(sequence[which].toString());
+
+ pos[which] = true;
+ } else {
+ selectedSensorSet.remove(sequence[which].toString());
+ neg[which] = true;
+ }
+ }
+ });
+
+ builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Log.d("Click", "Ok");
+ //call sensorDataMap reading class
+ sensorListListener.onDialogPositiveClick(SelectSensorDialog.this);
+
+ }
+ });
+
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Log.d("Click", "Cancel");
+ for (int i = 0; i < SupportedSensors.SUPPORTED_SENSOR_COUNT; i++) {
+
+ if (pos[i])
+ selections[i] = false;
+ if (neg[i])
+ selections[i] = true;
+ }
+ }
+ });
+
+ return builder.create();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ try {
+ sensorListListener = (SensorListListener) getActivity();
+ } catch (ClassCastException ex) {
+ throw new ClassCastException(activity.toString() + " must implement the SensorListener");
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ /**
+ * Interface to be implemented by the parent
+ */
+ public CharSequence[] getSequence(Set sensorset) {
+ CharSequence[] seq;
+ String[] seq2 = sensorset.toArray(new String[sensorset.size()]);
+ seq = Arrays.copyOf(seq2, seq2.length);
+ return seq;
+ }
+
+ public Set getSet() {
+ return this.selectedSensorSet;
+ }
+
+ public interface SensorListListener {
+ void onDialogPositiveClick(SelectSensorDialog dialog);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java
new file mode 100644
index 000000000..83b702d45
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.speech.detector;
+
+/**
+ * This interface is used to retrieve the voice commands and restart the listenting service
+ */
+public interface IVoiceControl {
+ /**
+ * This will be executed when a voice command was found
+ * @param voiceCommands
+ */
+ public abstract void processVoiceCommands(String... voiceCommands);
+
+ /**
+ * This will be executed after a voice command was processed to keep the recognition service activated
+ */
+ public void restartListeningService();
+
+ public void finish();
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java
new file mode 100644
index 000000000..903b6c3a8
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java
@@ -0,0 +1,132 @@
+package org.wso2.carbon.iot.android.sense.speech.detector;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.ActivitySelectSensor;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ListeningActivity;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.VoiceRecognitionListener;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+public class WordRecognitionActivity extends ListeningActivity {
+ Button setThreasholdButton;
+ Button addWordButton;
+ Button removeWordButton;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_speech_sense_main);
+ context = getApplicationContext(); // Needs to be set
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ VoiceRecognitionListener.getInstance().setListener(this); // Here we set the current listener
+ addListenerOnSetThreasholdButton();
+ addListenerOnAddWordButton();
+ addListenerOnRemoveWordButton();
+ String sessionId = getIntent().getStringExtra("sessionId");
+ ProcessWords.setSessionId(sessionId);
+ FloatingActionButton fbtnSpeechRecongnizer = (FloatingActionButton) findViewById(R.id.sensorChange);
+ fbtnSpeechRecongnizer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ WordData wordData = new WordData(ProcessWords.getSessionId(), SenseConstants.EVENT_LISTENER_FINISHED, 1);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ stopListening();
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ });
+ Long tsLong = System.currentTimeMillis() / 1000;
+ WordData wordData = new WordData(sessionId, SenseConstants.EVENT_LISTENER_STARTED, 1);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ startListening(); // starts listening
+ }
+
+ @Override
+ public void onBackPressed() {
+ }
+
+ @Override
+ public void processVoiceCommands(String... voiceCommands) {
+ if(voiceCommands==null || voiceCommands.length==0){
+ return;
+ }
+ ProcessWords processWords = new ProcessWords(this);
+ processWords.execute(voiceCommands);
+ restartListeningService();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ // getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_deEnroll) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ public void addListenerOnSetThreasholdButton() {
+ setThreasholdButton = (Button) findViewById(R.id.setThreshold);
+ setThreasholdButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String thresholdString = ((EditText) findViewById(R.id.editThreashold)).getText().toString();
+ try{
+ ProcessWords.setThreshold(Integer.parseInt(thresholdString));
+ } catch (NumberFormatException e) {
+ Toast.makeText(WordRecognitionActivity.this, "Invalid Threshold - " + thresholdString, Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ }
+
+ public void addListenerOnAddWordButton() {
+ addWordButton = (Button) findViewById(R.id.addWord);
+ addWordButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String word = ((EditText) findViewById(R.id.wordText)).getText().toString();
+ ProcessWords.addWord(word);
+ Toast.makeText(WordRecognitionActivity.this, word + " is added to the list", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ public void addListenerOnRemoveWordButton() {
+ removeWordButton = (Button) findViewById(R.id.removeWord);
+ removeWordButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String word = ((EditText) findViewById(R.id.wordText)).getText().toString();
+ Toast.makeText(WordRecognitionActivity.this, word + " is removed from the list", Toast.LENGTH_SHORT).show();
+ ProcessWords.removeWord(word);
+ }
+
+ });
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java
new file mode 100644
index 000000000..db37583b5
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.speech.RecognizerIntent;
+import android.speech.SpeechRecognizer;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.speech.detector.IVoiceControl;
+
+/**
+ * This Activity Contols the Speech Recognizer Activity.
+ */
+public abstract class ListeningActivity extends Activity implements IVoiceControl {
+
+ protected SpeechRecognizer sr;
+ protected Context context;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ /**
+ * Starts the listening service.
+ */
+ protected void startListening() {
+ initSpeech();
+ Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
+ sr.startListening(intent);
+ }
+
+ /**
+ * Stop the listening service.
+ */
+ protected void stopListening() {
+ if (sr != null) {
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+ }
+ sr = null;
+ }
+
+ /**
+ * Initialize the speech.
+ */
+ protected void initSpeech() {
+ if (sr == null) {
+ sr = SpeechRecognizer.createSpeechRecognizer(this);
+ if (!SpeechRecognizer.isRecognitionAvailable(context)) {
+ Toast.makeText(context, "Speech Recognition is not available",
+ Toast.LENGTH_LONG).show();
+ finish();
+ }
+ sr.setRecognitionListener(VoiceRecognitionListener.getInstance());
+ }
+ }
+
+ @Override
+ public void finish() {
+ stopListening();
+ super.finish();
+ }
+
+ @Override
+ protected void onStop() {
+ stopListening();
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (sr != null) {
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause() {
+ if(sr!=null){
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+
+ }
+ sr = null;
+
+ super.onPause();
+ }
+
+ /**
+ * Is abstract so the inheriting classes need to implement it. Here you put your code which should be executed once
+ * a command was found
+ */
+ @Override
+ public abstract void processVoiceCommands(String ... voiceCommands);
+
+ @Override
+ public void restartListeningService() {
+ stopListening();
+ startListening();
+ }
+}
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java
new file mode 100644
index 000000000..9933904a5
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.widget.EditText;
+
+import org.apache.commons.codec.language.Soundex;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.tartarus.snowball.ext.englishStemmer;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * This class process the words form required words with the recongnized words to check whether it matches with the
+ * certain threshold.
+ */
+public class ProcessWords extends AsyncTask {
+ private static volatile double threshold = 80;
+ private static volatile Map wordDataMap = new ConcurrentHashMap<>();
+ private static String sessionId = "default";
+ private static Soundex soundex = new Soundex();
+ Activity activity;
+
+ public ProcessWords(Activity activity) {
+ this.activity = activity;
+ }
+
+ /**
+ * Add the list of words which are used for reference.
+ * @param wordlist that needs to be looked upon in the speech
+ */
+ public static void addWords(List wordlist) {
+ for (String word : wordlist) {
+ if (!wordDataMap.keySet().contains(word) && !word.isEmpty()) {
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+ }
+
+ /**
+ * Process the recognized word list.
+ * @param voiceCommands word lists.
+ */
+ private void processTexts(String... voiceCommands) {
+ for (String requiredWord : wordDataMap.keySet()) {
+ int maxOccurunce = 0;
+ for (String command : voiceCommands) {
+ int occurence = 0;
+ for (String word : command.split(" ")) {
+ if (StringSimilarity.similarity(requiredWord, word) > threshold) {
+ occurence++;
+ continue;
+ }
+ if (soundex.encode(requiredWord).equals(soundex.encode(word))) {
+ occurence++;
+ continue;
+ }
+ if (StringSimilarity.similarity(requiredWord, stem(word)) > threshold) {
+ occurence++;
+ continue;
+ }
+ }
+ if (maxOccurunce < occurence) {
+ maxOccurunce = occurence;
+ }
+ }
+ if (maxOccurunce > 0) {
+ WordData wordData = wordDataMap.get(requiredWord);
+ wordData.addOccurences(maxOccurunce);
+ wordDataMap.put(requiredWord, wordData);
+ }
+ }
+ }
+
+ /**
+ * Check for distance between the referenced and recognized words.
+ * @param params
+ * @return
+ */
+ @Override
+ protected String doInBackground(String... params) {
+ processTexts(params);
+ publishProgress();
+ return "";
+ }
+
+ /**
+ * update it in the UI.
+ * @param values words list.
+ */
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ super.onProgressUpdate(values);
+ EditText content = (EditText) activity.findViewById(R.id.command);
+ String text = "";
+ for (String key : ProcessWords.wordDataMap.keySet()) {
+ text = text + key + " - " + ProcessWords.wordDataMap.get(key).getOccurences() + "\n";
+ }
+ content.setText(text);
+ EditText thresholdText = (EditText) activity.findViewById(R.id.editThreashold);
+ thresholdText.setText("" + threshold);
+ }
+
+ /**
+ * set the threshold to determine the distance.
+ * @param threshold to determine the distance.
+ */
+ public static synchronized void setThreshold(int threshold) {
+ ProcessWords.threshold = threshold;
+ }
+
+ /**
+ *
+ * @param sessionId for each listening session.
+ */
+ public static synchronized void setSessionId(String sessionId) {
+ ProcessWords.sessionId = sessionId;
+ }
+
+ /**
+ *
+ * retrieve sessionId for each listening session.
+ */
+ public static synchronized String getSessionId() {
+ return ProcessWords.sessionId;
+ }
+
+ /**
+ * @param word that is used for refrerence.
+ */
+ public static synchronized void addWord(String word) {
+ if (!wordDataMap.keySet().contains(word) && !word.isEmpty()) {
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+
+ /**
+ *
+ * @param word that needs to be removed from the reference list.
+ */
+ public static synchronized void removeWord(String word) {
+ cleanAndPushToWordMap();
+ wordDataMap.remove(word);
+ }
+
+ /**
+ * clean in memory content and pubish it to the server.
+ */
+ public static synchronized void cleanAndPushToWordMap() {
+ for (String word : wordDataMap.keySet()) {
+ WordData wordData = wordDataMap.get(word);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+
+ /**
+ * apply porter stem algorithm
+ * @param word to be stemmed.
+ * @return
+ */
+ private static String stem(String word)
+ {
+ englishStemmer stemmer = new englishStemmer();
+ stemmer.setCurrent(word);
+ boolean result = stemmer.stem();
+ if (!result)
+ {
+ return word;
+ }
+ return stemmer.getCurrent();
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java
new file mode 100644
index 000000000..a44e304f4
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+/**
+ * Calculates the similarity of strings.
+ */
+public class StringSimilarity {
+
+ /**
+ * Calculates the similarity (a number within 0 and 1) between two strings.
+ */
+ public static double similarity(String s1, String s2) {
+ String longer = s1, shorter = s2;
+ if (s1.length() < s2.length()) { // longer should always have greater length
+ longer = s2;
+ shorter = s1;
+ }
+ int longerLength = longer.length();
+ if (longerLength == 0) {
+ return 1.0; /* both strings are zero length */
+ }
+ return ((longerLength - editDistance(longer, shorter)) / (double) longerLength) * 100;
+ }
+
+ // Example implementation of the Levenshtein Edit Distance
+ // See http://rosettacode.org/wiki/Levenshtein_distance#Java
+ private static int editDistance(String s1, String s2) {
+ s1 = s1.toLowerCase();
+ s2 = s2.toLowerCase();
+
+ int[] costs = new int[s2.length() + 1];
+ for (int i = 0; i <= s1.length(); i++) {
+ int lastValue = i;
+ for (int j = 0; j <= s2.length(); j++) {
+ if (i == 0)
+ costs[j] = j;
+ else {
+ if (j > 0) {
+ int newValue = costs[j - 1];
+ if (s1.charAt(i - 1) != s2.charAt(j - 1))
+ newValue = Math.min(Math.min(newValue, lastValue),
+ costs[j]) + 1;
+ costs[j - 1] = lastValue;
+ lastValue = newValue;
+ }
+ }
+ }
+ if (i > 0)
+ costs[s2.length()] = lastValue;
+ }
+ return costs[s2.length()];
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java
new file mode 100644
index 000000000..52ce8d52f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.os.Bundle;
+import android.speech.RecognitionListener;
+import android.speech.SpeechRecognizer;
+import org.wso2.carbon.iot.android.sense.speech.detector.IVoiceControl;
+import java.util.ArrayList;
+
+/**
+ * This triggers android voice recognition listener.
+ */
+public class VoiceRecognitionListener implements RecognitionListener {
+ private static VoiceRecognitionListener instance = null;
+
+ IVoiceControl listener; // This is your running activity (we will initialize it later)
+
+ public static VoiceRecognitionListener getInstance() {
+ if (instance == null) {
+ instance = new VoiceRecognitionListener();
+ }
+ return instance;
+ }
+
+ private VoiceRecognitionListener() { }
+
+ public void setListener(IVoiceControl listener) {
+ this.listener = listener;
+ }
+
+ public void processVoiceCommands(String... voiceCommands) {
+ listener.processVoiceCommands(voiceCommands);
+ }
+
+ // This method will be executed when voice commands were found
+ public void onResults(Bundle data) {
+ ArrayList matches = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
+ String[] commands = new String[matches.size()];
+ commands = matches.toArray(commands);
+ processVoiceCommands(commands);
+ }
+
+ // User starts speaking
+ public void onBeginningOfSpeech() {
+ System.out.println("Starting to listen");
+ }
+
+ public void onBufferReceived(byte[] buffer) { }
+
+ // User finished speaking
+ public void onEndOfSpeech() {
+ System.out.println("Waiting for result...");
+ }
+
+ // If the user said nothing the service will be restarted
+ public void onError(int error) {
+ if (listener != null) {
+ listener.restartListeningService();
+ }
+ }
+ public void onEvent(int eventType, Bundle params) { }
+
+ public void onPartialResults(Bundle partialResults) { }
+
+ public void onReadyForSpeech(Bundle params) { }
+
+ public void onRmsChanged(float rmsdB) { }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java
new file mode 100644
index 000000000..fb76eab24
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java
@@ -0,0 +1,47 @@
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+/**
+ * This defines the data structure of the word data.
+ */
+public class WordData {
+ /**
+ * timestamp for all the occurences
+ */
+ private long timestamp;
+ private int occurences;
+ private String word;
+ private String sessionId;
+
+ public WordData(String sessionId, String word, int occurences) {
+ this.timestamp = System.currentTimeMillis() / 1000;
+ this.occurences = occurences;
+ this.word = word;
+ this.sessionId = sessionId;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public int getOccurences() {
+ return occurences;
+ }
+
+ public String getWord() {
+ return word;
+ }
+
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * @param occurences for the word and then add the timestamp for each occurences.
+ */
+ public void addOccurences(int occurences) {
+ this.occurences = this.occurences + occurences;
+ this.timestamp = System.currentTimeMillis() / 1000;
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java
new file mode 100644
index 000000000..e9d3d430f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * This is used to store the values in either in memory or in shared preferences.
+ */
+public class LocalRegistry {
+
+ private static final String SENSE_SHARED_PREFERENCES = "senseSharedPreferences";
+ private static final String USERNAME_KEY = "usernameKey";
+ private static final String DEVICE_ID_KEY = "deviceIdKey";
+ private static final String SERVER_HOST_KEY = "serverHostKey";
+ private static final String ACCESS_TOKEN_KEY = "accessTokenKey";
+ private static final String REFRESH_TOKEN_KEY = "refreshTokenKey";
+ private static final String MQTT_PORT_KEY = "mqttPort";
+ private static boolean exists = false;
+ private static String username;
+ private static String deviceId;
+ private static String serverURL;
+ private static MQTTTransportHandler mqttTransportHandler;
+ private static String accessToken;
+ private static String refreshToken;
+ private static int mqttPort;
+
+ public static boolean isExist(Context context) {
+ if (!exists) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ String username = sharedpreferences.getString(USERNAME_KEY, "");
+ String deviceId = sharedpreferences.getString(DEVICE_ID_KEY, "");
+ exists = (username != null && !username.isEmpty() && deviceId != null && !deviceId.isEmpty());
+ }
+ return exists;
+ }
+
+ public static void setExist(boolean status) {
+ exists = status;
+ }
+
+
+ public static void addUsername(Context context, String username) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(USERNAME_KEY, username);
+ editor.commit();
+ LocalRegistry.username = username;
+ }
+
+ public static String getUsername(Context context) {
+ if (LocalRegistry.username == null || username.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.username = sharedpreferences.getString(USERNAME_KEY, "");
+ }
+ return LocalRegistry.username;
+ }
+
+ public static void removeUsername(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.clear();
+ editor.remove(USERNAME_KEY);
+ editor.commit();
+ LocalRegistry.username = null;
+ }
+
+ public static void addDeviceId(Context context, String deviceId) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(DEVICE_ID_KEY, deviceId);
+ editor.commit();
+ LocalRegistry.deviceId = deviceId;
+ }
+
+ public static void removeDeviceId(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(DEVICE_ID_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.deviceId = null;
+ }
+
+ public static String getDeviceId(Context context) {
+ if (LocalRegistry.deviceId == null || LocalRegistry.deviceId.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.deviceId = sharedpreferences.getString(DEVICE_ID_KEY, "");
+ }
+ return LocalRegistry.deviceId;
+ }
+
+ public static void addServerURL(Context context, String host) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(SERVER_HOST_KEY, host);
+ editor.commit();
+ LocalRegistry.serverURL = host;
+ }
+
+ public static void removeServerURL(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(SERVER_HOST_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.serverURL = null;
+ }
+
+ public static String getServerURL(Context context) {
+ if (LocalRegistry.serverURL == null || LocalRegistry.serverURL.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.serverURL = sharedpreferences.getString(SERVER_HOST_KEY, "");
+ }
+ return LocalRegistry.serverURL;
+ }
+
+ public static void addAccessToken(Context context, String accessToken) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(ACCESS_TOKEN_KEY, accessToken);
+ editor.commit();
+ LocalRegistry.accessToken = accessToken;
+ }
+
+ public static void removeAccessToken(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(ACCESS_TOKEN_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.accessToken = null;
+ }
+
+ public static String getAccessToken(Context context) {
+ if (LocalRegistry.accessToken == null || LocalRegistry.accessToken.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.accessToken = sharedpreferences.getString(ACCESS_TOKEN_KEY, "");
+ }
+ return LocalRegistry.accessToken;
+ }
+
+ public static void addRefreshToken(Context context, String refreshToken) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(REFRESH_TOKEN_KEY, refreshToken);
+ editor.commit();
+ LocalRegistry.refreshToken = refreshToken;
+ }
+
+ public static void removeRefreshToken(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(REFRESH_TOKEN_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.refreshToken = null;
+ }
+
+ public static String getRefreshToken(Context context) {
+ if (LocalRegistry.refreshToken == null || LocalRegistry.refreshToken.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.refreshToken = sharedpreferences.getString(REFRESH_TOKEN_KEY, "");
+ }
+ return LocalRegistry.refreshToken;
+ }
+
+ public static void addMqttPort(Context context, int port) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putInt(MQTT_PORT_KEY, port);
+ editor.commit();
+ LocalRegistry.mqttPort = port;
+ }
+
+ public static void removeMqttPort(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(MQTT_PORT_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.mqttPort = 0;
+ }
+
+ public static int getMqttPort(Context context) {
+ if (LocalRegistry.mqttPort == 0) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.mqttPort = sharedpreferences.getInt(MQTT_PORT_KEY, SenseConstants.MQTT_BROKER_PORT);
+ }
+ return LocalRegistry.mqttPort;
+ }
+
+ public static String getServerHost(Context context) {
+
+ URL url = null;
+ String urlString = getServerURL(context);
+ try {
+ url = new URL(urlString);
+ return url.getHost();
+ } catch (MalformedURLException e) {
+ Log.e("Host ", "Invalid urlString :" + urlString);
+ return null;
+ }
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java
new file mode 100644
index 000000000..173525b82
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * This Client is used for http communication with the server.
+ */
+public class SenseClient {
+ private final static String TAG = "SenseService Client";
+
+ private Context context;
+
+ public SenseClient(Context context) {
+ this.context = context;
+ }
+
+ /**
+ * Enroll the device.
+ *
+ * @param username
+ * @param password
+ * @param deviceId
+ * @return
+ */
+ public boolean register(String username, String password, String deviceId) {
+ Map response = registerWithTimeWait(username, password, deviceId);
+ String responseStatus = response.get("status");
+ if (responseStatus.trim().contains(SenseConstants.Request.REQUEST_SUCCESSFUL)) {
+ Toast.makeText(context, "Device Registered", Toast.LENGTH_LONG).show();
+ return true;
+ } else if (responseStatus.trim().contains(SenseConstants.Request.REQUEST_CONFLICT)) {
+ Toast.makeText(context, "Login Successful", Toast.LENGTH_LONG).show();
+ return true;
+ } else {
+ Toast.makeText(context, "Authentication failed, please check your credentials and try again.", Toast
+ .LENGTH_LONG).show();
+
+ return false;
+ }
+ }
+
+ public Map registerWithTimeWait(String username, String password, String deviceId) {
+ for (int i = 1; i <= SenseConstants.Request.MAX_ATTEMPTS; i++) {
+ Log.d(TAG, "Attempt #" + i + " to register");
+ try {
+ SenseClientAsyncExecutor senseClientAsyncExecutor = new SenseClientAsyncExecutor(context);
+ String endpoint = LocalRegistry.getServerURL(context);
+ senseClientAsyncExecutor.execute(username, password, deviceId, endpoint);
+ Map response = senseClientAsyncExecutor.get();
+ if (response != null) {
+ return response;
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ Log.e("Send Sensor Data", "Thread Interruption for endpoint " + LocalRegistry.getServerURL(context));
+ } catch (ExecutionException e) {
+ Log.e("Send Sensor Data", "Failed to push data to the endpoint " + LocalRegistry.getServerURL(context));
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java
new file mode 100644
index 000000000..56842f6b2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.util.dto.AccessTokenInfo;
+import org.wso2.carbon.iot.android.sense.util.dto.AndroidSenseManagerService;
+import org.wso2.carbon.iot.android.sense.util.dto.ApiApplicationRegistrationService;
+import org.wso2.carbon.iot.android.sense.util.dto.ApiRegistrationProfile;
+import org.wso2.carbon.iot.android.sense.util.dto.DynamicClientRegistrationService;
+import org.wso2.carbon.iot.android.sense.util.dto.OAuthApplicationInfo;
+import org.wso2.carbon.iot.android.sense.util.dto.OAuthRequestInterceptor;
+import org.wso2.carbon.iot.android.sense.util.dto.RegistrationProfile;
+import org.wso2.carbon.iot.android.sense.util.dto.TokenIssuerService;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import feign.Client;
+import feign.Feign;
+import feign.FeignException;
+import feign.auth.BasicAuthRequestInterceptor;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import feign.jaxrs.JAXRSContract;
+
+public class SenseClientAsyncExecutor extends AsyncTask> {
+
+ private final static String TAG = "SenseService Client";
+ private static final String STATUS = "status";
+ private final static String DEVICE_NAME = Build.MANUFACTURER + " " + Build.MODEL;
+ private Context context;
+
+ public SenseClientAsyncExecutor(Context context) {
+ this.context = context;
+
+ }
+
+ TrustManager[] trustAllCerts = new TrustManager[]{
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+
+ Client disableHostnameVerification = new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
+ @Override
+ public boolean verify(String s, SSLSession sslSession) {
+ return true;
+ }
+ });
+
+ @Override
+ protected Map doInBackground(String... parameters) {
+ if (android.os.Debug.isDebuggerConnected())
+ android.os.Debug.waitForDebugger();
+ String response;
+ Map response_params = new HashMap<>();
+ String username = parameters[0];
+ String password = parameters[1];
+ String deviceId = parameters[2];
+ String endpoint = parameters[3];
+ Map responseMap = new HashMap<>();
+ responseMap.put(STATUS, "200");
+ try {
+ //DynamicClientRegistraiton.
+ DynamicClientRegistrationService dynamicClientRegistrationService = Feign.builder()
+ .client(disableHostnameVerification).contract(new
+ JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(DynamicClientRegistrationService.class, endpoint + SenseConstants.DCR_CONTEXT);
+ RegistrationProfile registrationProfile = new RegistrationProfile();
+ String applicationName = "android-sense:" + deviceId;
+ registrationProfile.setOwner(username);
+ registrationProfile.setClientName(applicationName);
+ registrationProfile.setCallbackUrl("");
+ registrationProfile.setGrantType("password refresh_token client_credentials");
+ registrationProfile.setApplicationType("device");
+ registrationProfile.setTokenScope("production");
+ OAuthApplicationInfo oAuthApplicationInfo = dynamicClientRegistrationService.register(registrationProfile);
+
+ //PasswordGrantType
+ TokenIssuerService tokenIssuerService = Feign.builder().client(disableHostnameVerification).requestInterceptor(
+ new BasicAuthRequestInterceptor(oAuthApplicationInfo.getClient_id(), oAuthApplicationInfo.getClient_secret()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(TokenIssuerService.class, endpoint + SenseConstants.TOKEN_ISSUER_CONTEXT);
+ AccessTokenInfo accessTokenInfo = tokenIssuerService.getToken("password", username, password);
+
+ //ApiApplicationRegistration
+ ApiApplicationRegistrationService apiApplicationRegistrationService = Feign.builder().client(disableHostnameVerification)
+ .requestInterceptor(new OAuthRequestInterceptor(accessTokenInfo.getAccess_token()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(ApiApplicationRegistrationService.class, endpoint + SenseConstants.API_APPLICATION_REGISTRATION_CONTEXT);
+ ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile();
+ apiRegistrationProfile.setApplicationName(applicationName);
+ apiRegistrationProfile.setConsumerKey(oAuthApplicationInfo.getClient_id());
+ apiRegistrationProfile.setConsumerSecret(oAuthApplicationInfo.getClient_secret());
+ apiRegistrationProfile.setIsAllowedToAllDomains(false);
+ apiRegistrationProfile.setIsMappingAnExistingOAuthApp(true);
+ apiRegistrationProfile.setTags(new String[]{SenseConstants.DEVICE_TYPE});
+ String replyMsg = apiApplicationRegistrationService.register(apiRegistrationProfile);
+
+ //DeviceRegister
+ AndroidSenseManagerService androidSenseManagerService = Feign.builder().client(disableHostnameVerification)
+ .requestInterceptor(new OAuthRequestInterceptor(accessTokenInfo.getAccess_token()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(AndroidSenseManagerService.class, "https://192.168.56.1:8243" + SenseConstants.REGISTER_CONTEXT);
+ boolean registered = androidSenseManagerService.register(deviceId, DEVICE_NAME);
+ if (registered) {
+ LocalRegistry.addAccessToken(context, accessTokenInfo.getAccess_token());
+ LocalRegistry.addRefreshToken(context, accessTokenInfo.getRefresh_token());
+ }
+ return responseMap;
+ } catch (FeignException e) {
+ responseMap.put(STATUS, "" + e.status());
+ return responseMap;
+ }
+ }
+
+ private SSLSocketFactory getTrustedSSLSocketFactory() {
+ try {
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ return sc.getSocketFactory();
+ } catch (KeyManagementException | NoSuchAlgorithmException e) {
+ Log.e(SenseClientAsyncExecutor.class.getName(), "Invalid Certificate");
+ return null;
+ }
+
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java
new file mode 100644
index 000000000..463cf8ab9
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorData;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryData;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * This holds the sensor,battery and location data inmemory.
+ */
+public class SenseDataHolder {
+
+ private static List sensorDataHolder;
+ private static List batteryDataHolder;
+ private static List locationDataHolder;
+ private static List wordDataHolder;
+
+ public static List getSensorDataHolder(){
+ if(sensorDataHolder == null){
+ sensorDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return sensorDataHolder;
+ }
+
+ public static List getBatteryDataHolder(){
+ if(batteryDataHolder == null){
+ batteryDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return batteryDataHolder;
+ }
+
+ public static List getLocationDataHolder(){
+ if(locationDataHolder == null){
+ locationDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return locationDataHolder;
+ }
+
+ public static List getWordDataHolder(){
+ if(wordDataHolder == null){
+ wordDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return wordDataHolder;
+ }
+
+ public static void resetSensorDataHolder(){
+ sensorDataHolder = null;
+ }
+
+ public static void resetBatteryDataHolder(){
+ batteryDataHolder = null;
+ }
+
+ public static void resetLocationDataHolder(){
+ locationDataHolder = null;
+ }
+
+ public static void resetWordDataHolder() {
+ wordDataHolder = null;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java
new file mode 100644
index 000000000..956e780de
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import java.util.UUID;
+
+public class SenseUtils {
+
+ /**
+ * this generate the device Id
+ *
+ * @param baseContext
+ * @param contentResolver
+ * @return
+ */
+ //http://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id
+ public static String generateDeviceId(Context baseContext, ContentResolver contentResolver) {
+
+ final TelephonyManager tm = (TelephonyManager) baseContext.getSystemService(Context.TELEPHONY_SERVICE);
+
+ final String tmDevice, tmSerial, androidId;
+ tmDevice = String.valueOf(tm.getDeviceId());
+ tmSerial = String.valueOf(tm.getSimSerialNumber());
+ androidId = String.valueOf(android.provider.Settings.Secure.getString(contentResolver, android.provider.Settings.Secure.ANDROID_ID));
+
+ UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
+ return deviceUuid.toString();
+
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java
new file mode 100644
index 000000000..1a6a36bbb
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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 org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.Log;
+
+/**
+ * It doesnt let the phone goto sleep.
+ */
+public class SenseWakeLock {
+
+ private static PowerManager.WakeLock wakeLock;
+ private static String TAG = "Wake Lock";
+
+ public static void acquireWakeLock(Context context) {
+ Log.i(SenseWakeLock.class.getSimpleName(), "Acquire CPU wakeup lock start");
+ if (wakeLock == null) {
+ Log.i(TAG, "CPU wakeUp log is not null");
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SenseWakeLock");
+ }
+ wakeLock.acquire();
+ }
+
+ public static void releaseCPUWakeLock() {
+ if (wakeLock != null) {
+ wakeLock.release();
+ wakeLock = null;
+ }
+ Log.i(TAG, "Release wakeup");
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java
new file mode 100644
index 000000000..65170970b
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java
@@ -0,0 +1,40 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+public class AccessTokenInfo {
+ public String token_type;
+ public String expires_in;
+ public String refresh_token;
+ public String access_token;
+
+ public String getToken_type() {
+ return token_type;
+ }
+
+ public void setToken_type(String token_type) {
+ this.token_type = token_type;
+ }
+
+ public String getExpires_in() {
+ return expires_in;
+ }
+
+ public void setExpires_in(String expires_in) {
+ this.expires_in = expires_in;
+ }
+
+ public String getRefresh_token() {
+ return refresh_token;
+ }
+
+ public void setRefresh_token(String refresh_token) {
+ this.refresh_token = refresh_token;
+ }
+
+ public String getAccess_token() {
+ return access_token;
+ }
+
+ public void setAccess_token(String access_token) {
+ this.access_token = access_token;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java
new file mode 100644
index 000000000..0cbf26bd2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java
@@ -0,0 +1,13 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+
+public interface AndroidSenseManagerService {
+
+ @Path("devices/{device_id}")
+ @POST
+ boolean register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java
new file mode 100644
index 000000000..e8cd26148
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java
@@ -0,0 +1,25 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * This is the application registration service that exposed for apimApplicationRegistration
+ */
+
+@Path("/register")
+public interface ApiApplicationRegistrationService {
+
+ /**
+ * This method is used to register api application
+ *
+ * @param registrationProfile contains the necessary attributes that are needed in order to register an app.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ String register(ApiRegistrationProfile registrationProfile);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java
new file mode 100644
index 000000000..433ef707b
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java
@@ -0,0 +1,64 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+/**
+ * This class represents the data that are required to register
+ * the oauth application.
+ */
+public class ApiRegistrationProfile {
+
+ public String applicationName;
+ public String tags[];
+ public boolean isAllowedToAllDomains;
+ public String consumerKey;
+ public String consumerSecret;
+ public boolean isMappingAnExistingOAuthApp;
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ public String[] getTags() {
+ return tags;
+ }
+
+ public void setTags(String[] tags) {
+ this.tags = tags;
+ }
+
+ public boolean isAllowedToAllDomains() {
+ return isAllowedToAllDomains;
+ }
+
+ public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
+ this.isAllowedToAllDomains = isAllowedToAllDomains;
+ }
+
+ public boolean isMappingAnExistingOAuthApp() {
+ return isMappingAnExistingOAuthApp;
+ }
+
+ public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
+ this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
+ }
+
+ public String getConsumerKey() {
+ return consumerKey;
+ }
+
+ public void setConsumerKey(String consumerKey) {
+ this.consumerKey = consumerKey;
+ }
+
+ public String getConsumerSecret() {
+ return consumerSecret;
+ }
+
+ public void setConsumerSecret(String consumerSecret) {
+ this.consumerSecret = consumerSecret;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java
new file mode 100644
index 000000000..aa409673a
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/register")
+public interface DynamicClientRegistrationService {
+
+ /**
+ * This method is used to register an Oauth application.
+ *
+ * @param profile contains the necessary attributes that are
+ * needed in order to register an app.
+ * @return Status 200 if success including consumerKey and consumerSecret.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ OAuthApplicationInfo register(RegistrationProfile profile);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java
new file mode 100644
index 000000000..4bf5bf354
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java
@@ -0,0 +1,44 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+/**
+ * This class represents an OAuth application populated with necessary data.
+ */
+public class OAuthApplicationInfo {
+
+ public String client_id;
+ public String client_name;
+ public String callback_url;
+ public String client_secret;
+
+ public String getClient_id() {
+ return client_id;
+ }
+
+ public void setClient_id(String client_id) {
+ this.client_id = client_id;
+ }
+
+ public String getClient_name() {
+ return client_name;
+ }
+
+ public void setClient_name(String client_name) {
+ this.client_name = client_name;
+ }
+
+ public String getCallback_url() {
+ return callback_url;
+ }
+
+ public void setCallback_url(String callback_url) {
+ this.callback_url = callback_url;
+ }
+
+ public String getClient_secret() {
+ return client_secret;
+ }
+
+ public void setClient_secret(String client_secret) {
+ this.client_secret = client_secret;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java
new file mode 100644
index 000000000..32aac77c9
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java
@@ -0,0 +1,26 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+
+import static feign.Util.checkNotNull;
+
+public class OAuthRequestInterceptor implements RequestInterceptor {
+
+ private final String headerValue;
+
+ /**
+ * Creates an interceptor that authenticates all requests with the specified OAUTH token
+ *
+ * @param token the access token to use for authentication
+ */
+ public OAuthRequestInterceptor(String token) {
+ checkNotNull(token, "access_token");
+ headerValue = "Bearer " + token;
+ }
+ @Override
+ public void apply(RequestTemplate template) {
+ template.header("Authorization", headerValue);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java
new file mode 100644
index 000000000..046c112a3
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java
@@ -0,0 +1,67 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+/**
+ * This class represents the data that are required to register
+ * the oauth application.
+ */
+public class RegistrationProfile {
+
+ public String callbackUrl;
+ public String clientName;
+ public String tokenScope;
+ public String owner;
+ public String grantType;
+ public String applicationType;
+
+ private static final String TAG = RegistrationProfile.class.getSimpleName();
+
+ public String getCallbackUrl() {
+ return callbackUrl;
+ }
+
+ public void setCallbackUrl(String callBackUrl) {
+ this.callbackUrl = callBackUrl;
+ }
+
+ public String getClientName() {
+ return clientName;
+ }
+
+ public void setClientName(String clientName) {
+ this.clientName = clientName;
+ }
+
+ public String getTokenScope() {
+ return tokenScope;
+ }
+
+ public void setTokenScope(String tokenScope) {
+ this.tokenScope = tokenScope;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public String getGrantType() {
+ return grantType;
+ }
+
+ public void setGrantType(String grantType) {
+ this.grantType = grantType;
+ }
+
+ public String getApplicationType() {
+ return applicationType;
+ }
+
+ public void setApplicationType(String applicationType) {
+ this.applicationType = applicationType;
+ }
+
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java
new file mode 100644
index 000000000..570aeda7f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java
@@ -0,0 +1,16 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+@Path("/token")
+public interface TokenIssuerService {
+
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
+ @QueryParam("password") String password);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png
new file mode 100644
index 000000000..c79961029
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png
new file mode 100644
index 000000000..3dc93ed29
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png
new file mode 100644
index 000000000..a73fb4ee5
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml
new file mode 100644
index 000000000..5dcda6408
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml
new file mode 100644
index 000000000..0650eddb5
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml
new file mode 100644
index 000000000..a02e11ade
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml
new file mode 100644
index 000000000..82891d0c7
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml
new file mode 100644
index 000000000..f024bc223
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml
new file mode 100644
index 000000000..6dc91c927
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml
new file mode 100644
index 000000000..e431b902a
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml
new file mode 100644
index 000000000..e9e550487
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml
new file mode 100644
index 000000000..63208a6e0
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml
new file mode 100644
index 000000000..d07c2cfe2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml
new file mode 100644
index 000000000..861bf44cd
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml
new file mode 100644
index 000000000..c0d1d7170
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml
new file mode 100644
index 000000000..f4a7a3d8c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml
@@ -0,0 +1,7 @@
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..cde69bccc
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png
new file mode 100644
index 000000000..b4114a6c1
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..c133a0cbd
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..bfa42f0e7
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..324e72cdd
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks
new file mode 100644
index 000000000..0b3bfedf2
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer
new file mode 100644
index 000000000..8c02f03ef
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 000000000..65d0c39df
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,8 @@
+>
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 000000000..63fc81644
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml
new file mode 100644
index 000000000..e7f032534
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml
@@ -0,0 +1,4 @@
+
+
+ false
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml
new file mode 100644
index 000000000..2626ab6a6
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 16dp
+ 160dp
+ 16dp
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..a335b9272
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml
@@ -0,0 +1,14 @@
+
+ WSO2-SenseAgent
+ Sense Settings
+ Server URL https://host:9443
+ Speakup to capture the words
+ DeEnroll
+ ActivitySelectSensor
+
+ Open navigation drawer
+ Close navigation drawer
+
+
+ Hello blank fragment
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml
new file mode 100644
index 000000000..f45b28c7f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml
@@ -0,0 +1,13 @@
+
+
+
+ Username
+ Password
+ Register Device
+ Sign in
+ sessionId
+ This email address is invalid
+ This password is too short
+ This password is incorrect
+ This field is required
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml
new file mode 100644
index 000000000..35fee10ce
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle
new file mode 100644
index 000000000..952246faf
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle
@@ -0,0 +1,21 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/' }
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.3.0'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/' }
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..5a1377c93
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Dec 11 10:25:01 IST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew
new file mode 100755
index 000000000..91a7e269e
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat
new file mode 100644
index 000000000..8a0b282aa
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml
new file mode 100644
index 000000000..7476a92b0
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+ 4.0.0
+ org.wso2.iot.agents
+ org.wso2.carbon.device.mgt.iot.androidsense.agent
+ 1.0.0
+ Android Sense
+ Android Sense
+ pom
+
+
+
+ exec-maven-plugin
+ org.codehaus.mojo
+
+
+ Gradle Build
+ generate-sources
+
+ exec
+
+
+ ./gradlew
+
+ assembleRelease
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle
new file mode 100644
index 000000000..e7b4def49
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
index 427f113ba..4d63e66b0 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
@@ -38,167 +38,13 @@ import javax.ws.rs.core.Response;
@API(name = "android_sense", version = "1.0.0", context = "/android_sense", tags = {"android_sense"})
public interface AndroidSenseControllerService {
- /**
- * Service to push all the sensor data collected by the Android. Called by the Android device
- *
- * @param dataMsg The json string containing sensor readings
- */
- @Path("device/sensors")
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- Response addSensorData(DeviceData dataMsg);
-
- /**
- * End point which is called by Front-end js to get Light sensor readings from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/light")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "light", name = "Light", description = "Read Light data from the device", type = "monitor")
- Response getLightData(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Battery data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/battery")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "battery", name = "Battery", description = "Read Battery data from the device", type = "monitor")
- Response getBattery(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get GPS data from the server.
- *
- * @param deviceId The registered device id call to this API.
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gps")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gps", name = "gps", description = "Read GPS data from the device", type = "monitor")
- Response getGPS(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Magnetic data readings from the server.
- *
- * @param deviceId The registered device id
- * call to this API.
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/magnetic")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "magnetic", name = "Magnetic", description = "Read Magnetic data from the device", type = "monitor")
- Response readMagnetic(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Accelerometer data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/accelerometer")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "accelerometer", name = "Accelerometer", description = "Read Accelerometer data from the device",
- type = "monitor")
- Response readAccelerometer(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Rotation data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/rotation")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "rotation", name = "Rotation", description = "Read Rotational Vector data from the device",
- type = "monitor")
- Response readRotation(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Proximity data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/proximity")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "proximity", name = "Proximity", description = "Read Proximity data from the device",
- type = "monitor")
- Response readProximity(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Gyroscope data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gyroscope")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gyroscope", name = "Gyroscope", description = "Read Gyroscope data from the device",
- type = "monitor")
- Response readGyroscope(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Pressure data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/pressure")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "pressure", name = "Pressure", description = "Read Pressure data from the device", type = "monitor")
- Response readPressure(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Gravity data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gravity")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gravity", name = "Gravity",
- description = "Read Gravity data from the device", type = "monitor")
- Response readGravity(@PathParam("deviceId") String deviceId);
-
- @Path("device/{deviceId}/sensors/words")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "words", name = "Words", description = "Get the key words and occurrences",
- type = "monitor")
- Response getWords(@PathParam("deviceId") String deviceId, @QueryParam("sessionId") String sessionId);
-
/**
* End point to send the key words to the device
*
* @param deviceId The registered device Id.
* @param keywords The key words to be sent. (Comma separated values)
*/
- @Path("device/{deviceId}/sensors/words")
+ @Path("device/{deviceId}/words")
@POST
@Feature(code = "keywords", name = "Add Keywords", description = "Send keywords to the device",
type = "operation")
@@ -210,13 +56,13 @@ public interface AndroidSenseControllerService {
* @param deviceId The registered device Id.
* @param threshold The key words to be sent. (Comma separated values)
*/
- @Path("device/{deviceId}/sensors/words/threshold")
+ @Path("device/{deviceId}/words/threshold")
@POST
@Feature(code = "threshold", name = "Add a Threshold", description = "Set a threshold for word in the device",
type = "operation")
Response sendThreshold(@PathParam("deviceId") String deviceId, @FormParam("threshold") String threshold);
- @Path("device/{deviceId}/sensors/words")
+ @Path("device/{deviceId}/words")
@DELETE
@Feature(code = "remove", name = "Remove Keywords", description = "Remove the keywords",
type = "operation")
@@ -225,7 +71,8 @@ public interface AndroidSenseControllerService {
/**
* Retrieve Sensor data for the device type
*/
- @Path("stats/device/{deviceId}/sensors/{sensorName}")
+
+ @Path("stats/{deviceId}/sensors/{sensorName}")
@GET
@Consumes("application/json")
@Produces("application/json")
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
index 9849aa8a7..70463543e 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
@@ -50,273 +50,6 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
private static Log log = LogFactory.getLog(AndroidSenseControllerServiceImpl.class);
private static AndroidSenseMQTTConnector androidSenseMQTTConnector;
- /**
- * Fetches the `AndroidSenseMQTTConnector` specific to this Android Sense controller service.
- *
- * @return the 'AndroidSenseMQTTConnector' instance bound to the 'AndroidSenseMQTTConnector' variable of
- * this service.
- */
- @SuppressWarnings("Unused")
- public AndroidSenseMQTTConnector getAndroidSenseMQTTConnector() {
- return androidSenseMQTTConnector;
- }
-
- /**
- * Sets the `AndroidSenseMQTTConnector` variable of this Android Sense controller service.
- *
- * @param androidSenseMQTTConnector a 'AndroidSenseMQTTConnector' object that handles all MQTT related
- * communications of any connected Android Sense device-type
- */
- @SuppressWarnings("Unused")
- public void setAndroidSenseMQTTConnector(final AndroidSenseMQTTConnector androidSenseMQTTConnector) {
- Runnable connector = new Runnable() {
- public void run() {
- if (waitForServerStartup()) {
- return;
- }
- //The delay is added till the server starts up.
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- AndroidSenseControllerServiceImpl.androidSenseMQTTConnector = androidSenseMQTTConnector;
- if (MqttConfig.getInstance().isEnabled()) {
- synchronized (androidSenseMQTTConnector) {
- androidSenseMQTTConnector.connect();
- }
- } else {
- log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
- }
- }
- };
- Thread connectorThread = new Thread(connector);
- connectorThread.setDaemon(true);
- connectorThread.start();
- }
-
- private boolean waitForServerStartup() {
- while (!IoTServerStartupListener.isServerReady()) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- return true;
- }
- }
- return false;
- }
-
- public Response addSensorData(DeviceData dataMsg) {
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx
- .getOSGiService(EventsPublisherService.class, null);
- SensorData[] sensorData = dataMsg.values;
- String streamDef = null;
- Object payloadData[] = null;
- String sensorName = null;
- for (SensorData sensor : sensorData) {
- switch (sensor.key) {
- case "battery":
- streamDef = AndroidSenseConstants.BATTERY_STREAM_DEFINITION;
- payloadData = new Float[]{Float.parseFloat(sensor.value)};
- sensorName = AndroidSenseConstants.SENSOR_BATTERY;
- break;
- case "GPS":
- streamDef = AndroidSenseConstants.GPS_STREAM_DEFINITION;
- String gpsValue = sensor.value;
- String gpsValuesString[] = gpsValue.split(",");
- Float gpsValues[] = new Float[2];
- gpsValues[0] = Float.parseFloat(gpsValuesString[0]);
- gpsValues[1] = Float.parseFloat(gpsValuesString[0]);
- payloadData = gpsValues;
- sensorName = AndroidSenseConstants.SENSOR_GPS;
- break;
- default:
- try {
- int androidSensorId = Integer.parseInt(sensor.key);
- String value = sensor.value;
- String sensorValueString[] = value.split(",");
- Float sensorValues[] = new Float[1];
- switch (androidSensorId) {
- case 1:
- streamDef = AndroidSenseConstants.ACCELEROMETER_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ACCELEROMETER;
- break;
- case 2:
- streamDef = AndroidSenseConstants.MAGNETIC_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_MAGNETIC;
- break;
- case 4:
- streamDef = AndroidSenseConstants.GYROSCOPE_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GYROSCOPE;
- break;
- case 5:
- streamDef = AndroidSenseConstants.LIGHT_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_LIGHT;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 6:
- streamDef = AndroidSenseConstants.PRESSURE_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PRESSURE;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 8:
- streamDef = AndroidSenseConstants.PROXIMITY_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PROXIMITY;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 9:
- streamDef = AndroidSenseConstants.GRAVITY_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GRAVITY;
- break;
- case 11:
- streamDef = AndroidSenseConstants.ROTATION_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ROTATION;
- break;
- }
- } catch (NumberFormatException e) {
- log.error("Invalid sensor value is sent from the device");
- continue;
- }
- }
- Object metaData[] = {dataMsg.owner, AndroidSenseConstants.DEVICE_TYPE, dataMsg.deviceId, sensor.time};
- if (streamDef != null && payloadData != null && payloadData.length > 0) {
- try {
- SensorDataManager.getInstance()
- .setSensorRecord(dataMsg.deviceId, sensorName, sensor.value, sensor.time);
- deviceAnalyticsService.publishEvent(streamDef, "1.0.0", metaData, new Object[0], payloadData);
- } catch (DataPublisherConfigurationException e) {
- return Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode()).build();
- }
- }
- }
- return Response.ok().build();
- }
-
- public Response getLightData(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_LIGHT);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getBattery(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_BATTERY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getGPS(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_GPS);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readMagnetic(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_MAGNETIC);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readAccelerometer(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_ACCELEROMETER);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readRotation(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_ROTATION);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readProximity(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_PROXIMITY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readGyroscope(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_GYROSCOPE);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readPressure(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_PRESSURE);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readGravity(String deviceId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_GRAVITY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getWords(String deviceId, String sessionId) {
- try {
- org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_WORDCOUNT);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
public Response sendKeyWords(String deviceId, String keywords) {
try {
@@ -420,4 +153,60 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
}
return sensorEventTableName;
}
+
+ /**
+ * Fetches the `AndroidSenseMQTTConnector` specific to this Android Sense controller service.
+ *
+ * @return the 'AndroidSenseMQTTConnector' instance bound to the 'AndroidSenseMQTTConnector' variable of
+ * this service.
+ */
+ @SuppressWarnings("Unused")
+ public AndroidSenseMQTTConnector getAndroidSenseMQTTConnector() {
+ return androidSenseMQTTConnector;
+ }
+
+ /**
+ * Sets the `AndroidSenseMQTTConnector` variable of this Android Sense controller service.
+ *
+ * @param androidSenseMQTTConnector a 'AndroidSenseMQTTConnector' object that handles all MQTT related
+ * communications of any connected Android Sense device-type
+ */
+ @SuppressWarnings("Unused")
+ public void setAndroidSenseMQTTConnector(final AndroidSenseMQTTConnector androidSenseMQTTConnector) {
+ Runnable connector = new Runnable() {
+ public void run() {
+ if (waitForServerStartup()) {
+ return;
+ }
+ //The delay is added till the server starts up.
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ AndroidSenseControllerServiceImpl.androidSenseMQTTConnector = androidSenseMQTTConnector;
+ if (MqttConfig.getInstance().isEnabled()) {
+ synchronized (androidSenseMQTTConnector) {
+ androidSenseMQTTConnector.connect();
+ }
+ } else {
+ log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
+ }
+ }
+ };
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ private boolean waitForServerStartup() {
+ while (!IoTServerStartupListener.isServerReady()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
index 770930ec5..abc865a39 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
@@ -35,7 +35,7 @@ import javax.ws.rs.core.Response;
@API(name = "android_sense_mgt", version = "1.0.0", context = "/android_sense_mgt", tags = {"android_sense"})
public interface AndroidSenseManagerService {
- @Path("device/{device_id}")
+ @Path("devices/{device_id}")
@POST
Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
@@ -53,10 +53,10 @@ public interface AndroidSenseManagerService {
@Produces("application/json")
Response getDevice(@PathParam("device_id") String deviceId);
- @Path("devices/{sketch_type}/download")
+ @Path("devices/download")
@GET
@Produces("application/octet-stream")
- Response downloadSketch(@PathParam("sketch_type") String sketchType);
+ Response downloadSketch();
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
index 531bc5deb..aad1ffbca 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
@@ -27,6 +27,11 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.utils.CarbonUtils;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.File;
import java.util.Date;
@@ -35,7 +40,9 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
private static Log log = LogFactory.getLog(AndroidSenseManagerServiceImpl.class);
- public Response register(String deviceId, String deviceName) {
+ @Path("devices/{device_id}")
+ @POST
+ public Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidSenseConstants.DEVICE_TYPE);
@@ -56,12 +63,12 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
device.setEnrolmentInfo(enrolmentInfo);
boolean added = APIUtil.getDeviceManagementService().enrollDevice(device);
if (added) {
- return Response.ok().build();
+ return Response.ok(true).build();
} else {
- return Response.status(Response.Status.NOT_ACCEPTABLE.getStatusCode()).build();
+ return Response.status(Response.Status.NOT_ACCEPTABLE.getStatusCode()).entity(false).build();
}
} catch (DeviceManagementException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(false).build();
}
}
@@ -114,7 +121,7 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
}
}
- public Response downloadSketch(String sketchType) {
+ public Response downloadSketch() {
try {
String sep = File.separator;
String sketchFolder = "repository" + sep + "resources" + sep + "sketches" + sep + "android_sense" + sep;
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
index 701e0e21c..bac5bea8d 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
@@ -18,8 +18,6 @@
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.transport;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
@@ -28,25 +26,15 @@ import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
-import org.wso2.carbon.device.mgt.common.Device;
-import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
-import org.wso2.carbon.device.mgt.common.DeviceManagementException;
-import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
-import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.DeviceData;
-import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorData;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
-import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@@ -84,7 +72,7 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + AndroidSenseConstants.DEVICE_TYPE + " device_mqtt_connector";
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
- apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
+ apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
//create token
String accessToken = accessTokenInfo.getAccessToken();
setUsernameAndPassword(accessToken, EMPTY_STRING);
@@ -99,10 +87,13 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
}
}catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
+ return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
+ return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
+ return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
@@ -161,189 +152,7 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
@Override
public void processIncomingMessage(MqttMessage mqttMessage, String... strings) throws TransportHandlerException {
- String[] topic = strings[0].split("/");
- String deviceId = topic[3];
- if (log.isDebugEnabled()) {
- log.debug("Received MQTT message for: & [DEVICE.ID-" + deviceId + "]");
- }
- try {
- Gson gson = new Gson();
- String actualMessage = mqttMessage.toString();
- DeviceData deviceData = gson.fromJson(actualMessage, DeviceData.class);
-
- SensorData[] sensorData = deviceData.values;
- String streamDef = null;
- Object payloadData[] = null;
- String sensorName = null;
- PrivilegedCarbonContext.startTenantFlow();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceManagementProviderService deviceManagementProviderService =
- (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null);
- if (deviceManagementProviderService != null) {
- DeviceIdentifier identifier = new DeviceIdentifier(deviceId, AndroidSenseConstants.DEVICE_TYPE);
- Device device = deviceManagementProviderService.getDevice(identifier);
- if (device != null) {
- String owner = device.getEnrolmentInfo().getOwner();
- ctx.setUsername(owner);
- ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
- } else {
- return;
- }
-
- } else {
- return;
- }
- ctx.setTenantDomain("carbon.super", true);
- for (SensorData sensor : sensorData) {
- if (sensor.key.equals("battery")) {
- streamDef = AndroidSenseConstants.BATTERY_STREAM_DEFINITION;
- payloadData = new Float[]{Float.parseFloat(sensor.value)};
- sensorName = AndroidSenseConstants.SENSOR_BATTERY;
- } else if (sensor.key.equals("GPS")) {
- streamDef = AndroidSenseConstants.GPS_STREAM_DEFINITION;
- String gpsValue = sensor.value;
- String gpsValuesString[] = gpsValue.split(",");
- Float gpsValues[] = new Float[2];
- gpsValues[0] = Float.parseFloat(gpsValuesString[0]);
- gpsValues[1] = Float.parseFloat(gpsValuesString[0]);
- payloadData = gpsValues;
- sensorName = AndroidSenseConstants.SENSOR_GPS;
- } else if (sensor.key.equals("word")) {
- try {
- streamDef = AndroidSenseConstants.WORD_COUNT_STREAM_DEFINITION;
- String[] values = sensor.value.split(",");
- String sessionId = values[0];
- String keyword = values[1];
- int occurrence = Integer.parseInt(values[2]);
- String status = values[3];
- sensorName = AndroidSenseConstants.SENSOR_WORDCOUNT;
- if (occurrence > 0) {
- payloadData = new Object[]{sessionId, keyword, status};
- for (int i = 0; i < occurrence; i++) {
- Long timestamp = Long.parseLong(values[3 + occurrence]);
- publishDataToDAS(deviceId, timestamp, sensorName, streamDef,
- sensor.value, payloadData);
-
- }
- continue;
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- log.error(
- "Timestamp does not match the occurence sensor values are sent from the device.");
- }
- continue;
- } else {
- try {
- int androidSensorId = Integer.parseInt(sensor.key);
- String sensorValue = sensor.value;
- String sensorValuesString[] = sensorValue.split(",");
- Float sensorValues[] = new Float[1];
-
- switch (androidSensorId) {
- case 1:
- streamDef = AndroidSenseConstants.ACCELEROMETER_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ACCELEROMETER;
- break;
- case 2:
- streamDef = AndroidSenseConstants.MAGNETIC_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_MAGNETIC;
- break;
- case 4:
- streamDef = AndroidSenseConstants.GYROSCOPE_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GYROSCOPE;
- break;
- case 5:
- streamDef = AndroidSenseConstants.LIGHT_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_LIGHT;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 6:
- streamDef = AndroidSenseConstants.PRESSURE_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PRESSURE;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 8:
- streamDef = AndroidSenseConstants.PROXIMITY_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PROXIMITY;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 9:
- streamDef = AndroidSenseConstants.GRAVITY_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GRAVITY;
- break;
- case 11:
- streamDef = AndroidSenseConstants.ROTATION_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ROTATION;
- break;
- }
- } catch (NumberFormatException e) {
- log.error("Invalid sensor values are sent from the device.");
- continue;
- }
- }
- publishDataToDAS(deviceId, sensor.time, sensorName, streamDef, sensor.value, payloadData);
- }
- } catch (JsonSyntaxException e) {
- throw new TransportHandlerException("Invalid message format " + mqttMessage.toString());
- } catch (DeviceManagementException e) {
- throw new TransportHandlerException("Invalid device id " + deviceId);
- } finally {
- PrivilegedCarbonContext.endTenantFlow();
- }
- }
-
- private void publishDataToDAS(String deviceId, Long time, String sensorName,
- String streamDefinition, String sensorValue, Object payloadData[]) {
- try {
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceManagementProviderService deviceManagementProviderService = (DeviceManagementProviderService) ctx
- .getOSGiService(DeviceManagementProviderService.class, null);
- if (deviceManagementProviderService != null) {
- DeviceIdentifier identifier = new DeviceIdentifier(deviceId, AndroidSenseConstants.DEVICE_TYPE);
- Device device = deviceManagementProviderService.getDevice(identifier);
- if (device != null) {
- String owner = device.getEnrolmentInfo().getOwner();
- ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
- EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx
- .getOSGiService(EventsPublisherService.class, null);
- if (deviceAnalyticsService != null) {
- Object metaData[] = {owner, AndroidSenseConstants.DEVICE_TYPE, deviceId, time};
- if (streamDefinition != null && payloadData != null && payloadData.length > 0) {
- try {
- SensorDataManager.getInstance().setSensorRecord(deviceId, sensorName, sensorValue, time);
- deviceAnalyticsService.publishEvent(streamDefinition, "1.0.0", metaData,
- new Object[0], payloadData);
- } catch (DataPublisherConfigurationException e) {
- log.error("Data publisher configuration failed - " + e);
- }
- }
- }
- }
- }
- } catch (DeviceManagementException e) {
- log.error("Failed to load device management service.", e);
- }
}
/**
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
index 780d13f66..7ea6c31b1 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
@@ -28,152 +28,67 @@
-
-
- add sensor information
- /device-mgt/user/device/sensors
- /device/sensors
- POST
- android_sense_device
-
-
- Get light information
- /device-mgt/user/device/sensors/light
- /device/*/sensors/light
- GET
- android_sense_user
-
-
- Get battery information
- /device-mgt/user/device/sensors/battery
- /device/*/sensors/battery
- GET
- android_sense_user
-
- Get gps information
- /device-mgt/user/device/sensors/gps
- /device/*/sensors/gps
- GET
- android_sense_user
-
-
- Get magnetic information
- /device-mgt/user/device/sensors/magnetic
- /device/*/sensors/magnetic
- GET
- android_sense_user
-
-
- Get accelerometer information
- /device-mgt/user/device/accelerometer
- /device/*/sensors/accelerometer
- GET
- android_sense_user
-
-
- Get rotation information
- /device-mgt/user/device/sensors/rotation
- /device/*/sensors/rotation
- GET
- android_sense_user
-
-
- Get proximity information
- /device-mgt/user/device/sensors/proximity
- /device/*/sensors/proximity
- GET
- android_sense_user
-
-
- Get gyroscope information
- /device-mgt/user/device/gyroscope
- /device/*/sensors/gyroscope
- GET
- android_sense_user
-
-
- Get pressure information
- /device-mgt/user/device/sensors/pressure
- /device/*/sensors/pressure
- GET
- android_sense_user
-
-
- Get gravity information
- /device-mgt/user/device/sensors/gravity
- /device/*/sensors/gravity
- GET
- android_sense_user
-
-
- Get words information
- /device-mgt/user/device/sensors/words
- /device/*/sensors/words
- GET
- android_sense_user
-
-
- Get words information
- /device-mgt/user/device/sensors/word
- /device/*/sensors/words
+ Set words
+ /device-mgt/android_sense/word/add
+ /device/*/words
POST
android_sense_user
set word threshold information
- /device-mgt/user/device/sensors/words/threshold
- /device/*/sensors/words/threshold
+ /device-mgt/android_sense/threshold
+ /device/*/words/threshold
POST
android_sense_user
delete words
- /device-mgt/user/device/sensors/words
- /device/*/sensors/words
+ /device-mgt/android_sense/word/delete
+ /device/*/words
DELETE
android_sense_user
get device stats
- /device-mgt/user/device/stats
- /stats/device/*/sensors/*
+ /device-mgt/android_sense/device/stats
+ /stats/*/sensors/*
GET
android_sense_device
Get device
- /device-mgt/user/devices/list
+ /device-mgt/android_sense/user/devices/list
/devices/*
GET
android_sense_user
Add device
- /device-mgt/user/devices/add
- /devices/register
+ /device-mgt/android_sense/user/devices/add
+ /devices/*
POST
android_sense_user
Remove device
- /device-mgt/user/devices/remove
+ /device-mgt/android_sense/user/devices/remove
/devices/*
DELETE
android_sense_user
Download device
- /device-mgt/user/devices/add
- /devices/*/download
+ /device-mgt/android_sense/user/devices/add
+ /devices/download
GET
android_sense_user
Update device
- /device-mgt/user/devices/update
+ /device-mgt/android_sense/user/devices/update
/devices/*
- POST
+ PUT
android_sense_user
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
index 138f002d0..f3c570f1e 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
@@ -22,7 +22,7 @@
doAuthentication
- false
+ true
isSharedWithAllTenants
@@ -43,15 +43,7 @@
admin
- managed-api-context-template
- /android_sense/{version}
-
-
- managed-api-application
- android_sense
-
-
- managed-api-isSecured
- true
+ managed-api-endpoint-context
+ /android_sense
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SubscriptionEndpoint.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SubscriptionEndpoint.java
index d6e0e4909..9439b422c 100644
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SubscriptionEndpoint.java
+++ b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SubscriptionEndpoint.java
@@ -18,10 +18,9 @@
*
*/
-import oauth.OAuthTokenValdiator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.wso2.carbon.servlet.ServiceHolder;
+import util.ServiceHolder;
import javax.websocket.CloseReason;
import javax.websocket.Session;
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java
index f6c27536f..546473cd3 100644
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java
+++ b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/SuperTenantSubscriptionEndpoint.java
@@ -20,7 +20,7 @@ import oauth.OAuthTokenValdiator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.servlet.ServiceHolder;
+import util.ServiceHolder;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import util.AuthenticationInfo;
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java
index d0ff600b6..837e75f00 100644
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java
+++ b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/TenantSubscriptionEndpoint.java
@@ -20,7 +20,7 @@ import oauth.OAuthTokenValdiator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.servlet.ServiceHolder;
+import util.ServiceHolder;
import util.AuthenticationInfo;
import javax.websocket.CloseReason;
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/SuperTenantEventRetrievalEndpoint.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/SuperTenantEventRetrievalEndpoint.java
deleted file mode 100644
index 41a0d8b33..000000000
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/SuperTenantEventRetrievalEndpoint.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.wso2.carbon.servlet;/*
- *
- * Copyright (c) 2014-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
- *
- * WSO2 Inc. licenses this file to you 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.
- *
- */
-
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
-import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
-import util.UIConstants;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-/**
- * Getting events for HTTP request for super tenant
- */
-
-@Path("/")
-public class SuperTenantEventRetrievalEndpoint{
-
- public SuperTenantEventRetrievalEndpoint() {
- }
-
- /**
- * Retrieve events when polling
- *
- * @param streamName - StreamName extracted from the http url.
- * @param version - Version extracted from the http url.
- * @param lastUpdatedTime - Last event's dispatched name.
- * @return respnse
- */
- @GET
- @Path("/{streamname}/{version}")
- public Response retrieveEvents(@PathParam("streamname") String streamName, @PathParam("version") String version,
- @QueryParam("lastUpdatedTime") String lastUpdatedTime) {
- String streamId;
- JsonObject eventDetails;
- String jsonString;
-
- try {
- PrivilegedCarbonContext.startTenantFlow();
- PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
- streamId = streamName + UIConstants.ADAPTER_UI_COLON + version;
-
- eventDetails = ServiceHolder.getInstance().getUiOutputCallbackControllerService().retrieveEvents(streamName, version,
- lastUpdatedTime);
-
- } finally {
- PrivilegedCarbonContext.getThreadLocalCarbonContext().endTenantFlow();
- }
-
- if(eventDetails == null){
- JsonObject errorData = new JsonObject();
- errorData.addProperty("error","StreamId: " + streamId + " is not registered to receive events.");
- jsonString = new Gson().toJson(errorData);
- return Response.status(Response.Status.NOT_FOUND).entity(jsonString).header
- ("Access-Control-Allow-Origin","*").build();
- } else{
- jsonString = new Gson().toJson(eventDetails);
- return Response.ok(jsonString, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin",
- "*").build();
- }
- }
-
-}
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/TenantEventRetrievalEndpoint.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/TenantEventRetrievalEndpoint.java
deleted file mode 100644
index ec14e5722..000000000
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/TenantEventRetrievalEndpoint.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.wso2.carbon.servlet;
-/*
- *
- * Copyright (c) 2014-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
- *
- * WSO2 Inc. licenses this file to you 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.
- *
- */
-
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.wso2.carbon.context.PrivilegedCarbonContext;
-import util.UIConstants;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-/**
- * Getting events for HTTP request from a tenant
- */
-
-@Path("/t/{tdomain}/")
-public class TenantEventRetrievalEndpoint {
-
- private static final Log log = LogFactory.getLog(SuperTenantEventRetrievalEndpoint.class);
-
- public TenantEventRetrievalEndpoint() {
-
- }
-
- /**
- * Retrieve events when polling
- *
- * @param streamName - StreamName extracted from the http url.
- * @param version - Version extracted from the http url.
- * @param lastUpdatedTime - Last event's dispatched name.
- * @param tdomain - Tenant domain extracted from http url
- * @return response
- */
- @GET
- @Path("/{streamname}/{version}")
- public Response retrieveEvents(@PathParam("streamname") String streamName, @PathParam("version") String version,
- @QueryParam("lastUpdatedTime") String lastUpdatedTime,
- @PathParam("tdomain") String tdomain) {
-
- String streamId;
- JsonObject eventDetails;
- try {
- PrivilegedCarbonContext.startTenantFlow();
- PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true);
- streamId = streamName + UIConstants.ADAPTER_UI_COLON + version;
- eventDetails = ServiceHolder.getInstance().getUiOutputCallbackControllerService().retrieveEvents
- (streamName, version, lastUpdatedTime);
- } finally {
- PrivilegedCarbonContext.endTenantFlow();
- }
-
- String jsonString;
- if (eventDetails == null) {
- JsonObject errorData = new JsonObject();
- errorData.addProperty("error", "StreamId: " + streamId + " is not registered to receive events.");
- jsonString = new Gson().toJson(errorData);
- return Response.status(Response.Status.NOT_FOUND).entity(jsonString).header
- ("Access-Control-Allow-Origin", "*").build();
- } else {
- jsonString = new Gson().toJson(eventDetails);
- return Response.ok(jsonString, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin",
- "*").build();
- }
- }
-}
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/ServiceHolder.java b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/util/ServiceHolder.java
similarity index 82%
rename from components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/ServiceHolder.java
rename to components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/util/ServiceHolder.java
index 08d07a44c..249d5cb75 100644
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/org/wso2/carbon/servlet/ServiceHolder.java
+++ b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/java/util/ServiceHolder.java
@@ -1,4 +1,4 @@
-package org.wso2.carbon.servlet;
+package util;
import org.wso2.carbon.context.PrivilegedCarbonContext;
@@ -11,8 +11,7 @@ public class ServiceHolder {
private ServiceHolder(){
uiOutputCallbackControllerService = (UIOutputCallbackControllerService) PrivilegedCarbonContext
- .getThreadLocalCarbonContext()
- .getOSGiService(UIOutputCallbackControllerService.class,null);
+ .getThreadLocalCarbonContext().getOSGiService(UIOutputCallbackControllerService.class, null);
}
public synchronized static ServiceHolder getInstance(){
diff --git a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/webapp/WEB-INF/web.xml b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/webapp/WEB-INF/web.xml
index 4c01cc52c..2ec7fc7e9 100644
--- a/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/webapp/WEB-INF/web.xml
+++ b/components/iot-plugins/das-extensions/org.wso2.carbon.event.output.adapter.extensions.ui.endpoint/src/main/webapp/WEB-INF/web.xml
@@ -21,21 +21,4 @@
Output WebSocket
-
- JAXServlet
-
- org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
-
-
- jaxrs.serviceClasses
- org.wso2.carbon.servlet.TenantEventRetrievalEndpoint org.wso2.carbon.servlet.SuperTenantEventRetrievalEndpoint
-
- 1
-
-
-
-
- JAXServlet
- /*
-
diff --git a/components/iot-plugins/das-extensions/pom.xml b/components/iot-plugins/das-extensions/pom.xml
index 7c1f0be17..d72d656c4 100644
--- a/components/iot-plugins/das-extensions/pom.xml
+++ b/components/iot-plugins/das-extensions/pom.xml
@@ -29,7 +29,7 @@
4.0.0
das-extensions
pom
- This contains das extension
+ WSO2 Carbon - DAS Extension
http://wso2.org
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
index 2950a66dd..49b9111f1 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
@@ -81,10 +81,13 @@ public class DigitalDisplayMQTTConnector extends MQTTTransportHandler {
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
+ return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
+ return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
+ return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
index a413bbf9c..901374a99 100644
--- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
@@ -252,19 +252,24 @@ public abstract class MQTTTransportHandler implements MqttCallback, TransportHan
* @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
*/
protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException {
+ if (!isConnected()) {
+ connectToQueue();
+ }
try {
client.publish(topic, message);
if (log.isDebugEnabled()) {
- log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
+ log.debug(
+ "Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
}
} catch (MqttException ex) {
String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
- "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
+
/**
* This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via
* publishing to this broker that the messages are communicated to the device. This is an overloaded method with
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
index 30c9fb2bf..d5bf225be 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
@@ -94,10 +94,13 @@ public class RaspberryPiMQTTConnector extends MQTTTransportHandler {
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
+ return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
+ return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
+ return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
index 0d7efef2b..6cbd9af81 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
@@ -123,10 +123,13 @@ public class VirtualFireAlarmMQTTConnector extends MQTTTransportHandler {
}
} catch (JWTClientException e) {
log.error("Failed to retrieve token from JWT Client.", e);
+ return;
} catch (UserStoreException e) {
log.error("Failed to retrieve the user.", e);
+ return;
} catch (APIManagerException e) {
log.error("Failed to create an application and generate keys.", e);
+ return;
} finally {
PrivilegedCarbonContext.endTenantFlow();
}