From ea7da0724f465507c7ba9d6749a982f6f649c1be Mon Sep 17 00:00:00 2001 From: Madawa Soysa Date: Thu, 24 Nov 2016 18:09:11 +0530 Subject: [PATCH 01/10] IOTS-296: Generalizing policy UI for Android device type This commit includes moving policy flow device type specific client side logic and UI components to the android plugin. --- .../policy-wizard.hbs | 2 +- .../policy-edit.hbs | 19 +- .../public/js/android-policy-edit.js | 855 ++++++++++ .../public/templates/android-policy-edit.hbs | 1464 +++++++++++++++++ .../policy-wizard.hbs | 47 +- .../public/js/android-policy-operations.js | 842 ++++++++++ .../templates/android-policy-operations.hbs | 1464 +++++++++++++++++ 7 files changed, 4662 insertions(+), 31 deletions(-) create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/js/android-policy-edit.js create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/templates/android-policy-edit.hbs create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/js/android-policy-operations.js create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/templates/android-policy-operations.hbs diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.policy-wizard/policy-wizard.hbs b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.policy-wizard/policy-wizard.hbs index 2ddd9c1d1c..fbd9fb6d04 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.policy-wizard/policy-wizard.hbs +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.policy-wizard/policy-wizard.hbs @@ -15,4 +15,4 @@ specific language governing permissions and limitations under the License. }} -{{unit "cdmf.unit.policy.wizard"}} \ No newline at end of file +{{unit "cdmf.unit.policy.create"}} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/policy-edit.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/policy-edit.hbs index c4bb415a11..7b9952568a 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/policy-edit.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/policy-edit.hbs @@ -1 +1,18 @@ -{{unit "mdm.unit.policy.edit"}} \ No newline at end of file +{{! + 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. +}} +{{unit "cdmf.unit.policy.edit"}} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/js/android-policy-edit.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/js/android-policy-edit.js new file mode 100644 index 0000000000..eb36242fea --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/js/android-policy-edit.js @@ -0,0 +1,855 @@ +/* + * 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. + */ +// Constants to define Android Operation Constants +var androidOperationConstants = { + "PASSCODE_POLICY_OPERATION": "passcode-policy", + "PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY", + "CAMERA_OPERATION": "camera", + "CAMERA_OPERATION_CODE": "CAMERA", + "ENCRYPT_STORAGE_OPERATION": "encrypt-storage", + "ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE", + "WIFI_OPERATION": "wifi", + "WIFI_OPERATION_CODE": "WIFI", + "VPN_OPERATION": "vpn", + "VPN_OPERATION_CODE": "VPN", + "APPLICATION_OPERATION": "app-restriction", + "APPLICATION_OPERATION_CODE": "APP-RESTRICTION", + "KIOSK_APPS_CODE": "KIOSK_APPS", + "KIOSK_APPS": "cosu-whitelisted-applications" +}; + +/** + * Method to update the visibility of grouped input. + * @param domElement HTML grouped-input element with class name "grouped-input" + */ +var updateGroupedInputVisibility = function (domElement) { + if ($(".parent-input:first", domElement).is(":checked")) { + if ($(".grouped-child-input:first", domElement).hasClass("disabled")) { + $(".grouped-child-input:first", domElement).removeClass("disabled"); + } + $(".child-input", domElement).each(function () { + $(this).prop('disabled', false); + }); + } else { + if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) { + $(".grouped-child-input:first", domElement).addClass("disabled"); + } + $(".child-input", domElement).each(function () { + $(this).prop('disabled', true); + }); + } +}; + +var polulateProfileOperations = function (configuredOperations) { + $(".wr-advance-operations li.grouped-input").each(function () { + updateGroupedInputVisibility(this); + }); + for (var i = 0; i < configuredOperations.length; ++i) { + var configuredOperation = configuredOperations[i]; + $(".operation-data").filterByData("operation-code", configuredOperation) + .find(".panel-title .wr-input-control.switch input[type=checkbox]").each(function () { + $(this).click(); + }); + } +}; + +/** + * Checks if provided number is valid against a range. + * + * @param numberInput Number Input + * @param min Minimum Limit + * @param max Maximum Limit + * @returns {boolean} Returns true if input is within the specified range + */ +var inputIsValidAgainstRange = function (numberInput, min, max) { + return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max); +}; + +var validatePolicyProfile = function () { + var validationStatusArray = []; + var validationStatus; + var operation; + + // starting validation process and updating validationStatus + if (configuredOperations.length == 0) { + // updating validationStatus + validationStatus = { + "error": true, + "mainErrorMsg": "You cannot continue. Zero configured features." + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } else { + // validating each and every configured Operation + // Validating PASSCODE_POLICY + if ($.inArray(androidOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) { + // if PASSCODE_POLICY is configured + operation = androidOperationConstants["PASSCODE_POLICY_OPERATION"]; + // initializing continueToCheckNextInputs to true + var continueToCheckNextInputs = true; + + // validating first input: passcodePolicyMaxPasscodeAgeInDays + var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val(); + if (passcodePolicyMaxPasscodeAgeInDays) { + if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode age is not a number.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + + // validating second and last input: passcodePolicyPasscodeHistory + if (continueToCheckNextInputs) { + var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val(); + if (passcodePolicyPasscodeHistory) { + if (!$.isNumeric(passcodePolicyPasscodeHistory)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode history is not a number.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + } + + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating CAMERA + if ($.inArray(androidOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) { + // if CAMERA is configured + operation = androidOperationConstants["CAMERA_OPERATION"]; + // updating validationStatus + validationStatus = { + "error": false, + "okFeature": operation + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating ENCRYPT_STORAGE + if ($.inArray(androidOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) { + // if ENCRYPT_STORAGE is configured + operation = androidOperationConstants["ENCRYPT_STORAGE_OPERATION"]; + // updating validationStatus + validationStatus = { + "error": false, + "okFeature": operation + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating WIFI + if ($.inArray(androidOperationConstants["WIFI_OPERATION_CODE"], configuredOperations) != -1) { + // if WIFI is configured + operation = androidOperationConstants["WIFI_OPERATION"]; + // initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var wifiSSID = $("input#wifi-ssid").val(); + if (!wifiSSID) { + validationStatus = { + "error": true, + "subErrorMsg": "WIFI SSID is not given. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + // For the secure wifi types, it is required to have a password + var wifiTypeUIElement = $("#wifi-type"); + var wifiType = wifiTypeUIElement.find("option:selected").val(); + if (wifiTypeUIElement.is("input:checkbox")) { + wifiType = wifiTypeUIElement.is(":checked").toString(); + } + if (wifiType != "none") { + if (!$("#wifi-password").val()) { + validationStatus = { + "error": true, + "subErrorMsg": "Password is required for the wifi security type " + wifiType + ". " + + "Please provide a password to proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + + if ($.inArray(androidOperationConstants["VPN_OPERATION_CODE"], configuredOperations) != -1) { + // if WIFI is configured + operation = androidOperationConstants["VPN_OPERATION"]; + // initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var serverAddress = $("input#vpn-server-address").val(); + if (!serverAddress) { + validationStatus = { + "error": true, + "subErrorMsg": "Server address is required. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + if (continueToCheckNextInputs) { + var serverPort = $("input#vpn-server-port").val(); + if (!serverPort) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port is required. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!$.isNumeric(serverPort)) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port requires a number input.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(serverPort, 0, 65535)) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port is not within the range " + + "of valid port numbers.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + if ($.inArray(androidOperationConstants["APPLICATION_OPERATION_CODE"], configuredOperations) != -1) { + //If application restriction configured + operation = androidOperationConstants["APPLICATION_OPERATION"]; + // Initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var appRestrictionType = $("#app-restriction-type").val(); + + var restrictedApplicationsGridChildInputs = "div#restricted-applications .child-input"; + + if (!appRestrictionType) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications restriction type is not provided.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + if (continueToCheckNextInputs) { + if ($(restrictedApplicationsGridChildInputs).length == 0) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications are not provided in application restriction list.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + else { + childInputCount = 0; + childInputArray = []; + emptyChildInputCount = 0; + duplicatesExist = false; + // Looping through each child input + $(restrictedApplicationsGridChildInputs).each(function () { + childInputCount++; + if (childInputCount % 2 == 0) { + // If child input is of second column + childInput = $(this).val(); + childInputArray.push(childInput); + // Updating emptyChildInputCount + if (!childInput) { + // If child input field is empty + emptyChildInputCount++; + } + } + }); + // Checking for duplicates + initialChildInputArrayLength = childInputArray.length; + if (emptyChildInputCount == 0 && initialChildInputArrayLength > 1) { + for (m = 0; m < (initialChildInputArrayLength - 1); m++) { + poppedChildInput = childInputArray.pop(); + for (n = 0; n < childInputArray.length; n++) { + if (poppedChildInput == childInputArray[n]) { + duplicatesExist = true; + break; + } + } + if (duplicatesExist) { + break; + } + } + } + // Updating validationStatus + if (emptyChildInputCount > 0) { + // If empty child inputs are present + validationStatus = { + "error": true, + "subErrorMsg": "One or more package names of " + + "applications are empty.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (duplicatesExist) { + // If duplicate input is present + validationStatus = { + "error": true, + "subErrorMsg": "Duplicate values exist with " + + "for package names.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + } + } + + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // Updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + if ($.inArray(androidOperationConstants["KIOSK_APPS_CODE"], configuredOperations) != -1) { + //If COSU whitelisting applications configured + operation = androidOperationConstants["KIOSK_APPS"]; + // Initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + var whitelistedApplicationsGridChildInputs = "div#cosu-whitelisted-applications .child-input"; + if (continueToCheckNextInputs) { + if ($(whitelistedApplicationsGridChildInputs).length == 0) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications are not provided in application whitelist list.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + else { + childInputCount = 0; + childInputArray = []; + emptyChildInputCount = 0; + duplicatesExist = false; + // Looping through each child input + $(whitelistedApplicationsGridChildInputs).each(function () { + childInputCount++; + if (childInputCount % 2 == 0) { + // If child input is of second column + childInput = $(this).val(); + childInputArray.push(childInput); + // Updating emptyChildInputCount + if (!childInput) { + // If child input field is empty + emptyChildInputCount++; + } + } + }); + // Checking for duplicates + initialChildInputArrayLength = childInputArray.length; + if (emptyChildInputCount == 0 && initialChildInputArrayLength > 1) { + for (m = 0; m < (initialChildInputArrayLength - 1); m++) { + poppedChildInput = childInputArray.pop(); + for (n = 0; n < childInputArray.length; n++) { + if (poppedChildInput == childInputArray[n]) { + duplicatesExist = true; + break; + } + } + if (duplicatesExist) { + break; + } + } + } + // Updating validationStatus + if (emptyChildInputCount > 0) { + // If empty child inputs are present + validationStatus = { + "error": true, + "subErrorMsg": "One or more package names of " + + "applications are empty.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (duplicatesExist) { + // If duplicate input is present + validationStatus = { + "error": true, + "subErrorMsg": "Duplicate values exist with " + + "for package names.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + } + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + // Updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + } + // ending validation process + + // start taking specific notifying actions upon validation + var wizardIsToBeContinued; + var errorCount = 0; + var mainErrorMsgWrapper, mainErrorMsg, + subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon; + var i; + for (i = 0; i < validationStatusArray.length; i++) { + validationStatus = validationStatusArray[i]; + if (validationStatus["error"]) { + errorCount++; + if (validationStatus["mainErrorMsg"]) { + mainErrorMsgWrapper = "#policy-profile-main-error-msg"; + mainErrorMsg = mainErrorMsgWrapper + " span"; + $(mainErrorMsg).text(validationStatus["mainErrorMsg"]); + $(mainErrorMsgWrapper).removeClass("hidden"); + } else if (validationStatus["subErrorMsg"]) { + subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg"; + subErrorMsg = subErrorMsgWrapper + " span"; + subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error"; + subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok"; + featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured"; + // hiding featureConfiguredState as the first step + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // updating error state and corresponding messages + $(subErrorMsg).text(validationStatus["subErrorMsg"]); + if ($(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).removeClass("hidden"); + } + if (!$(subOkIcon).hasClass("hidden")) { + $(subOkIcon).addClass("hidden"); + } + if ($(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).removeClass("hidden"); + } + } + } else { + if (validationStatus["okFeature"]) { + subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg"; + subErrorIcon = "#" + validationStatus["okFeature"] + "-error"; + subOkIcon = "#" + validationStatus["okFeature"] + "-ok"; + featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured"; + // hiding featureConfiguredState as the first step + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // updating success state and corresponding messages + if (!$(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).addClass("hidden"); + } + if (!$(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).addClass("hidden"); + } + if ($(subOkIcon).hasClass("hidden")) { + $(subOkIcon).removeClass("hidden"); + } + } + } + } + + wizardIsToBeContinued = (errorCount == 0); + return wizardIsToBeContinued; +}; + +// Start of HTML embedded invoke methods +var showAdvanceOperation = function (operation, button) { + $(button).addClass('selected'); + $(button).siblings().removeClass('selected'); + var hiddenOperation = ".wr-hidden-operations-content > div"; + $(hiddenOperation + '[data-operation="' + operation + '"]').show(); + $(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide(); +}; + + +/** + * This method will display appropriate fields based on wifi type + * @param select + */ +var changeAndroidWifiPolicy = function (select) { + slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['wep', 'wpa', '802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-eap', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['802eap']); +}; + +/** + * This method will display appropriate fields based on wifi EAP type + * @param select + * @param superSelect + */ +var changeAndroidWifiPolicyEAP = function (select, superSelect) { + slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['peap', 'ttls', 'pwd', 'fast', 'leap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['peap', 'ttls', 'fast']); + slideDownPaneAgainstValueSet(select, 'control-wifi-provisioning', ['fast']); + slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['peap', 'tls', 'ttls', 'pwd', 'fast', 'leap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['peap', 'ttls']); + slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['peap', 'tls', 'ttls']); + if (superSelect.value != '802eap') { + changeAndroidWifiPolicy(superSelect); + } +}; + +/** + * Method to slide down a provided pane upon provided value set. + * + * @param selectElement Select HTML Element to consider + * @param paneID HTML ID of div element to slide down + * @param valueSet Applicable Value Set + */ +var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) { + var selectedValueOnChange = $(selectElement).find("option:selected").val(); + if ($(selectElement).is("input:checkbox")) { + selectedValueOnChange = $(selectElement).is(":checked").toString(); + } + + var i, slideDownVotes = 0; + for (i = 0; i < valueSet.length; i++) { + if (selectedValueOnChange == valueSet[i]) { + slideDownVotes++; + } + } + var paneSelector = "#" + paneID; + if (slideDownVotes > 0) { + if (!$(paneSelector).hasClass("expanded")) { + $(paneSelector).addClass("expanded"); + } + $(paneSelector).slideDown(); + } else { + if ($(paneSelector).hasClass("expanded")) { + $(paneSelector).removeClass("expanded"); + } + $(paneSelector).slideUp(); + /** now follows the code to reinitialize all inputs of the slidable pane */ + // reinitializing input fields into the defaults + $(paneSelector + " input").each( + function () { + if ($(this).is("input:text")) { + $(this).val($(this).data("default")); + } else if ($(this).is("input:password")) { + $(this).val(""); + } else if ($(this).is("input:checkbox")) { + $(this).prop("checked", $(this).data("default")); + // if this checkbox is the parent input of a grouped-input + if ($(this).hasClass("parent-input")) { + var groupedInput = $(this).parent().parent().parent(); + updateGroupedInputVisibility(groupedInput); + } + } + } + ); + // reinitializing select fields into the defaults + $(paneSelector + " select").each( + function () { + var defaultOption = $(this).data("default"); + $("option:eq(" + defaultOption + ")", this).prop("selected", "selected"); + } + ); + // collapsing expanded-panes (upon the selection of html-select-options) if any + $(paneSelector + " .expanded").each( + function () { + if ($(this).hasClass("expanded")) { + $(this).removeClass("expanded"); + } + $(this).slideUp(); + } + ); + // removing all entries of grid-input elements if exist + $(paneSelector + " .grouped-array-input").each( + function () { + var gridInputs = $(this).find("[data-add-form-clone]"); + if (gridInputs.length > 0) { + gridInputs.remove(); + } + var helpTexts = $(this).find("[data-help-text=add-form]"); + if (helpTexts.length > 0) { + helpTexts.show(); + } + } + ); + } +}; +// End of HTML embedded invoke methods + + +// Start of functions related to grid-input-view + +/** + * Method to set count id to cloned elements. + * @param {object} addFormContainer + */ +var setId = function (addFormContainer) { + $(addFormContainer).find("[data-add-form-clone]").each(function (i) { + $(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1)); + if ($(this).find(".index").length > 0) { + $(this).find(".index").html(i + 1); + } + }); +}; + +/** + * Method to set count id to cloned elements. + * @param {object} addFormContainer + */ +var showHideHelpText = function (addFormContainer) { + var helpText = "[data-help-text=add-form]"; + if ($(addFormContainer).find("[data-add-form-clone]").length > 0) { + $(addFormContainer).find(helpText).hide(); + } else { + $(addFormContainer).find(helpText).show(); + } +}; + +$(document).ready(function () { + // Maintains an array of configured features of the profile + var advanceOperations = ".wr-advance-operations"; + $(advanceOperations).on("click", ".wr-input-control.switch", function (event) { + var operationCode = $(this).parents(".operation-data").data("operation-code"); + var operation = $(this).parents(".operation-data").data("operation"); + var operationDataWrapper = $(this).data("target"); + // prevents event bubbling by figuring out what element it's being called from. + if (event.target.tagName == "INPUT") { + var featureConfiguredIcon; + if ($("input[type='checkbox']", this).is(":checked")) { + configuredOperations.push(operationCode); + // when a feature is enabled, if "zero-configured-features" msg is available, hide that. + var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg"; + if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) { + $(zeroConfiguredOperationsErrorMsg).addClass("hidden"); + } + // add configured-state-icon to the feature + featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).removeClass("hidden"); + } + } else { + //splicing the array if operation is present. + var index = $.inArray(operationCode, configuredOperations); + if (index != -1) { + configuredOperations.splice(index, 1); + } + // when a feature is disabled, clearing all its current configured, error or success states + var subErrorMsgWrapper = "#" + operation + "-feature-error-msg"; + var subErrorIcon = "#" + operation + "-error"; + var subOkIcon = "#" + operation + "-ok"; + featureConfiguredIcon = "#" + operation + "-configured"; + + if (!$(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).addClass("hidden"); + } + if (!$(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).addClass("hidden"); + } + if (!$(subOkIcon).hasClass("hidden")) { + $(subOkIcon).addClass("hidden"); + } + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // reinitializing input fields into the defaults + $(operationDataWrapper + " input").each( + function () { + if ($(this).is("input:text")) { + $(this).val($(this).data("default")); + } else if ($(this).is("input:password")) { + $(this).val(""); + } else if ($(this).is("input:checkbox")) { + $(this).prop("checked", $(this).data("default")); + // if this checkbox is the parent input of a grouped-input + if ($(this).hasClass("parent-input")) { + var groupedInput = $(this).parent().parent().parent(); + updateGroupedInputVisibility(groupedInput); + } + } + } + ); + // reinitializing select fields into the defaults + $(operationDataWrapper + " select").each( + function () { + var defaultOption = $(this).data("default"); + $("option:eq(" + defaultOption + ")", this).prop("selected", "selected"); + } + ); + // collapsing expanded-panes (upon the selection of html-select-options) if any + $(operationDataWrapper + " .expanded").each( + function () { + if ($(this).hasClass("expanded")) { + $(this).removeClass("expanded"); + } + $(this).slideUp(); + } + ); + // removing all entries of grid-input elements if exist + $(operationDataWrapper + " .grouped-array-input").each( + function () { + var gridInputs = $(this).find("[data-add-form-clone]"); + if (gridInputs.length > 0) { + gridInputs.remove(); + } + var helpTexts = $(this).find("[data-help-text=add-form]"); + if (helpTexts.length > 0) { + helpTexts.show(); + } + } + ); + } + } + }); + + // + $(advanceOperations).on('hidden.bs.collapse', function (event) { + var collapsedFeatureBody = event.target.id; + var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-")); + var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]"; + var featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguringSwitch).prop("checked") == true) { + $(featureConfiguringSwitch).prop("checked", false); + } + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + }); + + $(advanceOperations).on('shown.bs.collapse', function (event) { + var expandedFeatureBody = event.target.id; + var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-")); + var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]"; + var featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguringSwitch).prop("checked") == false) { + $(featureConfiguringSwitch).prop("checked", true); + } + if ($(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).removeClass("hidden"); + } + }); + // + + // adding support for cloning multiple profiles per feature with cloneable class definitions + $(advanceOperations).on("click", ".multi-view.add.enabled", function () { + // get a copy of .cloneable and create new .cloned div element + var cloned = "

