Java tutorial
/* * Copyright (C) 2014 TU Darmstadt, Hessen, Germany. * Department of Computer Science Databases and Distributed Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.tudarmstadt.dvs.myhealthassistant.myhealthhub.services.messagehandler; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.os.IBinder; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.commontools.EventUtils; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.AbstractChannel; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.Event; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.localmanagement.EventTransformationRequest; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.localmanagement.EventTransformationResponse; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.Advertisement; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.Announcement; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.JSONDataExchange; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.ManagementEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.StartProducer; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.StopProducer; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.Subscription; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.Unadvertisement; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.management.Unsubscription; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.notifications.NotificationEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.events.sensorreadings.SensorReadingEvent; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.services.transformationmanager.database.LocalTransformationDB; import de.tudarmstadt.dvs.myhealthassistant.myhealthhub.services.transformationmanager.database.LocalTransformationDBMS; public class MessageHandler extends Service { /** For Debugging */ private static final String TAG = "MessageHandler"; private static boolean D = false; private static final String TAG_ANNOUNCEMENT = "Announcement MessageHandler"; private static boolean D_ANNOUNCEMENT = false; private static final String TAG_ROUTING = "MessageHandler Routing"; private static boolean D_ROUTING = true; DBAdapterSubscriptions db; // = new DBAdapterSubscriptions(this); private HashMap<String, List<String>> subscriberChannelHashMap; private HashMap<String, List<ProducerDetails>> advertisementHashMap; private HashMap<String, Integer> sensorConnectivityAnnouncement; private EventUtils evtUtils; private final IntentFilter sensorReadingsChannel = new IntentFilter(AbstractChannel.RECEIVER); private EventReceiver mEventReceiver; private ManagementReceiver mManagementReceiver; private final IntentFilter managementReceiverChannel = new IntentFilter(AbstractChannel.MANAGEMENT); private ResponseReceiver mResponseReceiver; private IntentFilter mResponseReceiverChannel = new IntentFilter(AbstractChannel.LOCAL_MANAGEMENT); private final IntentFilter notificationChannel = new IntentFilter(AbstractChannel.NOTIFICATION); private NotificationReceiver mNotificationReceiver; private class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { final NotificationEvent evt = (NotificationEvent) intent .getParcelableExtra(Event.PARCELABLE_EXTRA_EVENT); // Create subject String tempSubject = "myHealthAssistant "; switch (evt.severity) { case NotificationEvent.SEVERITY_INFORMATION: tempSubject += "INFORMATION"; break; case NotificationEvent.SEVERITY_DEBUG: tempSubject += "DEBUG"; break; case NotificationEvent.SEVERITY_CRITICAL: tempSubject += "CRITICAL"; break; case NotificationEvent.SEVERITY_WARNING: tempSubject += "WARNING"; break; } tempSubject += ": " + evt.subject; final String subject = tempSubject; // Create body final String body = "(This is an auto-generated message from myHealthAssistant.)" + "\n\nMessage: " + evt.text + "\n\nProcuder: " + evt.getProducerID(); // Send e-mail Thread thread = new Thread() { public void run() { try { // GMailSender sender = new GMailSender( // null, // null); // sender.sendMail(subject, body, // null, // null); } catch (Exception e) { Log.e("SendMail", e.getMessage(), e); } } }; thread.start(); } } /** Event Handler */ private class EventReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Event evt = intent.getParcelableExtra(Event.PARCELABLE_EXTRA_EVENT); if (D) Log.d(TAG, "Incoming event of type " + evt.getEventType()); String eventType = intent.getStringExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE); // Discard null values for a String if (eventType == null) { Log.e(TAG, "eventType is null"); return; } // Parse event type into an event tree String[] eventTree = parseEventType(eventType); // Discard invalid events if (eventTree == null) { Log.e(TAG, "Invalid incoming event type: " + eventType); return; } // Skip if tree height is smaller than 2 if (eventTree.length < 1) { Log.e(TAG, "Event tree too small. Event is not forwarded. " + eventType); return; } List<String> tempSubscriberForEventTypeList; String eventTypeKey = Event.EVENT_ROOT; //Check for each step in the eventTree if anyone is subscribed for (int i = 0; i < eventTree.length; i++) { eventTypeKey = (eventTypeKey + "." + eventTree[i]); tempSubscriberForEventTypeList = subscriberChannelHashMap.get(eventTypeKey); if (tempSubscriberForEventTypeList != null) { //set implicit intent.setAction(eventTypeKey); //Send to all subscribers for (int j = 0; j < tempSubscriberForEventTypeList.size(); j++) { String receiverPackage = tempSubscriberForEventTypeList.get(j); /*if(receiverPackage.equals(getPackageName())) { // send locally if(D)Log.i(TAG, "Send locally to package: "+receiverPackage); LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent); //TODO intent.setPackage(tempSubscriberForEventTypeList.get(j)); getApplicationContext().sendBroadcast(intent); } else {*/ // globally if (D) Log.i(TAG, "Send globally to package: " + receiverPackage); //set explicit intent.setPackage(tempSubscriberForEventTypeList.get(j)); getApplicationContext().sendBroadcast(intent); //} } } } }; } /** Management Receiver */ private class ManagementReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent == null) return; //Log.d(TAG, "Received EventTypeShort: "+getLastStringAfterDot(intent.getStringExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE))); Event evt = intent.getParcelableExtra(Event.PARCELABLE_EXTRA_EVENT); //Checks the ManamgentEvent and notifies the sender about the invalid argument if (!isManagementEventValid(evt)) return; // JSONDataExchange if (evt.getEventType().equals(ManagementEvent.JSON_DATA_EXCHANGE)) { Log.d(TAG, "JSON Data Exchange event from: " + evt.getProducerID()); String eventProducerID = evt.getProducerID(); String eventProducersPackageName = ((JSONDataExchange) evt).getPackageName(); String dataExchangeEventType = ((JSONDataExchange) evt).getDataExchangeEventType(); // ProducerDetails producerDetails = new ProducerDetails(eventProducerID, eventProducersPackageName); String jsonDataString = ((JSONDataExchange) evt).getJSONEncodedData(); try { JSONObject jsonData = new JSONObject(jsonDataString); String json_request = jsonData.optString(JSONDataExchange.JSON_REQUEST, "null"); JSONArray jObjArray = jsonData.optJSONArray(JSONDataExchange.JSON_CONTENT_ARRAY); if (json_request.equalsIgnoreCase(JSONDataExchange.JSON_STORE) && jObjArray != null) { // save contents to db ArrayList<ContentValues> vArray = new ArrayList<ContentValues>(); for (int i = 0; i < jObjArray.length(); i++) { JSONObject jObj = jObjArray.optJSONObject(i); if (jObj != null) { String contents = jObj.toString(); String contentDate = jObj.optString(JSONDataExchange.JSON_DATE, "null"); String contentExtra = jObj.optString(JSONDataExchange.JSON_EXTRA, "null"); ContentValues value = new ContentValues(); value.put(LocalTransformationDB.COUMN_JSON_DATE, contentDate); value.put(LocalTransformationDB.COUMN_JSON_CONTENT, contents); value.put(LocalTransformationDB.COUMN_JSON_EXTRA, contentExtra); vArray.add(value); } } LocalTransformationDBMS transformationDB = new LocalTransformationDBMS(context); transformationDB.open(); transformationDB.storeJsonData(vArray); transformationDB.close(); } else if (json_request.equalsIgnoreCase(JSONDataExchange.JSON_GET)) { // send to eventProducer all data from db LocalTransformationDBMS transformationDB = new LocalTransformationDBMS(context); transformationDB.open(); JSONArray getJArray = transformationDB.getAlljsonData(); transformationDB.close(); JSONObject jEncodedData = new JSONObject(); jEncodedData.putOpt(JSONDataExchange.JSON_REQUEST, JSONDataExchange.JSON_GET); jEncodedData.putOpt(JSONDataExchange.JSON_CONTENT_ARRAY, getJArray); if (evtUtils != null) { JSONDataExchange eData = new JSONDataExchange(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, eventProducersPackageName, dataExchangeEventType, jEncodedData.toString()); sendToManagementChannel(eData, eventProducersPackageName); Log.e(TAG, "send EncodedData to " + eventProducersPackageName + "; ID:" + eventProducerID); } else { Log.e(TAG, "cant send back jsonEncodedData to " + eventProducersPackageName + "; ID:" + eventProducerID); } } else if (json_request.equalsIgnoreCase(JSONDataExchange.JSON_EDIT) && jObjArray != null) { // edit contents in db ArrayList<ContentValues> vArray = new ArrayList<ContentValues>(); int id = -1; for (int i = 0; i < jObjArray.length(); i++) { JSONObject jObj = jObjArray.optJSONObject(i); if (jObj != null) { id = jObj.optInt(JSONDataExchange.JSON_CONTENT_ID, -1); String contents = jObj.toString(); String contentDate = jObj.optString(JSONDataExchange.JSON_DATE, "null"); String contentExtra = jObj.optString(JSONDataExchange.JSON_EXTRA, "null"); ContentValues value = new ContentValues(); value.put(LocalTransformationDB.COUMN_JSON_DATE, contentDate); value.put(LocalTransformationDB.COUMN_JSON_CONTENT, contents); value.put(LocalTransformationDB.COUMN_JSON_EXTRA, contentExtra); vArray.add(value); } } LocalTransformationDBMS transformationDB = new LocalTransformationDBMS(context); transformationDB.open(); transformationDB.editJsonData(id, vArray.get(0)); // assume that only one jObj passed in transformationDB.close(); } else if (json_request.equalsIgnoreCase(JSONDataExchange.JSON_DEL) && jObjArray != null) { // delete contents in db int id = -1; for (int i = 0; i < jObjArray.length(); i++) { JSONObject jObj = jObjArray.optJSONObject(i); if (jObj != null) { id = jObj.optInt(JSONDataExchange.JSON_CONTENT_ID, -1); } } Log.e(TAG, "delet json:" + id); LocalTransformationDBMS transformationDB = new LocalTransformationDBMS(context); transformationDB.open(); transformationDB.deleteJsonData(id); transformationDB.close(); } } catch (JSONException e) { e.printStackTrace(); } } //Advertisement if (evt.getEventType().equals(ManagementEvent.ADVERTISEMENT)) { if (D) Log.d(TAG, "Advertisement event from " + evt.getProducerID()); String eventProducerID = evt.getProducerID(); String eventProducersPackageName = ((Advertisement) evt).getPackageName(); String advertisedEventType = ((Advertisement) evt).getAdvertisedEventType(); ProducerDetails producerDetails = new ProducerDetails(eventProducerID, eventProducersPackageName); //Get producers for the EventType List<ProducerDetails> tempProducerDetailsList = advertisementHashMap.get(advertisedEventType); // Check if anyone is already providing the event if (tempProducerDetailsList != null) { //Check if producer is already in list for (int i = 0; i < tempProducerDetailsList.size(); i++) { if (tempProducerDetailsList.get(i).getProducerID().equals(eventProducerID)) { if (D) Log.d(TAG, "Producer already in List: " + eventProducerID); sendAnnouncement(Announcement.ADVERTSIMENT_UNSUCESSFULL_PRODUCER_ALREADY_IN_LIST, advertisedEventType, eventProducersPackageName); return; } } tempProducerDetailsList.add(producerDetails); if (D) Log.d(TAG, "Producer added to advertisementList: " + eventProducerID); } else { // If no producer exists for EventType create a new entry List<ProducerDetails> producerList = new ArrayList<ProducerDetails>(); producerList.add(producerDetails); advertisementHashMap.put(advertisedEventType, producerList); if (D) Log.d(TAG, "New Entry in Producer HashMap: " + eventProducerID); } // Send a startEvent/StopEvent to the producer and a ManagementEvent to all subscribers List<String> subscribersListForEventType = getSubscribersListForEventType(advertisedEventType); if (subscribersListForEventType != null) { sendStartEvent(eventProducerID, advertisedEventType, eventProducersPackageName); sendAnnouncementToRecieverList(Announcement.ADVERTISMENT_NEW_EVENT_TYPE_AVAILABLE, advertisedEventType, subscribersListForEventType); } else { sendStopEvent(eventProducerID, advertisedEventType, eventProducersPackageName); } sendAnnouncement(Announcement.ADVERTISMENT_SUCCESSFULL, advertisedEventType, eventProducersPackageName); if (D_ROUTING) printAdvertisementsAndSubscriptions(); //Unadvertisement } else if (evt.getEventType().equals(ManagementEvent.UNADVERTISEMENT)) { String eventProducer = evt.getProducerID(); String packageName = ((Unadvertisement) evt).getPackageName(); String unadvertisedEventType = ((Unadvertisement) evt).getUnadvertisedEventType(); ProducerDetails producerDetails = new ProducerDetails(eventProducer, packageName); //Check if there are producers for EventType if (advertisementHashMap.containsKey(unadvertisedEventType)) { List<ProducerDetails> producerDetailsList = advertisementHashMap.get(unadvertisedEventType); for (int i = 0; i < producerDetailsList.size(); i++) { if (producerDetailsList.get(i).getProducerID().equals(producerDetails.getProducerID())) { producerDetailsList.remove(i); i--; if (D) Log.d(TAG, "Removed ProducerDetails: ProducerID: " + producerDetails.getProducerID() + " PackageNameShort " + getLastStringAfterDot(producerDetails.getProducerPackageName())); } } //If there are no more producer for the EventType remove from EventType advertismentHashMap and notify all subscribers if (producerDetailsList.isEmpty()) { advertisementHashMap.remove(unadvertisedEventType); //Notify all EventType subscribers List<String> receiverPackageNameList = getSubscribersListForEventType( unadvertisedEventType); if (receiverPackageNameList != null) { sendAnnouncementToRecieverList( Announcement.UNADVERTISMENT_EVENT_TYPE_NOT_LONGER_AVAILABLE, unadvertisedEventType, receiverPackageNameList); } } sendAnnouncement(Announcement.UNADVERTISMENT_SUCCESSFULL, unadvertisedEventType, packageName); } if (D_ROUTING) printAdvertisementsAndSubscriptions(); //Subscription } else if (evt.getEventType().equals(ManagementEvent.SUBSCRIPITON)) { if (D) Log.d(TAG, "Subscription event from " + evt.getProducerID()); String subscribersPackageName = ((Subscription) evt).getPackageName(); String subscriptionSensorReadings = ((Subscription) evt).getSubscriptionSensorReadings(); // Check if an entry for the eventType already exists if (subscriberChannelHashMap.containsKey(subscriptionSensorReadings)) { List<String> tempSubscribersListForEventType = subscriberChannelHashMap .get(subscriptionSensorReadings); if (!tempSubscribersListForEventType.contains(subscribersPackageName)) { //Check all effected producers and send a StartEvent if no one is already subscribed to it subscriptionCheckWithAllAvailableEventsThatMatch(subscriptionSensorReadings); //Important: check before adding! tempSubscribersListForEventType.add(subscribersPackageName); if (D) Log.d(TAG, "Subscriber added to Entry in subscribersHashMap: EventTypeShort: " + getLastStringAfterDot(subscriptionSensorReadings) + ", PackageNameShort: " + subscribersPackageName); } else { sendAnnouncement(Announcement.SUBSCRIPTOPN_SUBSCRIBER_ALREADY_IN_LIST, subscriptionSensorReadings, subscribersPackageName); return; } } else { // If no entry exists create a new one and send a StartEvent to the EventType producer List<String> receiverList = new ArrayList<String>(); receiverList.add(subscribersPackageName); //Check all effected producers and send a StartEvent if no one is already subscribed to it subscriptionCheckWithAllAvailableEventsThatMatch(subscriptionSensorReadings); //Important: check before adding! subscriberChannelHashMap.put(subscriptionSensorReadings, receiverList); if (D) Log.d(TAG, "Subscriber Package new Entry in subscribersHashMap: EventTypeShort: " + getLastStringAfterDot(subscriptionSensorReadings) + ", PackageNameShort: " + subscribersPackageName); } sendAnnouncement(Announcement.SUBSCRIPTION_SUCCESSFULL, subscriptionSensorReadings, subscribersPackageName); // send sensor connectivity if (sensorConnectivityAnnouncement.containsKey(subscriptionSensorReadings)) sendAnnouncement(sensorConnectivityAnnouncement.get(subscriptionSensorReadings), subscriptionSensorReadings, subscribersPackageName); //Write Subscription into databases db.openWritabelDB(); db.insertOrReplaceRecord(evt.getEventType(), evt.getID(), evt.getTimestamp() /*evtUtils.getTimestamp()*/, evt.getProducerID(), subscribersPackageName, subscriptionSensorReadings); if (D) Log.d(TAG, "insertOrReplaceRecord(" + evt.getEventType() + ", " + evt.getID() + ", " + evt.getTimestamp() + ", " + evt.getProducerID() + ", " + subscribersPackageName + ", " + subscriptionSensorReadings + ")"); db.close(); //If there are no EventProducers send a TransformationManagerRequest //TODO: Due to lack in restore DB - erwaehnen in der Bachelorthesis if (advertisementHashMap.get(subscriptionSensorReadings) == null) { sendEventTransformationRequest(subscriptionSensorReadings); if (D) Log.d(TAG, "sendTransfromtionRequest(" + subscriptionSensorReadings + ");"); } if (D_ROUTING) printAdvertisementsAndSubscriptions(); //Unsubscription } else if (evt.getEventType().equals(ManagementEvent.UNSUBSCRIPTION)) { if (D) Log.d(TAG, "Unsubscription event from " + evt.getProducerID()); String unsubscribersPackageName = ((Unsubscription) evt).getPackageName(); String unsubscriptionSensorReadings = ((Unsubscription) evt).getUnsubscriptionSensorReadings(); //Check if Event is already subscribed if (subscriberChannelHashMap.containsKey(unsubscriptionSensorReadings)) { List<String> tempList = subscriberChannelHashMap.get(unsubscriptionSensorReadings); if (tempList.contains(unsubscribersPackageName)) { //Check all effected producers and send a StartEvent if no one is already subscribed to it unsubscriptionCheckWithAllAvailableEventsThatMatch(unsubscriptionSensorReadings); //Important: Check before removing! tempList.remove(unsubscribersPackageName); if (D) Log.d(TAG, "Unsubscription successful: EventTypeShort: " + getLastStringAfterDot(unsubscriptionSensorReadings) + ", PackageNameShort: " + getLastStringAfterDot(unsubscribersPackageName)); //Unsubscription successful write to database db.openWritabelDB(); db.insertOrReplaceRecord(evt.getEventType(), evt.getID(), evt.getTimestamp() /*evtUtils.getTimestamp() */, evt.getProducerID(), unsubscribersPackageName, unsubscriptionSensorReadings); if (D) Log.d(TAG, "insertRecord(" + evt.getEventType() + ", " + evt.getID() + ", " + evt.getTimestamp() + ", " + evt.getProducerID() + ", " + unsubscribersPackageName + ", " + unsubscriptionSensorReadings + ")"); db.close(); } if (tempList.isEmpty()) { // delete key from HashMap if there are no more subscriptions for this EventType subscriberChannelHashMap.remove(unsubscriptionSensorReadings); if (D) Log.d(TAG, "No more Subscribers delte Entry in subscribersHashMap for EventTypeShort: " + getLastStringAfterDot(unsubscriptionSensorReadings)); } } if (D_ROUTING) printAdvertisementsAndSubscriptions(); //Announcement } else if (evt.getEventType().equals(ManagementEvent.ANNOUNCEMENT)) { int announcement = ((Announcement) evt).getAnnouncement(); String packageName = ((Announcement) evt).getPackageName(); String eventType = ((Announcement) evt).getTransmittedEventType(); String sender = ((Announcement) evt).getProducerID(); printAnnouncement(evt); switch (announcement) { case Announcement.SENSOR_CONNECTED: case Announcement.SENSOR_DISCONNECTED: // Distribute announcement via LocalBroadcastManager for SensorConfigurationActivity sendToManagementChannel(evt, getPackageName()); // Distribute announcement to subscribed consumers List<String> receiverPackageNameList = getSubscribersListForEventType(eventType); if (receiverPackageNameList != null) { sendAnnouncementToRecieverList(announcement, eventType, receiverPackageNameList); } // store state for future subscriptions sensorConnectivityAnnouncement.put(eventType, announcement); if (D_ANNOUNCEMENT) Log.d(TAG, "Announcement Received: " + announcement + " from: " + sender); break; case Announcement.GET_ALL_AVAILABLE_EVENT_TYPES: sendAllAvailableEventTypes(packageName); if (D_ANNOUNCEMENT) Log.d(TAG, "Announcement Received: sendAllAvailableEventTypes from: " + sender); break; case Announcement.DATABASE_CLEAR_ALL: if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "Announcement Received: DATABASE_CLEAR_ALL from: " + sender); db.openWritabelDB(); db.deleteAll(); db.close(); break; case Announcement.DATABASE_SHOW_WITH_ALL_SUBSCRIPTIONS_AND_UNSUBSCRIPTIONS: if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "Announcement Received: DATABASE_SHOW_WITH_ALL_SUBSCRIPTIONS_AND_UNSUBSCRIPTIONS from: " + sender); db.openReadableDB(); Cursor c = db.getAllRecords(); if (c.moveToFirst()) { if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "c.moveToFirst() == " + c.moveToFirst()); while (!c.isAfterLast()) { displayRecord(c); c.moveToNext(); } } db.close(); break; default: break; } } }; } /** * Sends an EventTransformationsRequest for the given event type and all available events. * @param requested event type */ public void sendEventTransformationRequest(String subscriptionSensorReadings) { String[] allAvailableEvents = getAllAvailableEvents(); // Create request EventTransformationRequest request = createRequestEvent( EventTransformationRequest.TYPE_REQUEST_TRANSFORMATION, allAvailableEvents, subscriptionSensorReadings); // Broadcast event locally Intent i = new Intent(); i.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, request.getEventType()); i.putExtra(Event.PARCELABLE_EXTRA_EVENT, request); i.setAction(AbstractChannel.LOCAL_MANAGEMENT); LocalBroadcastManager.getInstance(this).sendBroadcast(i); } /** * Sends all available event types from the advertisementHashMap as an announcement using the package names for explicit addressing. * @param packageName used to setPackageName(packageName) */ private void sendAllAvailableEventTypes(String packageName) { String[] availableEventTypes = getAllAvailableEvents(); Announcement announcement = new Announcement(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, "", getPackageName(), Announcement.ALL_AVAILABLE_EVENT_TYPES); Intent intent = new Intent(); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, announcement.getEventType()); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, announcement); intent.putExtra(Event.PARCELABLE_EXTRA_AVAILABLE_EVENTS, availableEventTypes); if (D) Log.d(TAG, "availableEventTypes String[]" + availableEventTypes); //Implicit addressing intent.setAction(AbstractChannel.MANAGEMENT); //Explicit addressing intent.setPackage(packageName); getApplicationContext().sendBroadcast(intent); } /** * Sends a StopEvent to all producers who have exactly one subscriber now and will have zero after removing. * @param unsubscriptionSensorReadings event type that gets unsubscribed */ private void unsubscriptionCheckWithAllAvailableEventsThatMatch(String unsubscriptionSensorReadings) { String[] allAvailableEventTypes = getAllAvailableEvents(); List<String> matchUnsubscriptionAvailableEventTypes = new ArrayList<String>(); if (allAvailableEventTypes == null) return; //Get all availableEvents that start with channel subscription for (int i = 0; i < allAvailableEventTypes.length; i++) { if (allAvailableEventTypes[i].startsWith(unsubscriptionSensorReadings)) { matchUnsubscriptionAvailableEventTypes.add(allAvailableEventTypes[i]); } } //Needs to check with each possible matching event, due to the tree structure and possibility to unsubscribe on a node or leaf //Send a StopEvent to all producers, who have exactly one subscribers yet and will have zero after removing for (int j = 0; j < matchUnsubscriptionAvailableEventTypes.size(); j++) { //StopEvent to all producers only if no other channel is subscribed on this EventType already if (getSubscribersListForEventType(matchUnsubscriptionAvailableEventTypes.get(j)).size() == 1) { sendStopEventToAllProducersForEventType(matchUnsubscriptionAvailableEventTypes.get(j)); } } } /** * Sends a StartEvent to all producers, who have zero subscriber now and will have one after removing. * @param subscriptionSensorReadings EventType that gets subscribed for */ private void subscriptionCheckWithAllAvailableEventsThatMatch(String subscriptionSensorReadings) { String[] allAvailableEventTypes = getAllAvailableEvents(); List<String> matchSubscriptionAvailableEventTypes = new ArrayList<String>(); if (allAvailableEventTypes == null) return; //Get all availableEvents that start with channel subscription for (int i = 0; i < allAvailableEventTypes.length; i++) { if (allAvailableEventTypes[i].startsWith(subscriptionSensorReadings)) { matchSubscriptionAvailableEventTypes.add(allAvailableEventTypes[i]); } } //Needs to check with each possible event, due to the tree structure and possibility to subscribe on a node or leaf //Send a StartEvent to all producers, who have no subscribers yet and will have exactly 1 after subscription for (int j = 0; j < matchSubscriptionAvailableEventTypes.size(); j++) { //StartEvent to all producers only if no other channel is subscribed on this EventType already if (getSubscribersListForEventType(matchSubscriptionAvailableEventTypes.get(j)) == null) { sendStartEventToAllProducersForEventType(matchSubscriptionAvailableEventTypes.get(j)); } } } /** * Sends a StopEvent to all producers in the advertismentHashMap for the given event type. * @param eventType */ private void sendStopEventToAllProducersForEventType(String eventType) { List<ProducerDetails> producersDetailsList = advertisementHashMap.get(eventType); if (producersDetailsList == null) return; for (int i = 0; i < producersDetailsList.size(); i++) { sendStopEvent(producersDetailsList.get(i).getProducerID(), eventType, producersDetailsList.get(i).getProducerPackageName()); } } /** * Sends a StartEvent to all producers in the advertismentHashMap for the given event type * @param eventType */ private void sendStartEventToAllProducersForEventType(String eventType) { List<ProducerDetails> producersDetailsList = advertisementHashMap.get(eventType); if (producersDetailsList == null) return; for (int i = 0; i < producersDetailsList.size(); i++) { sendStartEvent(producersDetailsList.get(i).getProducerID(), eventType, producersDetailsList.get(i).getProducerPackageName()); } } /** * Different checks if the given Event is valid. Announcements are sent accordingly to the violation. * @param evt The Event that has to be checked * @return returns true if all checks are passed successful */ public boolean isManagementEventValid(Event evt) { String packageName = null; String transmittedEventType = null; //discard invalid EventTypes if (evt.getEventType() == null) return false; //Advertisement if (evt.getEventType().equals(ManagementEvent.JSON_DATA_EXCHANGE)) { packageName = ((JSONDataExchange) evt).getPackageName(); transmittedEventType = ((JSONDataExchange) evt).getDataExchangeEventType(); String json = ((JSONDataExchange) evt).getJSONEncodedData(); if (json == null) { sendAnnouncement(Announcement.INVALID_EVENT_TYPE_ARGUMENTS, transmittedEventType, packageName); return false; } } //Advertisement if (evt.getEventType().equals(ManagementEvent.ADVERTISEMENT)) { packageName = ((Advertisement) evt).getPackageName(); transmittedEventType = ((Advertisement) evt).getAdvertisedEventType(); String json = ((Advertisement) evt).getJSONEncodedProperties(); if (json == null) { sendAnnouncement(Announcement.INVALID_EVENT_TYPE_ARGUMENTS, transmittedEventType, packageName); return false; } //Unadvertisement } else if (evt.getEventType().equals(ManagementEvent.UNADVERTISEMENT)) { packageName = ((Unadvertisement) evt).getPackageName(); transmittedEventType = ((Unadvertisement) evt).getUnadvertisedEventType(); //Subscription } else if (evt.getEventType().equals(ManagementEvent.SUBSCRIPITON)) { packageName = ((Subscription) evt).getPackageName(); transmittedEventType = ((Subscription) evt).getSubscriptionSensorReadings(); /* //Check if application(packageName) has permission to subscribe to this EventType if(!securityManager.hasPermission(packageName, transmittedEventType)){ sendAnnouncement(ManagementEvent.SUBSCRIPTION_UNSUCCESSFULL_NO_PERMISSION, transmittedEventType, packageName); return false; } */ //Unsubscription } else if (evt.getEventType().equals(ManagementEvent.UNSUBSCRIPTION)) { packageName = ((Unsubscription) evt).getPackageName(); transmittedEventType = ((Unsubscription) evt).getUnsubscriptionSensorReadings(); //Announcement } else if (evt.getEventType().equals(ManagementEvent.ANNOUNCEMENT)) { packageName = ((Announcement) evt).getPackageName(); //none transmitted, set to valid value to support the testing scheme transmittedEventType = Event.EVENT_ROOT; } // If any Event variables are null if (evt.getID() == null || evt.getProducerID() == null || evt.getTimestamp() == null) { Log.w(TAG, "Error at least one Event argument is null"); sendAnnouncement(Announcement.INVALID_EVENT_TYPE_ARGUMENTS, transmittedEventType, packageName); return false; } //If EventType does not follow conventions if (!doesEventTypeMatchConventions(transmittedEventType)) { Log.w(TAG, "Error EVENT_TYPE_DOES_NOT_MATCH_NAME_CONVENTION"); sendAnnouncement(Announcement.EVENT_TYPE_DOES_NOT_MATCH_NAME_CONVENTION, transmittedEventType, packageName); return false; } //Check if application(packageName) is installed on device if (!isPackageInstalled(packageName)) { //Probably not useful to send this announcement Log.w(TAG, "PackageName invalid:" + packageName); sendAnnouncement(Announcement.MANAGEMENTEVENT_UNSUCCESSFULL_APPLICATION_NOT_INSTALLED, transmittedEventType, packageName); return false; } return true; } /** * Check if the event type matches event type conventions * @param eventType * @return returns true if check is passed */ public boolean doesEventTypeMatchConventions(String eventType) { if (eventType == null) return false; if (eventType.startsWith(Event.EVENT_ROOT)) return true; return false; } /** * Sends an announcement event to the given announcement receiver package name ManagementReceiver * @param typeOfAnnouncement Types defined in ManagmentEvent.STRING * @param transmittedEventType * @param announcementReceiverPackageName Used for explicit addressing - setPackageName(packageName) */ private void sendAnnouncement(int typeOfAnnouncement, String transmittedEventType, String announcementReceiverPackageName) { //if no packageName is set do not send an announcement if (announcementReceiverPackageName == null) return; Announcement announcement = new Announcement(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, transmittedEventType, announcementReceiverPackageName, typeOfAnnouncement); sendToManagementChannel(announcement, announcementReceiverPackageName); /*Intent intent = new Intent(); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, announcement.getEventType()); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, announcement); //Implicit addressing intent.setAction(ReadingChannels.MANAGEMENT); //Explicit addressing printAnnouncement(announcement); intent.setPackage(announcementReceiverPackageName); getApplicationContext().sendBroadcast(intent);*/ } /** * Sends announcements events to the given receiver package names list * @param typeOfAnnouncement Types defined in ManagmentEvent.STRING * @param eventType * @param listOfRecievers List of receiver package names used to explicit address ManagementReceivers */ private void sendAnnouncementToRecieverList(int typeOfAnnouncement, String eventType, List<String> listOfRecievers) { for (int i = 0; i < listOfRecievers.size(); i++) { sendAnnouncement(typeOfAnnouncement, eventType, listOfRecievers.get(i)); } } /** * Sends a start event to the given package names ManagementReceiver * @param eventProducerID * @param startEventType * @param packageName Receivers package name used to explicit address ManagementReceivers */ private void sendStartEvent(String eventProducerID, String startEventType, String packageName) { StartProducer startEvent = new StartProducer(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, eventProducerID, startEventType); sendToManagementChannel(startEvent, packageName); Log.i(TAG, "StartProducer Sensor: " + eventProducerID + ", EventTypeShort: " + getLastStringAfterDot(startEventType) + ", PackageNameShort: " + getLastStringAfterDot(packageName)); } /** * Sends a StopEvent to the given package names ManagementReceiver * @param eventProducerID * @param stopEventType * @param packageName Receivers package name used to explicit address ManagementReceiver */ private void sendStopEvent(String eventProducerID, String stopEventType, String packageName) { StopProducer stopEvent = new StopProducer(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, eventProducerID, stopEventType); sendToManagementChannel(stopEvent, packageName); Log.i(TAG, "StopProducer Sensor: " + eventProducerID + ", EventTypeShort: " + getLastStringAfterDot(stopEventType) + ", PackageNameShort: " + getLastStringAfterDot(packageName)); } /** * Sends an event to the local or global management channel depending on * the packageName. If the packageName equals the myHealthHub package name, * the event is send locally. * @param event that needs to be send * @param packageName of the receiver */ private void sendToManagementChannel(Event evt, String packageName) { Intent intent = new Intent(); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, evt.getEventType()); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, evt); // use local management channel for internal sensor modules if (packageName.equals(getPackageName())) { if (D) Log.d(TAG, "Sending on local management channel:" + evt.getEventType()); intent.setAction(AbstractChannel.LOCAL_MANAGEMENT); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); // use global management channel for external sensor modules (i.e. other applications) } else { if (D) Log.d(TAG, "Sending on global management channel:" + evt.getEventType()); //Implicit addressing intent.setAction(AbstractChannel.MANAGEMENT); //Explicit addressing intent.setPackage(packageName); getApplicationContext().sendBroadcast(intent); } } /** * Creates a EventTransformationRequest * @param requestType * @param advertisedEvents * @param eventSubscription * @return EventTransformationRequest */ private EventTransformationRequest createRequestEvent(int requestType, String[] advertisedEvents, String eventSubscription) { return new EventTransformationRequest(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, requestType, advertisedEvents, eventSubscription); } /** * Get all available events from the advertismentHashMap * @return String[] containing all available event types */ public String[] getAllAvailableEvents() { //Android documentation: The set does not support adding Set<String> availableEvents = advertisementHashMap.keySet(); if (availableEvents == null) return null; String[] events = availableEvents.toArray(new String[availableEvents.size()]); for (int i = 0; i < events.length; i++) { if (D || D_ROUTING) Log.d(TAG, "String[" + i + "] = Value: " + events[i]); } return events; } /** * Checks the subscribers permission for the channel/event type with a list of allowed subscribers for the channel/event type * @param eventType * @param allowedSubscribersPackageNamesList */ public void checkPermissionsForEventType(String eventType, List<String> allowedSubscribersPackageNamesList) { List<String> subscribersPackageNames = subscriberChannelHashMap.get(eventType); List<String> toBeUnsubscribedPackageNamesList = new ArrayList<String>(); //If there are subscribers verify them with allowedSubscribersPackageNamesList if (subscribersPackageNames != null) { for (int i = 0; i < subscribersPackageNames.size(); i++) { //Check if subscriber still has the permission if (allowedSubscribersPackageNamesList.contains(subscribersPackageNames.get(i))) { if (D) Log.d(TAG, "Permission verified successfull" + subscribersPackageNames.get(i)); } else { if (D) Log.d(TAG, "Permission not verified - unsubscribe" + subscribersPackageNames.get(i)); sendAnnouncement(Announcement.SECURITY_PERMISSION_REMOVED, eventType, subscribersPackageNames.get(i)); toBeUnsubscribedPackageNamesList.add(subscribersPackageNames.get(i)); } } } sendUnsubscriptionsForAllInvalidSubscribers(eventType, toBeUnsubscribedPackageNamesList); } /** * Sends an Unsubscription event for all subscribers package names in the list * @param eventType * @param toBeUnsubscribedPackageNamesList Package names to be removed from the subscribersHashMap */ private void sendUnsubscriptionsForAllInvalidSubscribers(String eventType, List<String> toBeUnsubscribedPackageNamesList) { for (int i = 0; i < toBeUnsubscribedPackageNamesList.size(); i++) { sendUnsubscription(eventType, toBeUnsubscribedPackageNamesList.get(i)); } } /** * Sends an Unsubscription event to the subscribers package name for the given event type * @param eventType * @param toBeUnsubscribedPackageName */ private void sendUnsubscription(String eventType, String toBeUnsubscribedPackageName) { Unsubscription unsubcribe = new Unsubscription(evtUtils.getEventID(), evtUtils.getTimestamp(), TAG, toBeUnsubscribedPackageName, eventType); Intent intent = new Intent(); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, unsubcribe.getEventType()); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, unsubcribe); intent.setAction(AbstractChannel.MANAGEMENT); sendBroadcast(intent); } /** * Parses event type filed and returns String array representing * the tree structure of the event type. myHealhAssistant prefix * is removed. * @param EVENT_TYPE Event type. * @return String[] including event tree. */ private String[] parseEventType(String eventType) { // Return null if not myHealthAssistant prefix if (!eventType.startsWith(Event.EVENT_ROOT)) return null; // Remove prefix eventType = eventType.substring(Event.EVENT_ROOT.length() + 1, eventType.length()); // Store fields into String array String[] eventTree = eventType.split("\\."); return eventTree; } /** * Get all subscribers (for each step in the event tree) for the event type, according to the tree structure and the possibility to subscribe to a node or leaf * * @return: a list of package names or null if there are no receivers */ private List<String> getSubscribersListForEventType(String eventType) { // Parse event type into an event tree String[] eventTree = parseEventType(eventType); // Discard invalid events if (eventTree == null) { Log.e(TAG, "Invalid incoming event type: " + eventType); return null; } List<String> listOfReceivers = new ArrayList<String>(); List<String> tempSubscriberList; String channelName = Event.EVENT_ROOT; //Build a list of receivers referring to the event tree subscriptions for (int i = 0; i < eventTree.length; i++) { channelName = (channelName + "." + eventTree[i]); //Log.d(TAG,"Search key for HashMap: "+channelName); tempSubscriberList = subscriberChannelHashMap.get(channelName); if (tempSubscriberList != null) { //Log.d(TAG,"Length HashMap result: "+tempSubscriberList.size()); listOfReceivers.addAll(tempSubscriberList); } } if (listOfReceivers.size() != 0) { return listOfReceivers; } return null; } /** * Verifies if the package is installed using the PackageManager and the given package name * @param packageName * @return Returns true if package is installed */ public boolean isPackageInstalled(String packageName) { if (packageName == null) return false; PackageManager pm = getPackageManager(); try { PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_META_DATA); } catch (NameNotFoundException e) { return false; } return true; } /** * SecurityManager: quick and dirty implementation for testing only */ private class SecurityManager { private HashMap<String, List<String>> permissionHashMap; private List<String> listOfPermissionApplication01 = new ArrayList<String>(); private List<String> listOfPermissionApplication02 = new ArrayList<String>(); public SecurityManager() { permissionHashMap = new HashMap<String, List<String>>(); listOfPermissionApplication01.add(SensorReadingEvent.READING_EVENT); listOfPermissionApplication01.add(SensorReadingEvent.ACCELEROMETER); listOfPermissionApplication02.add(SensorReadingEvent.HEART_RATE); permissionHashMap.put("com.example.myhealthhubsetpackage.application01", listOfPermissionApplication01); permissionHashMap.put("com.example.myhealthhubsetpackage.application02", listOfPermissionApplication02); } /** * Checks if a application has permission to subscribe on channel */ private boolean hasPermission(String packageName, String channel) { List<String> tempList = new ArrayList<String>(); tempList = permissionHashMap.get(packageName); if (tempList != null) { if (tempList.contains(channel)) { if (D) Log.d(TAG, "True: Permission is avaiable: " + channel); return true; } } if (D) Log.d(TAG, "False: Permission is avaiable: " + channel); return false; } } /** EventTransformation event receiver */ public class ResponseReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Skip if not a event transformation response if (!intent.getStringExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE) .equals(EventTransformationResponse.EVENT_TYPE)) return; // Get and print event EventTransformationResponse response = intent.getParcelableExtra(Event.PARCELABLE_EXTRA_EVENT); if (D) Log.d(TAG, "Got result " + response.isTransformationFound() + " for request ID: " + response.getID() + "."); } } /** * Returns the last String separated by "." * @param name * @return Returns last String separated by "." */ private String getLastStringAfterDot(String name) { if (name.contains(".") && name.length() >= 3) { String[] nameSplit = name.split("\\."); return nameSplit[nameSplit.length - 1]; } return "Error String does not contain '.' or is to short)"; } /** * Used for connecting a producerID with a package name to explicit address the producer * @author Jens * */ private class ProducerDetails { private String ProducerID; private String ProducerPackageName; public ProducerDetails(String producerID, String producerPackageName) { ProducerID = producerID; ProducerPackageName = producerPackageName; } public String getProducerID() { return ProducerID; } public void setProducerID(String producerID) { ProducerID = producerID; } public String getProducerPackageName() { return ProducerPackageName; } public void setProducerPackageName(String producerPackageName) { ProducerPackageName = producerPackageName; } } @Override public void onCreate() { Log.i(TAG, getPackageName()); // Initialize event RECEIVER mEventReceiver = new EventReceiver(); getApplication().registerReceiver(mEventReceiver, sensorReadingsChannel); LocalBroadcastManager.getInstance(this).registerReceiver(mEventReceiver, sensorReadingsChannel); // Notification Receiver mNotificationReceiver = new NotificationReceiver(); getApplication().registerReceiver(mNotificationReceiver, notificationChannel); // Management Receiver mManagementReceiver = new ManagementReceiver(); getApplication().registerReceiver(mManagementReceiver, managementReceiverChannel); LocalBroadcastManager.getInstance(this).registerReceiver(mManagementReceiver, managementReceiverChannel); mResponseReceiver = new ResponseReceiver(); LocalBroadcastManager.getInstance(this).registerReceiver(mResponseReceiver, mResponseReceiverChannel); subscriberChannelHashMap = new HashMap<String, List<String>>(); advertisementHashMap = new HashMap<String, List<ProducerDetails>>(); sensorConnectivityAnnouncement = new HashMap<String, Integer>(); //securityManager = new SecurityManager(); evtUtils = new EventUtils(NotificationEvent.EVENT_TYPE, TAG); //mTransformationManager = new TransformationManager(this, AbstractChannel.LOCAL_MANAGEMENT); db = new DBAdapterSubscriptions(this); restoreSubscriptionsFromDB(); } /** * Starts to restore the subscriberHashMap from a database */ private void restoreSubscriptionsFromDB() { Log.i(TAG, "Restore Subscriptions From DB"); db.openReadableDB(); Cursor c = db.getAllRecords(); if (c.moveToFirst()) { while (!c.isAfterLast()) { sendSubscription(c); c.moveToNext(); } } db.close(); printAdvertisementsAndSubscriptions(); } /** * Creates Subscriptions * @param c Cursor fetched from database with the necessary information to create a Subscription */ private void sendSubscription(Cursor c) { String eventType = c.getString(1); String eventID = c.getString(2); String timeStamp = c.getString(3); String producerID = c.getString(4); String packageName = c.getString(5); String subscribedEventType = c.getString(6); Intent intent = new Intent(); if (eventType.equals(ManagementEvent.SUBSCRIPITON)) { Subscription subscribe = new Subscription(eventID, timeStamp, producerID, packageName, subscribedEventType); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, subscribe.getEventType()); intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, subscribe); if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "Subscription sent: " + producerID + ", packageNameShort: " + getLastStringAfterDot(packageName) + ", subscribedEventTypeShort: " + getLastStringAfterDot(subscribedEventType)); intent.setAction(AbstractChannel.MANAGEMENT); intent.setPackage(getPackageName()); sendBroadcast(intent); } //No need to send Unsubscription else if (eventType.equals(ManagementEvent.UNSUBSCRIPTION)) { Unsubscription unsubscribe = new Unsubscription(eventID, timeStamp, producerID, packageName, subscribedEventType); //intent.putExtra(Event.PARCELABLE_EXTRA_EVENT_TYPE, unsubscribe.getEventType()); //intent.putExtra(Event.PARCELABLE_EXTRA_EVENT, unsubscribe); if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "Unsubscription restored but not sent: " + producerID + ", packageNameShort: " + getLastStringAfterDot(packageName) + ", subscribedEventTypeShort: " + getLastStringAfterDot(subscribedEventType)); } } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind(): entered..."); return null; } public void onUnbind() { if (D) Log.d(TAG, "onUnbind(): entered..."); } public void onDestroy() { if (D) Log.d(TAG, "onDestroy() entered..."); getApplication().unregisterReceiver(mEventReceiver); getApplication().unregisterReceiver(mNotificationReceiver); } //TODO: Can be removed after testing /** * Prints an announcement to LogCat using TAG_ANNOUNCEMENT * @param evt */ public void printAnnouncement(Event evt) { int announcement = ((Announcement) evt).getAnnouncement(); String packageName = ((Announcement) evt).getPackageName(); String eventType = ((Announcement) evt).getTransmittedEventType(); String sender = ((Announcement) evt).getProducerID(); if (D_ANNOUNCEMENT) Log.d(TAG_ANNOUNCEMENT, "Announcement Details: " + sender + ", AnnouncementType: " + announcement + ", PackageNameShort: " + getLastStringAfterDot(packageName) + ", EventTypeShort: " + getLastStringAfterDot(eventType)); } /** * Prints an database entry to LogCat using TAG_ANNOUNCEMENT * @param c */ private void displayRecord(Cursor c) { Log.d(TAG, "DisplayRecord: "); Log.d(TAG, "" + DBAdapterSubscriptions.KEY_ROWID + " : " + c.getString(0) + "\n" + DBAdapterSubscriptions.KEY_EVENT_TYPE + " : " + c.getString(1) + "\n" + DBAdapterSubscriptions.KEY_EVENT_ID + " : " + c.getString(2) + "\n" + DBAdapterSubscriptions.KEY_TIMESTAMP + " : " + c.getString(3) + "\n" + DBAdapterSubscriptions.KEY_PRODUCER_ID + " : " + c.getString(4) + "\n" + DBAdapterSubscriptions.KEY_PACKAGE_NAME + " : " + c.getString(5) + "\n" + DBAdapterSubscriptions.KEY_READING_EVENT_TYPE + " : " + c.getString(6) + "\n"); } /** * Prints lists of advertised and subscribed events. */ private void printAdvertisementsAndSubscriptions() { Log.d(TAG_ROUTING, "--\nList of Advertisements:"); Log.d(TAG_ROUTING, "======================="); getAllAvailableEvents(); Log.d(TAG_ROUTING, "\nList of Subscriptions:"); Log.d(TAG_ROUTING, "======================"); String output = ""; Iterator<Entry<String, List<String>>> it = subscriberChannelHashMap.entrySet().iterator(); while (it.hasNext()) { Entry<String, List<String>> e = it.next(); output += e.getKey() + "\t | "; for (String channel : e.getValue()) { output += channel + ", "; } output += "\n"; } Log.d(TAG_ROUTING, output + "\n--"); } }