" + $(".cloneable", $(this).parent().parent()).html() + "
"; + // append newly created .cloned div element to panel-body + $(this).parent().parent().append(cloned); + // enable remove action of newly cloned div element + $(".cloned", $(this).parent().parent()).each( + function () { + if ($(".multi-view.remove", this).hasClass("disabled")) { + $(".multi-view.remove", this).removeClass("disabled"); + } + if (!$(".multi-view.remove", this).hasClass("enabled")) { + $(".multi-view.remove", this).addClass("enabled"); + } + } + ); + }); + + $(advanceOperations).on("click", ".multi-view.remove.enabled", function () { + $(this).parent().remove(); + }); + + // enabling or disabling grouped-input based on the status of a parent check-box + $(advanceOperations).on("click", ".grouped-input", function () { + updateGroupedInputVisibility(this); + }); + + // add form entry click function for grid inputs + $(advanceOperations).on("click", "[data-click-event=add-form]", function () { + var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]"); + var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().find("[data-add-form-element=clone]") + .attr("data-add-form-clone", $(this).attr("href")); + + // adding class .child-input to capture text-input-array-values + $("input, select", clonedForm).addClass("child-input"); + + $(addFormContainer).append(clonedForm); + setId(addFormContainer); + showHideHelpText(addFormContainer); + }); + + // remove form entry click function for grid inputs + $(advanceOperations).on("click", "[data-click-event=remove-form]", function () { + var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]"); + + $(this).closest("[data-add-form-element=clone]").remove(); + setId(addFormContainer); + showHideHelpText(addFormContainer); + }); +}); diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/templates/android-policy-edit.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/templates/android-policy-edit.hbs new file mode 100644 index 0000000000..69b165900c --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-edit/public/templates/android-policy-edit.hbs @@ -0,0 +1,1464 @@ +{{! + 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. +}} +
+ + +
+ +
+
+ +
+
+ + +
+ +
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+ +
+
+
+
+
+ + + +
+
+ +
+ + + Un-check following checkbox in case you do not need the device to be encrypted. +
+
+
+ +
+
+
+
+
+ + + +
+
+ +
+
+ Please note that * sign represents required fields of data. +
+
+ +
+ + + +
+
+ + +
+ + + + + + + + + +
+
+
+ + + +
+
+ +
+
+ + + + + +
+ +
+ + + + + + + Add Application + +
+ + + + + + + + + + + + + + +
No:Application Name/DescriptionPackage Name
+ No entries added yet . +
+ + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+
+ Please note that * sign represents required fields of data. +
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + + +
+
+ +
+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + + + +
+
diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/policy-wizard.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/policy-wizard.hbs index 8d2cbf4d53..fbd9fb6d04 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/policy-wizard.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/policy-wizard.hbs @@ -1,29 +1,18 @@ -
-
-

ADD POLICY

-
-
-
-
-
-

Step 2: Configure profile

-
- -
-
-
- - Loading platform features . . . -

-
-
-
- Back - Continue -
-
-
-
-
\ No newline at end of file +{{! + 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. +}} +{{unit "cdmf.unit.policy.create"}} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/js/android-policy-operations.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/js/android-policy-operations.js new file mode 100644 index 0000000000..0853791071 --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/js/android-policy-operations.js @@ -0,0 +1,842 @@ +/* + * 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. + */ + +var androidOperationConstants = { + "PASSCODE_POLICY_OPERATION": "passcode-policy", + "PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY", + "CAMERA_OPERATION": "camera", + "CAMERA_OPERATION_CODE": "CAMERA", + "ENCRYPT_STORAGE_OPERATION": "encrypt-storage", + "ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE", + "WIFI_OPERATION": "wifi", + "WIFI_OPERATION_CODE": "WIFI", + "VPN_OPERATION": "vpn", + "VPN_OPERATION_CODE": "VPN", + "APPLICATION_OPERATION": "app-restriction", + "APPLICATION_OPERATION_CODE": "APP-RESTRICTION", + "KIOSK_APPS_CODE": "KIOSK_APPS", + "KIOSK_APPS": "cosu-whitelisted-applications" +}; + +/** + * Method to update the visibility of grouped input. + * @param domElement HTML grouped-input element with class name "grouped-input" + */ +var updateGroupedInputVisibility = function (domElement) { + if ($(".parent-input:first", domElement).is(":checked")) { + if ($(".grouped-child-input:first", domElement).hasClass("disabled")) { + $(".grouped-child-input:first", domElement).removeClass("disabled"); + } + $(".child-input", domElement).each(function () { + $(this).prop('disabled', false); + }); + } else { + if (!$(".grouped-child-input:first", domElement).hasClass("disabled")) { + $(".grouped-child-input:first", domElement).addClass("disabled"); + } + $(".child-input", domElement).each(function () { + $(this).prop('disabled', true); + }); + } +}; + +/** + * Checks if provided number is valid against a range. + * + * @param numberInput Number Input + * @param min Minimum Limit + * @param max Maximum Limit + * @returns {boolean} Returns true if input is within the specified range + */ +var inputIsValidAgainstRange = function (numberInput, min, max) { + return (numberInput == min || (numberInput > min && numberInput < max) || numberInput == max); +}; + +var validatePolicyProfile = function () { + var validationStatusArray = []; + var validationStatus; + var operation; + + // starting validation process and updating validationStatus + if (configuredOperations.length == 0) { + // updating validationStatus + validationStatus = { + "error": true, + "mainErrorMsg": "You cannot continue. Zero configured features." + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } else { + // validating each and every configured Operation + // Validating PASSCODE_POLICY + if ($.inArray(androidOperationConstants["PASSCODE_POLICY_OPERATION_CODE"], configuredOperations) != -1) { + // if PASSCODE_POLICY is configured + operation = androidOperationConstants["PASSCODE_POLICY_OPERATION"]; + // initializing continueToCheckNextInputs to true + var continueToCheckNextInputs = true; + + // validating first input: passcodePolicyMaxPasscodeAgeInDays + var passcodePolicyMaxPasscodeAgeInDays = $("input#passcode-policy-max-passcode-age-in-days").val(); + if (passcodePolicyMaxPasscodeAgeInDays) { + if (!$.isNumeric(passcodePolicyMaxPasscodeAgeInDays)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode age is not a number.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(passcodePolicyMaxPasscodeAgeInDays, 1, 730)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode age is not with in the range of 1-to-730.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + + // validating second and last input: passcodePolicyPasscodeHistory + if (continueToCheckNextInputs) { + var passcodePolicyPasscodeHistory = $("input#passcode-policy-passcode-history").val(); + if (passcodePolicyPasscodeHistory) { + if (!$.isNumeric(passcodePolicyPasscodeHistory)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode history is not a number.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(passcodePolicyPasscodeHistory, 1, 50)) { + validationStatus = { + "error": true, + "subErrorMsg": "Provided passcode history is not with in the range of 1-to-50.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + } + + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating CAMERA + if ($.inArray(androidOperationConstants["CAMERA_OPERATION_CODE"], configuredOperations) != -1) { + // if CAMERA is configured + operation = androidOperationConstants["CAMERA_OPERATION"]; + // updating validationStatus + validationStatus = { + "error": false, + "okFeature": operation + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating ENCRYPT_STORAGE + if ($.inArray(androidOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"], configuredOperations) != -1) { + // if ENCRYPT_STORAGE is configured + operation = androidOperationConstants["ENCRYPT_STORAGE_OPERATION"]; + // updating validationStatus + validationStatus = { + "error": false, + "okFeature": operation + }; + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + // Validating WIFI + if ($.inArray(androidOperationConstants["WIFI_OPERATION_CODE"], configuredOperations) != -1) { + // if WIFI is configured + operation = androidOperationConstants["WIFI_OPERATION"]; + // initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var wifiSSID = $("input#wifi-ssid").val(); + if (!wifiSSID) { + validationStatus = { + "error": true, + "subErrorMsg": "WIFI SSID is not given. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + // For the secure wifi types, it is required to have a password + var wifiTypeUIElement = $("#wifi-type"); + var wifiType = wifiTypeUIElement.find("option:selected").val(); + if (wifiTypeUIElement.is("input:checkbox")) { + wifiType = wifiTypeUIElement.is(":checked").toString(); + } + if (wifiType != "none") { + if (!$("#wifi-password").val()) { + validationStatus = { + "error": true, + "subErrorMsg": "Password is required for the wifi security type " + wifiType + ". " + + "Please provide a password to proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + + if ($.inArray(androidOperationConstants["VPN_OPERATION_CODE"], configuredOperations) != -1) { + // if WIFI is configured + operation = androidOperationConstants["VPN_OPERATION"]; + // initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var serverAddress = $("input#vpn-server-address").val(); + if (!serverAddress) { + validationStatus = { + "error": true, + "subErrorMsg": "Server address is required. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + if (continueToCheckNextInputs) { + var serverPort = $("input#vpn-server-port").val(); + if (!serverPort) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port is required. You cannot proceed.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!$.isNumeric(serverPort)) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port requires a number input.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (!inputIsValidAgainstRange(serverPort, 0, 65535)) { + validationStatus = { + "error": true, + "subErrorMsg": "VPN server port is not within the range " + + "of valid port numbers.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + + // at-last, if the value of continueToCheckNextInputs is still true + // this means that no error is found + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + if ($.inArray(androidOperationConstants["APPLICATION_OPERATION_CODE"], configuredOperations) != -1) { + //If application restriction configured + operation = androidOperationConstants["APPLICATION_OPERATION"]; + // Initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + + var appRestrictionType = $("#app-restriction-type").val(); + + var restrictedApplicationsGridChildInputs = "div#restricted-applications .child-input"; + + if (!appRestrictionType) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications restriction type is not provided.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + if (continueToCheckNextInputs) { + if ($(restrictedApplicationsGridChildInputs).length == 0) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications are not provided in application restriction list.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + else { + childInputCount = 0; + childInputArray = []; + emptyChildInputCount = 0; + duplicatesExist = false; + // Looping through each child input + $(restrictedApplicationsGridChildInputs).each(function () { + childInputCount++; + if (childInputCount % 2 == 0) { + // If child input is of second column + childInput = $(this).val(); + childInputArray.push(childInput); + // Updating emptyChildInputCount + if (!childInput) { + // If child input field is empty + emptyChildInputCount++; + } + } + }); + // Checking for duplicates + initialChildInputArrayLength = childInputArray.length; + if (emptyChildInputCount == 0 && initialChildInputArrayLength > 1) { + for (m = 0; m < (initialChildInputArrayLength - 1); m++) { + poppedChildInput = childInputArray.pop(); + for (n = 0; n < childInputArray.length; n++) { + if (poppedChildInput == childInputArray[n]) { + duplicatesExist = true; + break; + } + } + if (duplicatesExist) { + break; + } + } + } + // Updating validationStatus + if (emptyChildInputCount > 0) { + // If empty child inputs are present + validationStatus = { + "error": true, + "subErrorMsg": "One or more package names of " + + "applications are empty.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (duplicatesExist) { + // If duplicate input is present + validationStatus = { + "error": true, + "subErrorMsg": "Duplicate values exist with " + + "for package names.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + + } + } + + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + + // Updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + if ($.inArray(androidOperationConstants["KIOSK_APPS_CODE"], configuredOperations) != -1) { + //If COSU whitelisting applications configured + operation = androidOperationConstants["KIOSK_APPS"]; + // Initializing continueToCheckNextInputs to true + continueToCheckNextInputs = true; + var whitelistedApplicationsGridChildInputs = "div#cosu-whitelisted-applications .child-input"; + if (continueToCheckNextInputs) { + if ($(whitelistedApplicationsGridChildInputs).length == 0) { + validationStatus = { + "error": true, + "subErrorMsg": "Applications are not provided in application whitelist list.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + else { + childInputCount = 0; + childInputArray = []; + emptyChildInputCount = 0; + duplicatesExist = false; + // Looping through each child input + $(whitelistedApplicationsGridChildInputs).each(function () { + childInputCount++; + if (childInputCount % 2 == 0) { + // If child input is of second column + childInput = $(this).val(); + childInputArray.push(childInput); + // Updating emptyChildInputCount + if (!childInput) { + // If child input field is empty + emptyChildInputCount++; + } + } + }); + // Checking for duplicates + initialChildInputArrayLength = childInputArray.length; + if (emptyChildInputCount == 0 && initialChildInputArrayLength > 1) { + for (m = 0; m < (initialChildInputArrayLength - 1); m++) { + poppedChildInput = childInputArray.pop(); + for (n = 0; n < childInputArray.length; n++) { + if (poppedChildInput == childInputArray[n]) { + duplicatesExist = true; + break; + } + } + if (duplicatesExist) { + break; + } + } + } + // Updating validationStatus + if (emptyChildInputCount > 0) { + // If empty child inputs are present + validationStatus = { + "error": true, + "subErrorMsg": "One or more package names of " + + "applications are empty.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } else if (duplicatesExist) { + // If duplicate input is present + validationStatus = { + "error": true, + "subErrorMsg": "Duplicate values exist with " + + "for package names.", + "erroneousFeature": operation + }; + continueToCheckNextInputs = false; + } + } + } + if (continueToCheckNextInputs) { + validationStatus = { + "error": false, + "okFeature": operation + }; + } + // Updating validationStatusArray with validationStatus + validationStatusArray.push(validationStatus); + } + } + // ending validation process + + // start taking specific notifying actions upon validation + var wizardIsToBeContinued; + var errorCount = 0; + var mainErrorMsgWrapper, mainErrorMsg, + subErrorMsgWrapper, subErrorMsg, subErrorIcon, subOkIcon, featureConfiguredIcon; + var i; + for (i = 0; i < validationStatusArray.length; i++) { + validationStatus = validationStatusArray[i]; + if (validationStatus["error"]) { + errorCount++; + if (validationStatus["mainErrorMsg"]) { + mainErrorMsgWrapper = "#policy-profile-main-error-msg"; + mainErrorMsg = mainErrorMsgWrapper + " span"; + $(mainErrorMsg).text(validationStatus["mainErrorMsg"]); + $(mainErrorMsgWrapper).removeClass("hidden"); + } else if (validationStatus["subErrorMsg"]) { + subErrorMsgWrapper = "#" + validationStatus["erroneousFeature"] + "-feature-error-msg"; + subErrorMsg = subErrorMsgWrapper + " span"; + subErrorIcon = "#" + validationStatus["erroneousFeature"] + "-error"; + subOkIcon = "#" + validationStatus["erroneousFeature"] + "-ok"; + featureConfiguredIcon = "#" + validationStatus["erroneousFeature"] + "-configured"; + // hiding featureConfiguredState as the first step + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // updating error state and corresponding messages + $(subErrorMsg).text(validationStatus["subErrorMsg"]); + if ($(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).removeClass("hidden"); + } + if (!$(subOkIcon).hasClass("hidden")) { + $(subOkIcon).addClass("hidden"); + } + if ($(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).removeClass("hidden"); + } + } + } else { + if (validationStatus["okFeature"]) { + subErrorMsgWrapper = "#" + validationStatus["okFeature"] + "-feature-error-msg"; + subErrorIcon = "#" + validationStatus["okFeature"] + "-error"; + subOkIcon = "#" + validationStatus["okFeature"] + "-ok"; + featureConfiguredIcon = "#" + validationStatus["okFeature"] + "-configured"; + // hiding featureConfiguredState as the first step + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // updating success state and corresponding messages + if (!$(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).addClass("hidden"); + } + if (!$(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).addClass("hidden"); + } + if ($(subOkIcon).hasClass("hidden")) { + $(subOkIcon).removeClass("hidden"); + } + } + } + } + + wizardIsToBeContinued = (errorCount == 0); + return wizardIsToBeContinued; +}; + +// Start of HTML embedded invoke methods +var showAdvanceOperation = function (operation, button) { + $(button).addClass('selected'); + $(button).siblings().removeClass('selected'); + var hiddenOperation = ".wr-hidden-operations-content > div"; + $(hiddenOperation + '[data-operation="' + operation + '"]').show(); + $(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide(); +}; + + +/** + * This method will display appropriate fields based on wifi type + * @param select + */ +var changeAndroidWifiPolicy = function (select) { + slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['wep', 'wpa', '802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-eap', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['802eap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['802eap']); +}; + +/** + * This method will display appropriate fields based on wifi EAP type + * @param select + * @param superSelect + */ +var changeAndroidWifiPolicyEAP = function (select, superSelect) { + slideDownPaneAgainstValueSet(select, 'control-wifi-password', ['peap', 'ttls', 'pwd', 'fast', 'leap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-phase2', ['peap', 'ttls', 'fast']); + slideDownPaneAgainstValueSet(select, 'control-wifi-provisioning', ['fast']); + slideDownPaneAgainstValueSet(select, 'control-wifi-identity', ['peap', 'tls', 'ttls', 'pwd', 'fast', 'leap']); + slideDownPaneAgainstValueSet(select, 'control-wifi-anoidentity', ['peap', 'ttls']); + slideDownPaneAgainstValueSet(select, 'control-wifi-cacert', ['peap', 'tls', 'ttls']); + if (superSelect.value != '802eap') { + changeAndroidWifiPolicy(superSelect); + } +}; + +/** + * Method to slide down a provided pane upon provided value set. + * + * @param selectElement Select HTML Element to consider + * @param paneID HTML ID of div element to slide down + * @param valueSet Applicable Value Set + */ +var slideDownPaneAgainstValueSet = function (selectElement, paneID, valueSet) { + var selectedValueOnChange = $(selectElement).find("option:selected").val(); + if ($(selectElement).is("input:checkbox")) { + selectedValueOnChange = $(selectElement).is(":checked").toString(); + } + + var i, slideDownVotes = 0; + for (i = 0; i < valueSet.length; i++) { + if (selectedValueOnChange == valueSet[i]) { + slideDownVotes++; + } + } + var paneSelector = "#" + paneID; + if (slideDownVotes > 0) { + if (!$(paneSelector).hasClass("expanded")) { + $(paneSelector).addClass("expanded"); + } + $(paneSelector).slideDown(); + } else { + if ($(paneSelector).hasClass("expanded")) { + $(paneSelector).removeClass("expanded"); + } + $(paneSelector).slideUp(); + /** now follows the code to reinitialize all inputs of the slidable pane */ + // reinitializing input fields into the defaults + $(paneSelector + " input").each( + function () { + if ($(this).is("input:text")) { + $(this).val($(this).data("default")); + } else if ($(this).is("input:password")) { + $(this).val(""); + } else if ($(this).is("input:checkbox")) { + $(this).prop("checked", $(this).data("default")); + // if this checkbox is the parent input of a grouped-input + if ($(this).hasClass("parent-input")) { + var groupedInput = $(this).parent().parent().parent(); + updateGroupedInputVisibility(groupedInput); + } + } + } + ); + // reinitializing select fields into the defaults + $(paneSelector + " select").each( + function () { + var defaultOption = $(this).data("default"); + $("option:eq(" + defaultOption + ")", this).prop("selected", "selected"); + } + ); + // collapsing expanded-panes (upon the selection of html-select-options) if any + $(paneSelector + " .expanded").each( + function () { + if ($(this).hasClass("expanded")) { + $(this).removeClass("expanded"); + } + $(this).slideUp(); + } + ); + // removing all entries of grid-input elements if exist + $(paneSelector + " .grouped-array-input").each( + function () { + var gridInputs = $(this).find("[data-add-form-clone]"); + if (gridInputs.length > 0) { + gridInputs.remove(); + } + var helpTexts = $(this).find("[data-help-text=add-form]"); + if (helpTexts.length > 0) { + helpTexts.show(); + } + } + ); + } +}; +// End of HTML embedded invoke methods + + +// Start of functions related to grid-input-view + +/** + * Method to set count id to cloned elements. + * @param {object} addFormContainer + */ +var setId = function (addFormContainer) { + $(addFormContainer).find("[data-add-form-clone]").each(function (i) { + $(this).attr("id", $(this).attr("data-add-form-clone").slice(1) + "-" + (i + 1)); + if ($(this).find(".index").length > 0) { + $(this).find(".index").html(i + 1); + } + }); +}; + +/** + * Method to set count id to cloned elements. + * @param {object} addFormContainer + */ +var showHideHelpText = function (addFormContainer) { + var helpText = "[data-help-text=add-form]"; + if ($(addFormContainer).find("[data-add-form-clone]").length > 0) { + $(addFormContainer).find(helpText).hide(); + } else { + $(addFormContainer).find(helpText).show(); + } +}; + +$(document).ready(function () { + // Maintains an array of configured features of the profile + var advanceOperations = ".wr-advance-operations"; + $(advanceOperations).on("click", ".wr-input-control.switch", function (event) { + var operationCode = $(this).parents(".operation-data").data("operation-code"); + var operation = $(this).parents(".operation-data").data("operation"); + var operationDataWrapper = $(this).data("target"); + // prevents event bubbling by figuring out what element it's being called from. + if (event.target.tagName == "INPUT") { + var featureConfiguredIcon; + if ($("input[type='checkbox']", this).is(":checked")) { + configuredOperations.push(operationCode); + // when a feature is enabled, if "zero-configured-features" msg is available, hide that. + var zeroConfiguredOperationsErrorMsg = "#policy-profile-main-error-msg"; + if (!$(zeroConfiguredOperationsErrorMsg).hasClass("hidden")) { + $(zeroConfiguredOperationsErrorMsg).addClass("hidden"); + } + // add configured-state-icon to the feature + featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).removeClass("hidden"); + } + } else { + //splicing the array if operation is present. + var index = $.inArray(operationCode, configuredOperations); + if (index != -1) { + configuredOperations.splice(index, 1); + } + // when a feature is disabled, clearing all its current configured, error or success states + var subErrorMsgWrapper = "#" + operation + "-feature-error-msg"; + var subErrorIcon = "#" + operation + "-error"; + var subOkIcon = "#" + operation + "-ok"; + featureConfiguredIcon = "#" + operation + "-configured"; + + if (!$(subErrorMsgWrapper).hasClass("hidden")) { + $(subErrorMsgWrapper).addClass("hidden"); + } + if (!$(subErrorIcon).hasClass("hidden")) { + $(subErrorIcon).addClass("hidden"); + } + if (!$(subOkIcon).hasClass("hidden")) { + $(subOkIcon).addClass("hidden"); + } + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + // reinitializing input fields into the defaults + $(operationDataWrapper + " input").each( + function () { + if ($(this).is("input:text")) { + $(this).val($(this).data("default")); + } else if ($(this).is("input:password")) { + $(this).val(""); + } else if ($(this).is("input:checkbox")) { + $(this).prop("checked", $(this).data("default")); + // if this checkbox is the parent input of a grouped-input + if ($(this).hasClass("parent-input")) { + var groupedInput = $(this).parent().parent().parent(); + updateGroupedInputVisibility(groupedInput); + } + } + } + ); + // reinitializing select fields into the defaults + $(operationDataWrapper + " select").each( + function () { + var defaultOption = $(this).data("default"); + $("option:eq(" + defaultOption + ")", this).prop("selected", "selected"); + } + ); + // collapsing expanded-panes (upon the selection of html-select-options) if any + $(operationDataWrapper + " .expanded").each( + function () { + if ($(this).hasClass("expanded")) { + $(this).removeClass("expanded"); + } + $(this).slideUp(); + } + ); + // removing all entries of grid-input elements if exist + $(operationDataWrapper + " .grouped-array-input").each( + function () { + var gridInputs = $(this).find("[data-add-form-clone]"); + if (gridInputs.length > 0) { + gridInputs.remove(); + } + var helpTexts = $(this).find("[data-help-text=add-form]"); + if (helpTexts.length > 0) { + helpTexts.show(); + } + } + ); + } + } + }); + + // + $(advanceOperations).on('hidden.bs.collapse', function (event) { + var collapsedFeatureBody = event.target.id; + var operation = collapsedFeatureBody.substr(0, collapsedFeatureBody.lastIndexOf("-")); + var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]"; + var featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguringSwitch).prop("checked") == true) { + $(featureConfiguringSwitch).prop("checked", false); + } + if (!$(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).addClass("hidden"); + } + }); + + $(advanceOperations).on('shown.bs.collapse', function (event) { + var expandedFeatureBody = event.target.id; + var operation = expandedFeatureBody.substr(0, expandedFeatureBody.lastIndexOf("-")); + var featureConfiguringSwitch = "#" + operation + "-heading input[type=checkbox]"; + var featureConfiguredIcon = "#" + operation + "-configured"; + if ($(featureConfiguringSwitch).prop("checked") == false) { + $(featureConfiguringSwitch).prop("checked", true); + } + if ($(featureConfiguredIcon).hasClass("hidden")) { + $(featureConfiguredIcon).removeClass("hidden"); + } + }); + // + + // adding support for cloning multiple profiles per feature with cloneable class definitions + $(advanceOperations).on("click", ".multi-view.add.enabled", function () { + // get a copy of .cloneable and create new .cloned div element + var cloned = "

" + $(".cloneable", $(this).parent().parent()).html() + "
"; + // append newly created .cloned div element to panel-body + $(this).parent().parent().append(cloned); + // enable remove action of newly cloned div element + $(".cloned", $(this).parent().parent()).each( + function () { + if ($(".multi-view.remove", this).hasClass("disabled")) { + $(".multi-view.remove", this).removeClass("disabled"); + } + if (!$(".multi-view.remove", this).hasClass("enabled")) { + $(".multi-view.remove", this).addClass("enabled"); + } + } + ); + }); + + $(advanceOperations).on("click", ".multi-view.remove.enabled", function () { + $(this).parent().remove(); + }); + + // enabling or disabling grouped-input based on the status of a parent check-box + $(advanceOperations).on("click", ".grouped-input", function () { + updateGroupedInputVisibility(this); + }); + + // add form entry click function for grid inputs + $(advanceOperations).on("click", "[data-click-event=add-form]", function () { + var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]"); + var clonedForm = $("[data-add-form=" + $(this).attr("href") + "]").clone().find("[data-add-form-element=clone]") + .attr("data-add-form-clone", $(this).attr("href")); + + // adding class .child-input to capture text-input-array-values + $("input, select", clonedForm).addClass("child-input"); + + $(addFormContainer).append(clonedForm); + setId(addFormContainer); + showHideHelpText(addFormContainer); + }); + + // remove form entry click function for grid inputs + $(advanceOperations).on("click", "[data-click-event=remove-form]", function () { + var addFormContainer = $("[data-add-form-container=" + $(this).attr("href") + "]"); + + $(this).closest("[data-add-form-element=clone]").remove(); + setId(addFormContainer); + showHideHelpText(addFormContainer); + }); +}); \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/templates/android-policy-operations.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/templates/android-policy-operations.hbs new file mode 100644 index 0000000000..9ad80d134b --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.policy-wizard/public/templates/android-policy-operations.hbs @@ -0,0 +1,1464 @@ +{{! + 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. +}} +
+ + +
+ +
+
+ +
+
+ + +
+ +
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ + + +
+
+ +
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+ +
+
+
+
+
+ + + +
+
+ +
+ + + Un-check following checkbox in case you do not need the device to be encrypted. +
+
+
+ +
+
+
+
+
+ + + +
+
+ +
+
+ Please note that * sign represents required fields of data. +
+
+ +
+ + + +
+
+ + +
+ + + + + + + + + +
+
+
+ + + +
+
+ +
+
+ + + + + +
+ +
+ + + + + + + Add Application + +
+ + + + + + + + + + + + + + +
No:Application Name/DescriptionPackage Name
+ No entries added yet . +
+ + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+
+ Please note that * sign represents required fields of data. +
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + + +
+
+ +
+
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + + + +
+
\ No newline at end of file From 1038c23c983c9dc1216415a4c293729efb88b877 Mon Sep 17 00:00:00 2001 From: Hasunie Date: Tue, 29 Nov 2016 11:24:22 +0530 Subject: [PATCH 02/10] adding windows qr-code scanner --- .../qr-modal.hbs | 64 ++++++++++++++ .../qr-modal.js | 23 +++++ .../qr-modal.json | 3 + .../type-view.hbs | 88 +++++-------------- 4 files changed, 113 insertions(+), 65 deletions(-) create mode 100644 components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.hbs create mode 100644 components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.js create mode 100644 components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.json diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.hbs b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.hbs new file mode 100644 index 0000000000..544dc23d75 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.hbs @@ -0,0 +1,64 @@ +{{! + 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. +}} +{{#zone "content"}} + +{{/zone}} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.js b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.js new file mode 100644 index 0000000000..5177e51f38 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.js @@ -0,0 +1,23 @@ +/* + * 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. + */ + +function onRequest() { + var mdmProps = require("/app/modules/conf-reader/main.js")["conf"]; + var viewModel = {}; + //TODO: Move enrollment URL into app-conf.json + viewModel["enrollmentURL"] = mdmProps["generalConfig"]["host"] + mdmProps["windowsEnrollmentDir"]; + return viewModel; +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.json b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.json new file mode 100644 index 0000000000..688e939808 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.qr-modal/qr-modal.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.type-view/type-view.hbs b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.type-view/type-view.hbs index e4199de38a..ed4654d774 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.type-view/type-view.hbs +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.type-view/type-view.hbs @@ -1,22 +1,8 @@ -{{! - Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +{{unit "cdmf.unit.lib.qrcode"}} +{{unit "cdmf.unit.device.type.windows.qr-modal"}} - 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. -}}
-

Windows Mobile

+

Windows Mobile


@@ -24,39 +10,39 @@
- +

What it Does

-
-

Connect and manage your Windows device with WSO2 IoT Server.

+
+

Connect and manage your Android device with WSO2 IoT Server.


What You Need


    -
  • STEP 01 Windows Mobile.
  • -
  • STEP 02 Go ahead and click [Enroll Device]. +
  • STEP 01 Windows + Mobile.
  • -
  • STEP 03 Proceed to [Prepare] section. +
  • STEP 02 Go ahead + and click [Enroll Device]. +
  • +
  • STEP 03 Proceed + to the [Prepare] section.

- - - Enroll Device - -

+ Enroll Device +

-

Prepare

-
+

Prepare


    -
  • 01 Scan QR code.
  • +
  • 01 Scan QR code..
  • 02 Follow instructions in wizard.
  • 03 Configure your workspace account
@@ -73,40 +59,12 @@
-
- - - -{{#zone "bottomJs"}} - -{{/zone}} +
{{#zone "topCss"}} {{css "css/styles.css"}} +{{/zone}} + +{{#zone "bottomJs"}} + {{js "js/type-view.js"}} {{/zone}} \ No newline at end of file From b3a7ed91c00a35a98fc2e0caeebe8009720a389a Mon Sep 17 00:00:00 2001 From: GPrathap Date: Wed, 30 Nov 2016 12:50:50 +0530 Subject: [PATCH 03/10] oauth token retrieval mechanism changed Now oauth token is taken from http cookie --- .../endpoint/HttpSessionConfigurator.java | 36 ++++++++++++++ .../SuperTenantSubscriptionEndpoint.java | 14 ++++-- .../endpoint/TenantSubscriptionEndpoint.java | 21 ++++---- .../endpoint/constants/Constants.java | 25 ++++++++++ .../authentication/Authenticator.java | 7 +-- .../authentication/OAuthAuthenticator.java | 9 ++-- .../oauth/OAuthTokenValdiator.java | 48 ++++++++----------- 7 files changed, 114 insertions(+), 46 deletions(-) create mode 100644 components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/HttpSessionConfigurator.java create mode 100644 components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/HttpSessionConfigurator.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/HttpSessionConfigurator.java new file mode 100644 index 0000000000..a38a5e6352 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/HttpSessionConfigurator.java @@ -0,0 +1,36 @@ +/* + * + * 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.device.mgt.output.adapter.websocket.endpoint; + +import org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.constants.Constants; + +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; +import java.util.List; +import java.util.Map; + +public class HttpSessionConfigurator extends ServerEndpointConfig.Configurator { + public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { + Map> httpHeaders = request.getHeaders(); + config.getUserProperties().put(Constants.HTTP_HEADERS, httpHeaders); + } +} diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java index 53b40d1baa..5eac9280eb 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java @@ -24,24 +24,28 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.Authenticator; import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.Authorizer; +import org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.constants.Constants; import org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.util.ServiceHolder; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; -import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; +import java.util.List; +import java.util.Map; /** * Connect to web socket with Super tenant */ -@ServerEndpoint(value = "/{streamname}/{version}") +@ServerEndpoint(value = "/{streamname}/{version}", configurator = HttpSessionConfigurator.class) public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint { private static final Log log = LogFactory.getLog(SuperTenantSubscriptionEndpoint.class); @@ -54,13 +58,15 @@ public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint { * @param version - Version extracted from the ws url. */ @OnOpen - public void onOpen(Session session, @PathParam("streamname") String streamName, + public void onOpen(Session session, EndpointConfig config, @PathParam("streamname") String streamName, @PathParam("version") String version) { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: " + session.getId() + ", for the Stream:" + streamName); } + Map> httpHeaders; + httpHeaders = (Map>) config.getUserProperties().get(Constants.HTTP_HEADERS); Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); - AuthenticationInfo authenticationInfo = authenticator.isAutenticated(session); + AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(httpHeaders); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java index 553cdcbea6..9243498a1b 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java @@ -24,23 +24,27 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.AuthenticationInfo; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.Authenticator; import org.wso2.carbon.device.mgt.output.adapter.websocket.authorization.Authorizer; +import org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.constants.Constants; import org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.util.ServiceHolder; import javax.websocket.CloseReason; +import javax.websocket.EndpointConfig; +import javax.websocket.Session; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; -import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; +import java.util.List; +import java.util.Map; /** * Connect to web socket with a tenant */ -@ServerEndpoint(value = "/t/{tdomain}/{streamname}/{version}") +@ServerEndpoint(value = "/t/{tdomain}/{streamname}/{version}", configurator = HttpSessionConfigurator.class) public class TenantSubscriptionEndpoint extends SubscriptionEndpoint { private static final Log log = LogFactory.getLog(TenantSubscriptionEndpoint.class); @@ -54,13 +58,15 @@ public class TenantSubscriptionEndpoint extends SubscriptionEndpoint { * @param tdomain - Tenant domain extracted from ws url. */ @OnOpen - public void onOpen (Session session, @PathParam("streamname") String streamName , - @PathParam("version") String version, @PathParam("tdomain") String tdomain) { + public void onOpen (Session session, EndpointConfig config, @PathParam("streamname") String streamName , + @PathParam("version") String version, @PathParam("tdomain") String tdomain) { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: "+session.getId()+", for the Stream:"+streamName); } + Map> httpHeaders; + httpHeaders = (Map>) config.getUserProperties().get(Constants.HTTP_HEADERS); Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); - AuthenticationInfo authenticationInfo = authenticator.isAutenticated(session); + AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(httpHeaders); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); @@ -68,9 +74,8 @@ public class TenantSubscriptionEndpoint extends SubscriptionEndpoint { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tdomain, true); - ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName, - version, - session); + ServiceHolder.getInstance().getUiOutputCallbackControllerService().subscribeWebsocket(streamName + , version, session); } finally { PrivilegedCarbonContext.endTenantFlow(); } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java new file mode 100644 index 0000000000..14b4e968c5 --- /dev/null +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java @@ -0,0 +1,25 @@ +/* + * + * 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.device.mgt.output.adapter.websocket.endpoint.constants; + +public class Constants { + public static final String HTTP_HEADERS = "HttpHeaders"; +} diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/Authenticator.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/Authenticator.java index a9a5dc07b1..d1d06cc5c9 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/Authenticator.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/Authenticator.java @@ -14,7 +14,8 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.authentication; -import javax.websocket.Session; +import java.util.List; +import java.util.Map; /** * This interface is used to authenticate a websocket session @@ -24,7 +25,7 @@ public interface Authenticator { /** * Check whether the client is authenticated to connect. * @param session user object. - * @return AuthenicationInfo which contains authentication client information. + * @return AuthenticationInfo which contains authentication client information. */ - AuthenticationInfo isAutenticated(Session session); + AuthenticationInfo isAuthenticated(Map> webSocketConnectionProperties); } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/OAuthAuthenticator.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/OAuthAuthenticator.java index 7eaab2b5bb..698f4f8261 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/OAuthAuthenticator.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/OAuthAuthenticator.java @@ -15,12 +15,13 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.authentication; import org.wso2.carbon.device.mgt.output.adapter.websocket.authentication.oauth.OAuthTokenValdiator; -import javax.websocket.Session; + +import java.util.List; +import java.util.Map; public class OAuthAuthenticator implements Authenticator { - @Override - public AuthenticationInfo isAutenticated(Session session) { - return OAuthTokenValdiator.getInstance().validateToken(session); + public AuthenticationInfo isAuthenticated(Map> webSocketConnectionProperties) { + return OAuthTokenValdiator.getInstance().validateToken(webSocketConnectionProperties); } } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java index 5c55a5c217..b92f08ae09 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java @@ -31,7 +31,6 @@ import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; -import javax.websocket.Session; import java.io.File; import java.io.IOException; import java.rmi.RemoteException; @@ -50,10 +49,11 @@ public class OAuthTokenValdiator { private static Log log = LogFactory.getLog(OAuthTokenValdiator.class); private static final String WEBSOCKET_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "websocket-validation.properties"; - private static final String QUERY_STRING_SEPERATOR = "&"; - private static final String QUERY_KEY_VALUE_SEPERATOR = "="; + private static final String COOKIE_KEY_VALUE_SEPERATOR = "="; + private static final String COOKIE_KEYPAIR_SEPERATOR = ";"; + private static final String COOKIE = "cookie"; private static final String TOKEN_TYPE = "bearer"; - private static final String TOKEN_IDENTIFIER = "token"; + private static final String TOKEN_IDENTIFIER = "websocket-token"; private static OAuthTokenValdiator oAuthTokenValdiator; public static OAuthTokenValdiator getInstance() { @@ -79,12 +79,11 @@ public class OAuthTokenValdiator { /** * This method gets a string accessToken and validates it - * - * @param session which need to be validated. + * @param webSocketConnectionProperties WebSocket connection information including http headers * @return AuthenticationInfo with the validated results. */ - public AuthenticationInfo validateToken(Session session) { - String token = getTokenFromSession(session); + public AuthenticationInfo validateToken(Map> webSocketConnectionProperties) { + String token = getToken(webSocketConnectionProperties); if (token == null) { AuthenticationInfo authenticationInfo = new AuthenticationInfo(); authenticationInfo.setAuthenticated(false); @@ -189,26 +188,21 @@ public class OAuthTokenValdiator { } /** - * @param session of the user. - * @return retreive the token from the query string + * Retrieving the token from the http header + * @param webSocketConnectionProperties WebSocket connection information including http headers + * @return retrieved token */ - private String getTokenFromSession(Session session) { - String queryString = session.getQueryString(); - if (queryString != null) { - String[] allQueryParamPairs = queryString.split(QUERY_STRING_SEPERATOR); - - for (String keyValuePair : allQueryParamPairs) { - String[] queryParamPair = keyValuePair.split(QUERY_KEY_VALUE_SEPERATOR); - - if (queryParamPair.length != 2) { - log.warn("Invalid query string [" + queryString + "] passed in."); - break; - } - if (queryParamPair[0].equals(TOKEN_IDENTIFIER)) { - return queryParamPair[1]; - } - } - } + private String getToken(Map> webSocketConnectionProperties) { + String cookieString = webSocketConnectionProperties.get(COOKIE).get(0); + String[] properties = cookieString.split(COOKIE_KEYPAIR_SEPERATOR); + String token; + for (String keyValuePair: properties) { + if(TOKEN_IDENTIFIER.equals((keyValuePair.split(COOKIE_KEY_VALUE_SEPERATOR)[0]).trim())){ + token = (keyValuePair.split(COOKIE_KEY_VALUE_SEPERATOR)[1]).trim(); + return token; + } + } + log.error("WebSocket token should be specified in cookie"); return null; } } From 00a12f3ae1618847236b31ab6c8844af1c24112e Mon Sep 17 00:00:00 2001 From: GPrathap Date: Wed, 30 Nov 2016 12:52:51 +0530 Subject: [PATCH 04/10] removed oauth token sending as query param --- .../analytics-view.js | 26 +++++++++++++------ .../analytics-view.js | 26 +++++++++++++------ .../analytics-view.js | 26 ++++++++++++------- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js index 1c2d56a56a..e54cef4ec4 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js @@ -18,17 +18,27 @@ function onRequest(context) { var log = new Log("stats.js"); + var carbonServer = require("carbon").server; var device = context.unit.params.device; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var constants = require("/app/modules/constants.js"); - var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss"); - var tokenPair = session.get(constants["TOKEN_PAIR"]); - if (tokenPair) { - var token = parse(tokenPair)["accessToken"]; - websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + - "token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - } - + var jwtService = carbonServer.osgiService( + 'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService'); + var jwtClient = jwtService.getJWTClient(); + var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]); + var token = ""; + if (encodedClientKeys) { + var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; + var resp = tokenUtil.decode(encodedClientKeys).split(":"); + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } + websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; + var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; + response.addCookie(websocketToken); + } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js index 1c2d56a56a..e54cef4ec4 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js @@ -18,17 +18,27 @@ function onRequest(context) { var log = new Log("stats.js"); + var carbonServer = require("carbon").server; var device = context.unit.params.device; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var constants = require("/app/modules/constants.js"); - var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss"); - var tokenPair = session.get(constants["TOKEN_PAIR"]); - if (tokenPair) { - var token = parse(tokenPair)["accessToken"]; - websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + - "token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - } - + var jwtService = carbonServer.osgiService( + 'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService'); + var jwtClient = jwtService.getJWTClient(); + var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]); + var token = ""; + if (encodedClientKeys) { + var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; + var resp = tokenUtil.decode(encodedClientKeys).split(":"); + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } + websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; + var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; + response.addCookie(websocketToken); + } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js index fa9e138d00..e54cef4ec4 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js @@ -22,15 +22,23 @@ function onRequest(context) { var device = context.unit.params.device; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var constants = require("/app/modules/constants.js"); - var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss"); - - var tokenPair = session.get(constants["TOKEN_PAIR"]); - if (tokenPair) { - var token = parse(tokenPair)["accessToken"]; - websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + - "token=" + token + "&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - } - + var jwtService = carbonServer.osgiService( + 'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService'); + var jwtClient = jwtService.getJWTClient(); + var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]); + var token = ""; + if (encodedClientKeys) { + var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; + var resp = tokenUtil.decode(encodedClientKeys).split(":"); + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } + websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; + var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; + response.addCookie(websocketToken); + } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file From ab418dbde37f4569963ac86cf7d718d7e6ed4843 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Wed, 30 Nov 2016 14:55:53 +0530 Subject: [PATCH 05/10] Add new sensors to the android sense plugin Incoming and outgoing calls tracker Screen on off detector SMS tracker Audio playing and headset tracker Application install and uninstall detector User activity detector --- .../app/build.gradle | 1 + .../app/src/main/AndroidManifest.xml | 18 +- .../data/publisher/DataPublisherService.java | 106 ++++++++- .../android/sense/data/publisher/Event.java | 212 +++++++++++++++++- .../iot/android/sense/event/SenseService.java | 21 +- .../event/streams/SenseDataCollector.java | 6 +- .../event/streams/activity/ActivityData.java | 67 ++++++ .../streams/activity/ActivityReceiver.java | 54 +++++ .../streams/application/ApplicationData.java | 61 +++++ .../application/ApplicationDataReceiver.java | 45 ++++ .../sense/event/streams/audio/AudioData.java | 58 +++++ .../event/streams/audio/AudioDataReader.java | 50 +++++ .../event/streams/battery/BatteryData.java | 18 ++ .../streams/battery/BatteryDataReceiver.java | 8 +- .../sense/event/streams/call/CallData.java | 70 ++++++ .../event/streams/call/CallDataReceiver.java | 87 +++++++ .../event/streams/screen/ScreenData.java | 55 +++++ .../streams/screen/ScreenDataReceiver.java | 32 +++ .../sense/event/streams/sms/SmsData.java | 58 +++++ .../event/streams/sms/SmsDataReceiver.java | 49 ++++ .../sensorlisting/SupportedSensors.java | 3 + .../android/sense/util/SenseDataHolder.java | 111 +++++++-- .../sense/util/SenseDataReceiverManager.java | 175 +++++++++++++++ 23 files changed, 1319 insertions(+), 46 deletions(-) create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityReceiver.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationDataReceiver.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioDataReader.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallDataReceiver.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenDataReceiver.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsData.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsDataReceiver.java create mode 100644 components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataReceiverManager.java diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle index 0c360c9b12..9f6b11adf4 100755 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle @@ -61,4 +61,5 @@ dependencies { compile 'org.altbeacon:android-beacon-library:2.8.1' compile 'uk.co.alt236:easycursor-android:1.0.0' compile 'uk.co.alt236:bluetooth-le-library-android:1.0.0' + compile 'com.google.android.gms:play-services-location:9.4.0' } diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml index 7ba9b334cc..2b0f926dad 100755 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml @@ -11,11 +11,16 @@ - - + + + + + + + + + @@ -53,13 +60,6 @@ - - - - - batteryDataMap = SenseDataHolder.getBatteryDataHolder(); if (!batteryDataMap.isEmpty()) { for (BatteryData batteryData : batteryDataMap) { Event event = new Event(); event.setTimestamp(batteryData.getTimestamp()); event.setBattery(batteryData.getLevel()); + event.setBatteryTemperature(batteryData.getTemperature()); + event.setBatteryStatus(batteryData.getStatus()); + event.setBatteryState(batteryData.getState().toString()); events.add(event); } } SenseDataHolder.resetBatteryDataHolder(); + //retrieve location data. List locationDataMap = SenseDataHolder.getLocationDataHolder(); @@ -132,7 +140,7 @@ public class DataPublisherService extends Service { event.setGps(new double[]{locationData.getLatitude(), locationData.getLongitude()}); events.add(event); } - } + } SenseDataHolder.resetLocationDataHolder(); //retrieve speed data. @@ -186,6 +194,90 @@ public class DataPublisherService extends Service { } } SenseDataHolder.resetWordDataHolder(); + + // retrieve call data. + List callDataList = SenseDataHolder.getCallDataHolder(); + if (!callDataList.isEmpty()) { + for (CallData callData : callDataList) { + Event event = new Event(); + event.setCallNumber(callData.getPhoneNumber()); + event.setCallType(callData.getType().toString().toLowerCase()); + event.setCallStartTime(callData.getStartTime()); + event.setCallEndTime(callData.getEndTime()); + event.setTimestamp(callData.getStartTime()); + + events.add(event); + } + } + SenseDataHolder.resetCallDataHolder(); + + // retrieve screen data. + List screenDataList = SenseDataHolder.getScreenDataHolder(); + if (!screenDataList.isEmpty()) { + for (ScreenData screenData : screenDataList) { + Event event = new Event(); + event.setScreenState(screenData.getAction()); + event.setTimestamp(screenData.getTimestamp()); + + events.add(event); + } + } + SenseDataHolder.resetScreenDataHolder(); + + // retrieve audio data. + List audioDataList = SenseDataHolder.getAudioDataHolder(); + if (!audioDataList.isEmpty()) { + for (AudioData audioData : audioDataList) { + Event event = new Event(); + event.setTimestamp(audioData.getTimestamp()); + event.setAudioPlaying(audioData.isPlaying()); + event.setHeadsetOn(audioData.isHeadsetOn()); + event.setMusicVolume(audioData.getMusicVolume()); + events.add(event); + } + } + SenseDataHolder.resetAudioDataHolder(); + + // retrieve activity data. + List activityDataList = SenseDataHolder.getActivityDataHolder(); + if (!activityDataList.isEmpty()) { + for (ActivityData activityData : activityDataList) { + Event event = new Event(); + event.setTimestamp(activityData.getTimestamp()); + event.setActivityType(activityData.getActivity()); + event.setConfidence(activityData.getConfidence()); + events.add(event); + } + } + SenseDataHolder.resetActivityDataHolder(); + + // retrieve sms data. + List smsDataList = SenseDataHolder.getSmsDataHolder(); + if (!smsDataList.isEmpty()) { + for (SmsData smsData : smsDataList) { + Event event = new Event(); + event.setTimestamp(smsData.getTimestamp()); + event.setSmsNumber(smsData.getPhoneNumber()); + events.add(event); + } + } + SenseDataHolder.resetSmsDataHolder(); + + + // retrieve application data. + List appDataList = SenseDataHolder.getApplicationDataHolder(); + if (!appDataList.isEmpty()) { + for (ApplicationData appData : appDataList) { + Event event = new Event(); + event.setTimestamp(appData.getTimestamp()); + event.setPackageName(appData.getPackageName()); + event.setAction(appData.getAction().toString()); + events.add(event); + } + } + SenseDataHolder.resetApplicationDataHolder(); + + //publish the data if (events.size() > 0 && LocalRegistry.isEnrolled(context)) { String user = LocalRegistry.getUsername(context); diff --git a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java index 5b5446d707..1bc91c3a32 100755 --- a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java @@ -16,6 +16,12 @@ public class Event { private float accelerometer[] = new float[]{0, 0, 0}; //x,y,z private float magnetic[] = new float[]{0, 0, 0};; //x,y,z private float gyroscope[] = new float[]{0, 0, 0};; //x,y,z + private int batteryTemperature; + private int batteryStatus; + /** + * LOW or OK + */ + private String batteryState; private float light; private float pressure; private float proximity; @@ -32,8 +38,28 @@ public class Event { private int beaconMinor; private int beaconUuid; private String beaconProximity; - - + private String callNumber; + private String callType; + private long callStartTime; + private long callEndTime; + + /** + * State of the phone display. + * Possible values are: + * on + * off + * unknown + */ + private String screenState; + + private boolean audioPlaying; + private boolean headsetOn; + private int musicVolume; + private int activityType; + private int confidence; + private String smsNumber; + private String packageName; + private String action; private int getBattery() { return battery; @@ -44,6 +70,33 @@ public class Event { this.battery = battery; } + public int getBatteryTemperature() { + return batteryTemperature; + } + + public void setBatteryTemperature(int batteryTemperature) { + this.type = "battery"; // Type is battery + this.batteryTemperature = batteryTemperature; + } + + public int getBatteryStatus() { + return batteryStatus; + } + + public void setBatteryStatus(int batteryStatus) { + this.type = "battery"; // Type is battery + this.batteryStatus = batteryStatus; + } + + public String getBatteryState() { + return batteryState != null ? batteryState : ""; + } + + public void setBatteryState(String batteryState) { + this.type = "battery"; // Type is battery + this.batteryState = batteryState; + } + private double[] getGps() { return gps; } @@ -125,6 +178,15 @@ public class Event { this.rotation = rotation; } + public void setSmsNumber(String smsNumber) { + this.type = "sms"; + this.smsNumber = smsNumber; + } + + public String getSmsNumber() { + return smsNumber; + } + private String getWordSessionId() { return wordSessionId != null ? wordSessionId : ""; } @@ -142,6 +204,24 @@ public class Event { this.word = word; } + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.type = "application"; + this.packageName = packageName; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.type = "application"; + this.action = action; + } + private long getTimestamp() { return timestamp; } @@ -181,6 +261,9 @@ public class Event { public float getSpeed() { this.type = "speed"; + if (Float.isInfinite(speed) || Float.isNaN(speed)) { + return -1.0f; + } return speed; } @@ -192,7 +275,7 @@ public class Event { public String getTurns() { - if (turn == null || turn.isEmpty() || turn.equals("null")){ + if (turn == null || turn.isEmpty() || turn.equals("null")) { turn = "No Turns"; } return turn; @@ -234,8 +317,98 @@ public class Event { } public String getBeaconProximity() { - this.type = "beaconProximity"; - return beaconProximity; + return beaconProximity != null ? beaconProximity : ""; + } + + public String getCallNumber() { + return callNumber != null ? callNumber : ""; + } + + public void setCallNumber(String callNumber) { + this.type = "call"; + this.callNumber = callNumber; + } + + public String getCallType() { + return callType != null ? callType : ""; + } + + public void setCallType(String callType) { + this.type = "call"; + this.callType = callType; + } + + public long getCallStartTime() { + return callStartTime; + } + + public void setCallStartTime(long callStartTime) { + this.type = "call"; + this.callStartTime = callStartTime; + } + + public long getCallEndTime() { + return callEndTime; + } + + public void setCallEndTime(long callEndTime) { + this.type = "call"; + this.callEndTime = callEndTime; + } + + public String getScreenState() { + return screenState != null ? screenState : ""; + } + + public void setScreenState(String screenState) { + this.type = "screen"; + this.screenState = screenState; + } + + public boolean isAudioPlaying() { + return audioPlaying; + } + + public void setAudioPlaying(boolean audioPlaying) { + this.type = "audio"; + this.audioPlaying = audioPlaying; + } + + public boolean isHeadsetOn() { + return headsetOn; + } + + public void setHeadsetOn(boolean headsetOn) { + this.type = "audio"; + this.headsetOn = headsetOn; + } + + public int getMusicVolume() { + return musicVolume; + } + + public void setMusicVolume(int musicVolume) { + this.type = "audio"; + this.musicVolume = musicVolume; + } + + public int getActivityType() { + return activityType; + } + + public void setActivityType(int activityType) { + this.type = "activity"; + this.activityType = activityType; + } + + public int getConfidence() { + return confidence; + } + + public void setConfidence(int confidence) { + // Do not set type here since it can be used for various types. + // However, now it is being used by activity only + this.confidence = confidence; } public JSONObject getEvent() throws JSONException { @@ -248,7 +421,13 @@ public class Event { jsonEvent.put("metaData", jsonMetaData); JSONObject jsonPayloadData = new JSONObject(); + // battery jsonPayloadData.put("battery", getBattery()); + jsonPayloadData.put("battery_state", getBatteryState()); + jsonPayloadData.put("battery_status", getBatteryStatus()); + jsonPayloadData.put("battery_temperature", getBatteryTemperature()); + + //gps double gpsEvents[] = getGps(); jsonPayloadData.put("gps_lat", gpsEvents[0]); @@ -301,6 +480,29 @@ public class Event { jsonPayloadData.put("word_sessionId", getWordSessionId()); jsonPayloadData.put("word_status", getWordStatus()); + // call + jsonPayloadData.put("call_number", getCallNumber()); + jsonPayloadData.put("call_type", getCallType()); + jsonPayloadData.put("call_start_time", getCallStartTime()); + jsonPayloadData.put("call_end_time", getCallEndTime()); + + // screen + jsonPayloadData.put("screen_state", getScreenState()); + + // headset + jsonPayloadData.put("audio_playing", isAudioPlaying()); + jsonPayloadData.put("headset_on", isHeadsetOn()); + jsonPayloadData.put("music_volume", getMusicVolume()); + + jsonPayloadData.put("activity_type", getActivityType()); + jsonPayloadData.put("confidence", getConfidence()); + + jsonPayloadData.put("sms_number", getSmsNumber()); + + jsonPayloadData.put("application_name", getPackageName()); + jsonPayloadData.put("action", getAction()); + + jsonEvent.put("payloadData", jsonPayloadData); return jsonEvent; diff --git a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java index 0aac980762..37e3356c68 100755 --- a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java @@ -16,11 +16,11 @@ 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.SenseDataReceiverManager; import org.wso2.carbon.iot.android.sense.util.SenseWakeLock; /** @@ -48,10 +48,14 @@ public class SenseService extends Service { //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)); SenseDataCollector speed = new SenseDataCollector(this, SenseDataCollector.DataType.SPEED); - - + SenseDataCollector audio = new SenseDataCollector(this, SenseDataCollector.DataType.AUDIO); + SenseDataReceiverManager.registerBatteryDataReceiver(this); + SenseDataReceiverManager.registerScreenDataReceiver(this); + SenseDataReceiverManager.registerCallDataReceiver(this); + SenseDataReceiverManager.registerActivityDataReceiver(this); + SenseDataReceiverManager.registerSmsDataReceiver(this); + SenseDataReceiverManager.registerAppDataReceiver(this); //service will not be stopped until we manually stop the service return Service.START_NOT_STICKY; @@ -59,6 +63,13 @@ public class SenseService extends Service { @Override public void onDestroy() { + SenseDataReceiverManager.unregisterBatteryDataReceiver(this); + SenseDataReceiverManager.unregisterScreenDataReceiver(this); + SenseDataReceiverManager.unregisterCallDataReceiver(this); + SenseDataReceiverManager.unregisterActivityDataReceiver(this); + SenseDataReceiverManager.unregisterSmsDataReceiver(this); + SenseDataReceiverManager.unregisterAppDataReceiver(this); + SenseWakeLock.releaseCPUWakeLock(); super.onDestroy(); } diff --git a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java index 4899b29b8c..726e55fd41 100755 --- a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java @@ -19,13 +19,14 @@ import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationDataRead import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorDataReader; import org.wso2.carbon.iot.android.sense.event.streams.Speed.SpeedDataReader; import org.wso2.carbon.iot.android.sense.beacon.MonitoringActivity; +import org.wso2.carbon.iot.android.sense.event.streams.audio.AudioDataReader; /** * This class triggered by service to collect the sensor data. */ public class SenseDataCollector { public enum DataType { - SENSOR, LOCATION,SPEED + SENSOR, LOCATION,SPEED, AUDIO } public SenseDataCollector(Context ctx, DataType dt) { @@ -40,6 +41,9 @@ public class SenseDataCollector { case SPEED: dr = new SpeedDataReader(ctx); break; + case AUDIO: + dr = new AudioDataReader(ctx); + break; } if (dr != null) { diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityData.java new file mode 100644 index 0000000000..772351c5bd --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityData.java @@ -0,0 +1,67 @@ +/* + * 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.event.streams.activity; + +import java.util.Date; + +public class ActivityData { + /** + * 0 - In vehicle + * 1 - Bicycle + * 2 - Foot + * 3 - Still + * 4 - Unknown + * 5 - Tilting + * 7 - Walking + * 8 - Running + */ + private int activity; + private int confidence; + private long timestamp; + + ActivityData(int activity, int confidence) { + this.activity = activity; + this.confidence = confidence; + this.timestamp = new Date().getTime(); + } + + public int getActivity() { + return activity; + } + + public void setActivity(int activity) { + this.activity = activity; + } + + public int getConfidence() { + return confidence; + } + + public void setConfidence(int confidence) { + this.confidence = confidence; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityReceiver.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityReceiver.java new file mode 100644 index 0000000000..3220491983 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/activity/ActivityReceiver.java @@ -0,0 +1,54 @@ +/* + * 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.event.streams.activity; + +import android.app.IntentService; +import android.content.Intent; + +import com.google.android.gms.location.ActivityRecognitionResult; +import com.google.android.gms.location.DetectedActivity; + +import org.wso2.carbon.iot.android.sense.util.SenseDataHolder; + +public class ActivityReceiver extends IntentService { + public static final int MINIMUM_CONFIDENCE = 75; + + /** + * Retrieve the information for every 10 seconds. + */ + public static final long UPDATE_INTERVAL = 10000; + + public ActivityReceiver() { + super(ActivityReceiver.class.getName()); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (ActivityRecognitionResult.hasResult(intent)) { + ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); + + for (DetectedActivity activity : result.getProbableActivities()) { + if (activity.getConfidence() >= MINIMUM_CONFIDENCE) { + ActivityData data = new ActivityData(activity.getType(), activity.getConfidence()); + SenseDataHolder.getActivityDataHolder().add(data); + } + } + } + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationData.java new file mode 100644 index 0000000000..1443e36b94 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationData.java @@ -0,0 +1,61 @@ +/* + * 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.event.streams.application; + +import java.util.Date; + +public class ApplicationData { + public enum Action { + INSTALL, REMOVE + } + + private long timestamp; + private String packageName; + private Action action; + + ApplicationData(String packageName, Action action) { + this.packageName = packageName; + this.action = action; + this.timestamp = new Date().getTime(); + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public Action getAction() { + return action; + } + + public void setAction(Action action) { + this.action = action; + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationDataReceiver.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationDataReceiver.java new file mode 100644 index 0000000000..8cb52550fe --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/application/ApplicationDataReceiver.java @@ -0,0 +1,45 @@ +/* + * 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.event.streams.application; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.wso2.carbon.iot.android.sense.util.SenseDataHolder; + +/** + * Currently interested on package add and remove only. Can be extended for modification. + */ +public class ApplicationDataReceiver extends BroadcastReceiver { + + + @Override + public void onReceive(Context context, Intent intent) { + String packageName = intent.getData().toString().substring(8); + ApplicationData appData; + if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { + appData = new ApplicationData(packageName, ApplicationData.Action.INSTALL); + } else { + // Removed + appData = new ApplicationData(packageName, ApplicationData.Action.REMOVE); + } + SenseDataHolder.getApplicationDataHolder().add(appData); + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioData.java new file mode 100644 index 0000000000..0449d32919 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioData.java @@ -0,0 +1,58 @@ +/* + * 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.event.streams.audio; + +public class AudioData { + private long timestamp; + private boolean headsetOn; + private int musicVolume; + private boolean playing; + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public boolean isHeadsetOn() { + return headsetOn; + } + + public void setHeadsetOn(boolean headsetOn) { + this.headsetOn = headsetOn; + } + + public int getMusicVolume() { + return musicVolume; + } + + public void setMusicVolume(int musicVolume) { + this.musicVolume = musicVolume; + } + + public boolean isPlaying() { + return playing; + } + + public void setPlaying(boolean playing) { + this.playing = playing; + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioDataReader.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioDataReader.java new file mode 100644 index 0000000000..1a5f85c092 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/audio/AudioDataReader.java @@ -0,0 +1,50 @@ +/* + * 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.event.streams.audio; + +import android.content.Context; +import android.media.AudioManager; +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.Date; + +public class AudioDataReader extends DataReader { + + private static final String TAG = AudioDataReader.class.getName(); + private Context context; + + public AudioDataReader(Context context) { + this.context = context; + } + + @Override + public void run() { + Log.d(TAG, "Running AudioDataReader"); + AudioManager manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + AudioData audioData = new AudioData(); + audioData.setTimestamp(new Date().getTime()); + audioData.setPlaying(manager.isMusicActive()); + audioData.setHeadsetOn(manager.isWiredHeadsetOn()); + audioData.setMusicVolume(manager.getStreamVolume(AudioManager.STREAM_MUSIC)); + SenseDataHolder.getAudioDataHolder().add(audioData); + } +} diff --git a/components/device-types/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/device-types/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 index 666e02a85f..7a4d7413aa 100755 --- a/components/device-types/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/device-types/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 @@ -25,6 +25,10 @@ import java.util.Date; */ public class BatteryData { + public enum State { + LOW, OK + } + private int health; private int level; private int plugged; @@ -34,6 +38,7 @@ public class BatteryData { private int temperature; private int voltage; private long timestamp; + private State state; BatteryData(Intent intent) { timestamp = new Date().getTime(); @@ -46,7 +51,12 @@ public class BatteryData { String technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY); temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0); voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0); + state = State.OK; + } + BatteryData(State state) { + this.timestamp = new Date().getTime(); + this.state = state; } public int getHealth() { @@ -121,4 +131,12 @@ public class BatteryData { public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } } diff --git a/components/device-types/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/device-types/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 index 9fffa1c157..794f69b3db 100755 --- a/components/device-types/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/device-types/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 @@ -32,7 +32,13 @@ public class BatteryDataReceiver extends BroadcastReceiver { */ @Override public void onReceive(Context context, Intent intent) { - SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent)); + if (Intent.ACTION_BATTERY_OKAY.equals(intent.getAction())) { + SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.OK)); + } else if (Intent.ACTION_BATTERY_LOW.equals(intent.getAction())) { + SenseDataHolder.getBatteryDataHolder().add(new BatteryData(BatteryData.State.LOW)); + } else { + SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent)); + } } } diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallData.java new file mode 100644 index 0000000000..9f617cdb17 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallData.java @@ -0,0 +1,70 @@ +/* + * 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.event.streams.call; + +public class CallData { + + public enum Type { + INCOMING, OUTGOING, MISSED; + } + + private Type type; + private String phoneNumber; + private long startTime; + private long endTime; + + public CallData(Type type, String phoneNumber, long startTime, long endTime) { + this.type = type; + this.phoneNumber = phoneNumber; + this.startTime = startTime; + this.endTime = endTime; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } +} \ No newline at end of file diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallDataReceiver.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallDataReceiver.java new file mode 100644 index 0000000000..1988914e81 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/call/CallDataReceiver.java @@ -0,0 +1,87 @@ +/* + * 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.event.streams.call; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.telephony.TelephonyManager; + +import org.wso2.carbon.iot.android.sense.util.SenseDataHolder; + +public class CallDataReceiver extends BroadcastReceiver { + private static int lastState = TelephonyManager.CALL_STATE_IDLE; + private static long startTime; + private static boolean isIncoming; + private static String lastNotifiedNumber; + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { + lastNotifiedNumber = intent.getExtras().getString(Intent.EXTRA_PHONE_NUMBER); + } else { + String extraState = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); + int state = 0; + if (extraState.equals(TelephonyManager.EXTRA_STATE_IDLE)) { + state = TelephonyManager.CALL_STATE_IDLE; + } else if (extraState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { + state = TelephonyManager.CALL_STATE_OFFHOOK; + } else if (extraState.equals(TelephonyManager.EXTRA_STATE_RINGING)) { + state = TelephonyManager.CALL_STATE_RINGING; + } + + if (lastState == state) { + return; // Nothing has been changed + } + switch (state) { + case TelephonyManager.CALL_STATE_RINGING: + // Receiving a call + isIncoming = true; + startTime = System.currentTimeMillis(); + // If incoming call, get the incoming number + lastNotifiedNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER); + break; + case TelephonyManager.CALL_STATE_OFFHOOK: + if (lastState == TelephonyManager.CALL_STATE_RINGING) { + // RINGING -> OFFHOOK = ANSWERED + isIncoming = true; + startTime = System.currentTimeMillis(); + } else { + // NOT RINGING -> OFFHOOK = OUTGOING + isIncoming = false; + startTime = System.currentTimeMillis(); + } + break; + case TelephonyManager.CALL_STATE_IDLE: + if (lastState == TelephonyManager.CALL_STATE_RINGING) { + // RINGING -> IDLE = MISSED + SenseDataHolder.getCallDataHolder().add(new CallData(CallData.Type.MISSED, lastNotifiedNumber, startTime, System.currentTimeMillis())); + } else if (isIncoming) { + // Incoming (OFFHOOK) -> IDLE = INCOMING CALL ENDED + SenseDataHolder.getCallDataHolder().add(new CallData(CallData.Type.INCOMING, lastNotifiedNumber, startTime, System.currentTimeMillis())); + } else { + // Not Incoming -> IDLE = OUTGOING CALL ENDED + SenseDataHolder.getCallDataHolder().add(new CallData(CallData.Type.OUTGOING, lastNotifiedNumber, startTime, System.currentTimeMillis())); + } + break; + } + lastState = state; + } + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenData.java new file mode 100644 index 0000000000..0c124611f7 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenData.java @@ -0,0 +1,55 @@ +/* + * 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.event.streams.screen; + +import android.content.Intent; + +import java.util.Date; + +public class ScreenData { + private String action; + private long timestamp; + + ScreenData(Intent intent) { + if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) { + this.action = "on"; + } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { + this.action = "off"; + } else { + this.action = "unknown"; + } + this.timestamp = new Date().getTime(); + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenDataReceiver.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenDataReceiver.java new file mode 100644 index 0000000000..ace9d98faa --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/screen/ScreenDataReceiver.java @@ -0,0 +1,32 @@ +/* + * 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.event.streams.screen; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.wso2.carbon.iot.android.sense.util.SenseDataHolder; + +public class ScreenDataReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + SenseDataHolder.getScreenDataHolder().add(new ScreenData(intent)); + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsData.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsData.java new file mode 100644 index 0000000000..607ca2a857 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsData.java @@ -0,0 +1,58 @@ +/* + * 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.event.streams.sms; + +import java.util.Date; + +public class SmsData { + + private String phoneNumber; + private long timestamp; + private String message; + + SmsData(String phoneNumber, String message) { + this.phoneNumber = phoneNumber; + this.message = message; + this.timestamp = new Date().getTime(); + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsDataReceiver.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsDataReceiver.java new file mode 100644 index 0000000000..2ada981fb3 --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/sms/SmsDataReceiver.java @@ -0,0 +1,49 @@ +/* + * 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.event.streams.sms; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.telephony.SmsMessage; + +import org.wso2.carbon.iot.android.sense.util.SenseDataHolder; + +public class SmsDataReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + final Bundle bundle = intent.getExtras(); + + if (bundle != null) { + + final Object[] pdusObj = (Object[]) bundle.get("pdus"); + + for (int i = 0; i < pdusObj.length; i++) { + SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); + String phoneNumber = currentMessage.getDisplayOriginatingAddress(); + String message = currentMessage.getDisplayMessageBody(); + + SmsData smsData = new SmsData(phoneNumber, message); + SenseDataHolder.getSmsDataHolder().add(smsData); + } + } + } +} diff --git a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java index 6d57e6d704..2b0f5351be 100755 --- a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java @@ -60,6 +60,7 @@ public class SupportedSensors { sensorList.add("Light"); sensorList.add("Gyroscope"); sensorList.add("Proximity"); + sensorList.add("Pedometer"); } /** @@ -74,6 +75,7 @@ public class SupportedSensors { sensorTypeMap.put("gyroscope", Sensor.TYPE_GYROSCOPE); sensorTypeMap.put("light", Sensor.TYPE_LIGHT); sensorTypeMap.put("proximity", Sensor.TYPE_PROXIMITY); + sensorTypeMap.put("pedometer", Sensor.TYPE_STEP_COUNTER); } /** @@ -88,6 +90,7 @@ public class SupportedSensors { typeSensorMap.put(Sensor.TYPE_GYROSCOPE, "gyroscope"); typeSensorMap.put(Sensor.TYPE_LIGHT, "light"); typeSensorMap.put(Sensor.TYPE_PROXIMITY, "proximity"); + typeSensorMap.put(Sensor.TYPE_STEP_COUNTER, "pedometer"); } /** diff --git a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java index 1d33225b9a..c3d12cafb8 100755 --- a/components/device-types/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/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java @@ -17,11 +17,17 @@ import org.wso2.carbon.iot.android.sense.beacon.BeaconScanedData; 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.Speed.SpeedData; +import org.wso2.carbon.iot.android.sense.event.streams.activity.ActivityData; +import org.wso2.carbon.iot.android.sense.event.streams.application.ApplicationData; +import org.wso2.carbon.iot.android.sense.event.streams.audio.AudioData; import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryData; +import org.wso2.carbon.iot.android.sense.event.streams.call.CallData; +import org.wso2.carbon.iot.android.sense.event.streams.screen.ScreenData; +import org.wso2.carbon.iot.android.sense.event.streams.sms.SmsData; import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData; + import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import android.util.Log; /** @@ -31,72 +37,123 @@ public class SenseDataHolder { private static List sensorDataHolder; private static List batteryDataHolder; + private static List callDataHolder; private static List locationDataHolder; private static List wordDataHolder; private static List speedDataHolder; private static List beaconScanedDataHolder; - + private static List screenDataHolder; + private static List audioDataHolder; + private static List activityDataHolder; + private static List smsDataHolder; + private static List applicationDataHolder; //LocationData gps; private static final String TAG = SenseDataHolder.class.getName(); - public static List getSensorDataHolder(){ - if(sensorDataHolder == null){ + public static List getSensorDataHolder() { + if (sensorDataHolder == null) { sensorDataHolder = new CopyOnWriteArrayList<>(); } return sensorDataHolder; } - public static List getBatteryDataHolder(){ - if(batteryDataHolder == null){ + public static List getBatteryDataHolder() { + if (batteryDataHolder == null) { batteryDataHolder = new CopyOnWriteArrayList<>(); } return batteryDataHolder; } - public static List getLocationDataHolder(){ + public static List getCallDataHolder() { + if (callDataHolder == null) { + callDataHolder = new CopyOnWriteArrayList<>(); + } + return callDataHolder; + } + + public static List getLocationDataHolder() { - if(locationDataHolder == null){ + if (locationDataHolder == null) { locationDataHolder = new CopyOnWriteArrayList<>(); } - return locationDataHolder; + return locationDataHolder; } - public static List getWordDataHolder(){ - if(wordDataHolder == null){ + public static List getWordDataHolder() { + if (wordDataHolder == null) { wordDataHolder = new CopyOnWriteArrayList<>(); } return wordDataHolder; } - public static List getSpeedDataHolder(){ - if(speedDataHolder == null){ + public static List getSpeedDataHolder() { + if (speedDataHolder == null) { speedDataHolder = new CopyOnWriteArrayList<>(); } return speedDataHolder; } - public static List getBeaconScanedDataHolder(){ - if(beaconScanedDataHolder == null){ + public static List getBeaconScanedDataHolder() { + if (beaconScanedDataHolder == null) { beaconScanedDataHolder = new CopyOnWriteArrayList<>(); } return beaconScanedDataHolder; } - public static void resetSensorDataHolder(){ + public static List getScreenDataHolder() { + if (screenDataHolder == null) { + screenDataHolder = new CopyOnWriteArrayList<>(); + } + return screenDataHolder; + } + + public static List getAudioDataHolder() { + if (audioDataHolder == null) { + audioDataHolder = new CopyOnWriteArrayList<>(); + } + return audioDataHolder; + } + + public static List getActivityDataHolder() { + if (activityDataHolder == null) { + activityDataHolder = new CopyOnWriteArrayList<>(); + } + return activityDataHolder; + } + + public static List getSmsDataHolder() { + if (smsDataHolder == null) { + smsDataHolder = new CopyOnWriteArrayList<>(); + } + return smsDataHolder; + } + + public static List getApplicationDataHolder() { + if (applicationDataHolder == null) { + applicationDataHolder = new CopyOnWriteArrayList<>(); + } + return applicationDataHolder; + } + + public static void resetSensorDataHolder() { sensorDataHolder = null; } - public static void resetBatteryDataHolder(){ + public static void resetBatteryDataHolder() { batteryDataHolder = null; } - public static void resetLocationDataHolder(){ + public static void resetCallDataHolder() { + callDataHolder = null; + } + + public static void resetLocationDataHolder() { locationDataHolder = null; } @@ -112,5 +169,23 @@ public class SenseDataHolder { beaconScanedDataHolder = null; } + public static void resetScreenDataHolder() { + screenDataHolder = null; + } + public static void resetAudioDataHolder() { + audioDataHolder = null; + } + + public static void resetActivityDataHolder() { + activityDataHolder = null; + } + + public static void resetSmsDataHolder() { + smsDataHolder = null; + } + + public static void resetApplicationDataHolder() { + applicationDataHolder = null; + } } diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataReceiverManager.java b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataReceiverManager.java new file mode 100644 index 0000000000..a72532464a --- /dev/null +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataReceiverManager.java @@ -0,0 +1,175 @@ +/* + * 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; + +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.provider.Telephony; +import android.support.annotation.Nullable; +import android.telephony.TelephonyManager; + +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.location.ActivityRecognition; + +import org.wso2.carbon.iot.android.sense.event.streams.activity.ActivityReceiver; +import org.wso2.carbon.iot.android.sense.event.streams.application.ApplicationDataReceiver; +import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryDataReceiver; +import org.wso2.carbon.iot.android.sense.event.streams.call.CallDataReceiver; +import org.wso2.carbon.iot.android.sense.event.streams.screen.ScreenDataReceiver; +import org.wso2.carbon.iot.android.sense.event.streams.sms.SmsDataReceiver; + +public class SenseDataReceiverManager { + private static BroadcastReceiver batteryDataReceiver; + + private static BroadcastReceiver screenDataReceiver; + + private static BroadcastReceiver callDataReceiver; + + private static GoogleApiClient apiClient; + + private static SmsDataReceiver smsDataReceiver; + + private static ApplicationDataReceiver appDataReceiver; + + private SenseDataReceiverManager() { + + } + + public static void registerBatteryDataReceiver(Context context) { + if (batteryDataReceiver == null) { + batteryDataReceiver = new BatteryDataReceiver(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_BATTERY_LOW); + intentFilter.addAction(Intent.ACTION_BATTERY_OKAY); + intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); + + context.registerReceiver(batteryDataReceiver, intentFilter); + } + } + + public static void unregisterBatteryDataReceiver(Context context) { + if (batteryDataReceiver != null) { + context.unregisterReceiver(batteryDataReceiver); + batteryDataReceiver = null; + } + } + + public static void registerScreenDataReceiver(Context context) { + if (screenDataReceiver == null) { + screenDataReceiver = new ScreenDataReceiver(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_SCREEN_ON); + intentFilter.addAction(Intent.ACTION_SCREEN_OFF); + + context.registerReceiver(screenDataReceiver, intentFilter); + } + } + + public static void unregisterScreenDataReceiver(Context context) { + if (screenDataReceiver != null) { + context.unregisterReceiver(screenDataReceiver); + screenDataReceiver = null; + } + } + + public static void registerCallDataReceiver(Context context) { + if (callDataReceiver == null) { + callDataReceiver = new CallDataReceiver(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); + + context.registerReceiver(callDataReceiver, intentFilter); + } + } + + public static void unregisterCallDataReceiver(Context context) { + if (callDataReceiver != null) { + context.unregisterReceiver(callDataReceiver); + callDataReceiver = null; + } + } + + public static void registerActivityDataReceiver(Context context) { + if (apiClient == null) { + Intent intent = new Intent(context, ActivityReceiver.class); + final PendingIntent pendingIntent = PendingIntent.getService(context, 888971, intent, PendingIntent.FLAG_UPDATE_CURRENT); + apiClient = new GoogleApiClient.Builder(context) + .addApi(ActivityRecognition.API) + .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { + @Override + public void onConnected(@Nullable Bundle bundle) { + ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(apiClient, ActivityReceiver.UPDATE_INTERVAL, pendingIntent); + } + + @Override + public void onConnectionSuspended(int i) { + ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(apiClient, pendingIntent); + } + }) + .build(); + + apiClient.connect(); + } + } + + public static void unregisterActivityDataReceiver(Context context) { + if (apiClient != null) { + apiClient.disconnect(); + apiClient = null; + } + } + + public static void registerSmsDataReceiver(Context context) { + if (smsDataReceiver == null) { + smsDataReceiver = new SmsDataReceiver(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION); + context.registerReceiver(smsDataReceiver, intentFilter); + } + } + + public static void unregisterSmsDataReceiver(Context context) { + if (smsDataReceiver != null) { + context.unregisterReceiver(smsDataReceiver); + smsDataReceiver = null; + } + } + + public static void registerAppDataReceiver(Context context) { + if (appDataReceiver == null) { + appDataReceiver = new ApplicationDataReceiver(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + context.registerReceiver(appDataReceiver, intentFilter); + } + } + + public static void unregisterAppDataReceiver(Context context) { + if (appDataReceiver != null) { + context.unregisterReceiver(appDataReceiver); + appDataReceiver = null; + } + } +} From 326d59e7c10e21377d77572923d8c0df189bd90c Mon Sep 17 00:00:00 2001 From: Ace Date: Wed, 30 Nov 2016 16:51:49 +0530 Subject: [PATCH 06/10] Adding android operations-bar related changes --- .../device-view.hbs | 120 ++- .../device-view.hbs | 781 ++++++++---------- .../device-view.js | 11 +- .../public/js/device-detail.js | 88 -- .../public/templates/operations-log.hbs | 24 - .../public/templates/policy-compliance.hbs | 3 +- .../operation-bar.hbs | 32 + .../operation-bar.js | 106 +++ .../operation-bar.json | 3 + .../public/js/operation-bar.js | 248 ++++++ .../templates/hidden-operations-android.hbs | 0 .../templates/hidden-operations-ios.hbs | 0 .../public/templates/operations.hbs | 0 .../operation-bar.hbs | 113 ++- .../operation-bar.js | 129 +-- .../public/js/operation-bar.js | 326 +++----- .../private/config.json | 39 +- .../main/resources/devicetypes/android.xml | 209 ++--- 18 files changed, 1170 insertions(+), 1062 deletions(-) delete mode 100755 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/public/templates/operations-log.hbs create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.old.operation-bar/operation-bar.hbs create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.old.operation-bar/operation-bar.js create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.old.operation-bar/operation-bar.json create mode 100644 components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.old.operation-bar/public/js/operation-bar.js rename components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/{cdmf.unit.device.type.android.operation-bar => cdmf.unit.device.type.android.old.operation-bar}/public/templates/hidden-operations-android.hbs (100%) rename components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/{cdmf.unit.device.type.android.operation-bar => cdmf.unit.device.type.android.old.operation-bar}/public/templates/hidden-operations-ios.hbs (100%) rename components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/{cdmf.unit.device.type.android.operation-bar => cdmf.unit.device.type.android.old.operation-bar}/public/templates/operations.hbs (100%) diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.device-view/device-view.hbs b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.device-view/device-view.hbs index 7d345c2ab1..9cd2ca642b 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.device-view/device-view.hbs +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.device-view/device-view.hbs @@ -37,81 +37,75 @@ {{/zone}} -{{#zone "device-detail-properties"}} -
- -
-
+{{#zone "device-view-tabs"}} +
  • Device + Statistics +
  • +
  • Policies +
  • +
  • Operations Log
  • +{{/zone}} -
    -
    Device Statistics
    - {{unit "cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view" device=device}} -
    +{{#zone "device-view-tab-contents"}} -
    -
    Policies
    -
    - + Add device specific policy -
    -
    -
    Operations Log
    -
    - +
    +
    Operations Log
    +
    + -
    -
    - Not available yet -
    -
    -
    -
    + Loading Operations Log . . . +
    +
    +
    +
    +
    + Not available yet
    +
    {{/zone}} + diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs index 0f613ddc86..3842be7309 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.device-view/device-view.hbs @@ -1,485 +1,406 @@ {{unit "cdmf.unit.device.type.android.leaflet"}} {{unit "cdmf.unit.lib.qrcode"}} {{unit "cdmf.unit.device.type.android.qr-modal"}} -{{unit "cdmf.unit.device.type.android.operation-bar"}} {{#if deviceFound}} {{#if isAuthorized}} {{#zone "device-details-header"}} -

    - Device {{deviceView.name}} - {{#if deviceView.model}} - - ( {{deviceView.vendor}} {{deviceView.model}} ) +

    + Device {{device.name}} + {{#if device.model}} + + ( {{device.vendor}} {{device.model}} ) - {{/if}} -

    + {{/if}} +

    {{/zone}} - {{#zone "overview-section"}} -
    -
    Device - Overview -
    - - - {{#if deviceView.deviceIdentifier}} - - - - - {{/if}} - {{#if deviceView.name}} - - - - - {{/if}} - {{#if deviceView.vendor}} - {{#if deviceView.model}} - - - - - {{/if}} - {{/if}} - {{#if deviceView.status}} - - - - - {{/if}} - {{#if deviceView.owner}} - - - - - {{/if}} - {{#if deviceView.ownership}} - - - - - {{/if}} - {{#if deviceView.imei}} - - - - - {{/if}} - {{#if deviceView.udid}} - - - - - {{/if}} - {{#if deviceView.osBuildDate}} - - - - - {{/if}} - {{#if deviceView.phoneNumber}} - - - - - {{/if}} - {{#if deviceView.lastUpdatedTime}} - - - - - {{/if}} - -
    Device ID{{deviceView.deviceIdentifier}}
    Name{{deviceView.name}}
    Model{{deviceView.vendor}} {{deviceView.model}}
    Status - {{#equal deviceView.status "ACTIVE"}}Active{{/equal}} - {{#equal deviceView.status "INACTIVE"}}Inactive{{/equal}} - {{#equal deviceView.status "BLOCKED"}}Blocked{{/equal}} - {{#equal deviceView.status "REMOVED"}}Removed{{/equal}} -
    Owner{{deviceView.owner}}
    Ownership{{deviceView.ownership}}
    IMEI{{deviceView.imei}}
    UDID{{deviceView.udid}}
    Firmware Build - Date - {{deviceView.osBuildDate}}
    Phone Number{{deviceView.phoneNumber}}
    Last Update{{deviceView.lastUpdatedTime}}
    -
    - {{/zone}} - - {{#zone "device-opetations"}} - {{#if deviceView.isNotRemoved}} -
    - Operations -
    -
    - {{unit "cdmf.unit.device.operation-bar" device=deviceView backendApiUri=backendApiUri autoCompleteParams=autoCompleteParams}} -
    + {{#zone "overview-section"}} +
    +
    Device + Overview +
    + + + {{#if device.deviceIdentifier}} + + + + {{/if}} - {{/zone}} - + {{#if device.name}} + + + + + {{/if}} + {{#if device.vendor}} + {{#if device.model}} + + + + + {{/if}} + {{/if}} + {{#if device.status}} + + + + + {{/if}} + {{#if device.owner}} + + + + + {{/if}} + {{#if device.ownership}} + + + + + {{/if}} + {{#if device.imei}} + + + + + {{/if}} + {{#if device.udid}} + + + + + {{/if}} + {{#if device.osBuildDate}} + + + + + {{/if}} + {{#if device.phoneNumber}} + + + + + {{/if}} + {{#if device.lastUpdatedTime}} + + + + + {{/if}} + +
    Device ID{{device.deviceIdentifier}}
    Name{{device.name}}
    Model{{device.vendor}} + {{device.model}}
    Status + {{#equal device.status "ACTIVE"}}Active{{/equal}} + {{#equal device.status "INACTIVE"}}Inactive{{/equal}} + {{#equal device.status "BLOCKED"}}Blocked{{/equal}} + {{#equal device.status "REMOVED"}}Removed{{/equal}} +
    Owner{{device.owner}}
    Ownership{{device.ownership}}
    IMEI{{device.imei}}
    UDID{{device.udid}}
    Firmware Build + Date + {{device.osBuildDate}}
    Phone Number{{device.phoneNumber}}
    Last Update{{device.lastUpdatedTime}}
    + {{/zone}} - {{#zone "device-detail-properties"}} -
    -