Merge branch 'application-mgt-new' into 'application-mgt-new'

Merge with upstream master branch

See merge request entgra/carbon-device-mgt-plugins!49
revert-dabc3590
Dharmakeerthi Lasantha 6 years ago
commit 35f0fd0ceb

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -3,7 +3,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mb-extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mb-extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>pull-notification-listeners</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.extension.siddhi.device.test.util;
@ -23,6 +40,7 @@ import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.general.GeneralConfig;
@ -30,6 +48,7 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformDetails;
import java.util.ArrayList;
import java.util.List;
@ -100,6 +119,11 @@ public class TestDeviceManagementService implements DeviceManagementService {
return null;
}
@Override
public StartupOperationConfig getStartupOperationConfig() {
return null;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return null;
@ -114,4 +138,7 @@ public class TestDeviceManagementService implements DeviceManagementService {
public GeneralConfig getGeneralConfig() {
return null;
}
@Override
public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; }
}

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -57,7 +57,6 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>

@ -203,7 +203,6 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
</plugin>
</plugins>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -27,9 +27,20 @@ import java.io.Serializable;
description = "This class represents notification frequency configuration.")
public class NotifierFrequency extends AndroidOperation implements Serializable {
@ApiModelProperty(name = "type", value = "Notification type", required = true)
private int type;
@ApiModelProperty(name = "value", value = "Notification polling frequency", required = true)
private int value;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getValue() {
return value;
}

@ -134,6 +134,7 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
try {
configuration.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
List<ConfigurationEntry> configs = configuration.getConfiguration();
NotifierFrequency notifierFrequency = new NotifierFrequency();
for (ConfigurationEntry entry : configs) {
if (AndroidConstants.TenantConfigProperties.LICENSE_KEY.equals(entry.getName())) {
License license = new License();
@ -145,30 +146,18 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, license);
licenseEntry = entry;
} else if (AndroidConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals(entry.getName())) {
List<Device> deviceList = AndroidAPIUtils.
getDeviceManagementService().
getAllDevices(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, false);
List<DeviceIdentifier> deviceIdList = new ArrayList<>();
for (Device device : deviceList) {
if (EnrolmentInfo.Status.REMOVED != device.getEnrolmentInfo().getStatus()) {
deviceIdList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
}
if (!deviceIdList.isEmpty()) {
if (entry.getValue() != null) {
NotifierFrequency notifierFrequency = new NotifierFrequency();
notifierFrequency.setValue(Integer.parseInt(entry.getValue().toString()));
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.NOTIFIER_FREQUENCY);
operation.setPayLoad(notifierFrequency.toJSON());
operation.setEnabled(true);
AndroidAPIUtils.getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID,
operation, deviceIdList);
} else {
return Response.status(Response.Status.BAD_REQUEST)
.entity("No value specified for notifierFrequency.").build();
}
} else if (AndroidConstants.TenantConfigProperties.NOTIFIER_TYPE.equals(entry.getName())) {
if (entry.getValue() != null) {
notifierFrequency.setType(Integer.parseInt(entry.getValue().toString()));
} else {
return Response.status(Response.Status.BAD_REQUEST)
.entity("No value specified for notifierType.").build();
}
}
}
@ -178,6 +167,7 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
}
configuration.setConfiguration(configs);
AndroidAPIUtils.getDeviceManagementService().saveConfiguration(configuration);
notifyDevices(notifierFrequency);
} catch (DeviceManagementException e) {
msg = "Error occurred while modifying configuration settings of Android platform";
log.error(msg, e);
@ -203,6 +193,27 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
.entity("Android platform configuration has been updated successfully.").build();
}
private void notifyDevices(NotifierFrequency notifierFrequency) throws DeviceManagementException,
OperationManagementException, InvalidDeviceException {
List<Device> deviceList = AndroidAPIUtils.
getDeviceManagementService().
getAllDevices(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, false);
List<DeviceIdentifier> deviceIdList = new ArrayList<>();
for (Device device : deviceList) {
if (EnrolmentInfo.Status.REMOVED != device.getEnrolmentInfo().getStatus()) {
deviceIdList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
}
if (!deviceIdList.isEmpty()) {
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.NOTIFIER_FREQUENCY);
operation.setPayLoad(notifierFrequency.toJSON());
operation.setEnabled(true);
AndroidAPIUtils.getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID,
operation, deviceIdList);
}
}
@GET
@Path("/license")

@ -160,6 +160,7 @@ public final class AndroidConstants {
public static final String LANGUAGE_US = "en_US";
public static final String CONTENT_TYPE_TEXT = "text";
public static final String NOTIFIER_FREQUENCY = "notifierFrequency";
public static final String NOTIFIER_TYPE = "notifierType";
public static final String SERVER_VERSION = "serverVersion";
}

@ -26,6 +26,7 @@ import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
@ -40,6 +41,7 @@ import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationExecu
import org.wso2.carbon.device.mgt.common.push.notification.NotificationStrategy;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion;
import org.wso2.carbon.device.mgt.core.geo.GeoCluster;
import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
@ -126,6 +128,15 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
}
}
@Override
public Device getDevice(String s, boolean b) throws DeviceManagementException {
if (TestUtils.getDeviceId().equals(s)) {
return TestUtils.getDevice();
} else {
return null;
}
}
@Override
public Device getDevice(DeviceIdentifier deviceIdentifier, String s, boolean b) throws DeviceManagementException {
return null;
@ -141,6 +152,14 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
return null;
}
@Override
public Device getDevice(String s, Date date, boolean b) throws DeviceManagementException {
if (TestUtils.getDeviceId().equals(s)) {
return TestUtils.getDevice();
} else {
return null;
} }
@Override
public Device getDevice(DeviceIdentifier deviceIdentifier, String s, Date date, boolean b)
throws DeviceManagementException {
@ -338,6 +357,11 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
return TestUtils.getDeviceId().equals(deviceIdentifier.getId());
}
@Override
public boolean deleteDevice(DeviceIdentifier deviceIdentifier) throws DeviceManagementException {
return false;
}
@Override
public boolean isEnrolled(DeviceIdentifier deviceIdentifier) throws DeviceManagementException {
return false;
@ -509,6 +533,11 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
return null;
}
@Override
public List<String> getStartupOperations(String s) {
return null;
}
@Override
public int getDeviceMonitoringFrequency(String s) {
return 0;
@ -519,6 +548,11 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
return null;
}
@Override
public StartupOperationConfig getStartupOperationConfig(String s) {
return null;
}
@Override
public boolean isDeviceMonitoringEnabled(String s) {
return false;
@ -588,4 +622,26 @@ public class DeviceManagementProviderServiceMock implements DeviceManagementProv
public boolean updateEnrollment(String owner, List<String> deviceIdentifiers) {
return false;
}
@Override public boolean addDeviceTypeVersion(DeviceTypeVersion deviceTypeVersion)
throws DeviceManagementException {
return false;
}
@Override public List<DeviceTypeVersion> getDeviceTypeVersions(String s) throws DeviceManagementException {
return null;
}
@Override public boolean updateDeviceTypeVersion(DeviceTypeVersion deviceTypeVersion)
throws DeviceManagementException {
return false;
}
@Override public boolean isDeviceTypeVersionChangeAuthorized(String s, String s1) throws DeviceManagementException {
return false;
}
@Override public DeviceTypeVersion getDeviceTypeVersion(String s, String s1) throws DeviceManagementException {
return null;
}
}

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -31,6 +31,9 @@
<zipfileset
dir="target/"
includes="JavaApp.jar" fullpath="JavaApp.jar"/>
<zipfileset
dir="target/"
includes="client-debug.apk" fullpath="resources/client-debug.apk"/>
<zipfileset dir="${src-dir}/" includes="startEmulator.sh" filemode="755"/>
<zipfileset dir="${src-dir}"/>
</zip>

@ -23,16 +23,29 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.mobile.android.ui</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<name>WSO2 Carbon - Mobile Android UI</name>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>io.entgra.emm</groupId>
<artifactId>io.entgra.emm.android.agent.release</artifactId>
<type>apk</type>
</dependency>
<dependency>
<groupId>io.entgra.emm</groupId>
<artifactId>io.entgra.emm.android.agent.debug</artifactId>
<type>apk</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@ -56,6 +69,24 @@
</outputDirectory>
<destFileName>JavaApp.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>io.entgra.emm</groupId>
<artifactId>io.entgra.emm.android.agent.release</artifactId>
<type>apk</type>
<version>${android.agent.version}</version>
<overWrite>true</overWrite>
<outputDirectory>${project.basedir}/target/</outputDirectory>
<destFileName>android-agent.apk</destFileName>
</artifactItem>
<artifactItem>
<groupId>io.entgra.emm</groupId>
<artifactId>io.entgra.emm.android.agent.debug</artifactId>
<type>apk</type>
<version>${android.agent.version}</version>
<overWrite>true</overWrite>
<outputDirectory>${project.basedir}/target/</outputDirectory>
<destFileName>client-debug.apk</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>

@ -42,5 +42,13 @@
</outputDirectory>
<fileMode>755</fileMode>
</file>
<file>
<source>
${basedir}/target/android-agent.apk
</source>
<outputDirectory>/devicemgt/app/units/cdmf.unit.device.type.android.type-view/public/assets/
</outputDirectory>
<fileMode>755</fileMode>
</file>
</files>
</assembly>

@ -16,7 +16,7 @@
data-type="{{device.type}}"
data-ownership="{{device.ownership}}"
data-owner="{{device.owner}}"
data-status="{{device.status}}"
data-status="{{devicamera-enabledce.status}}"
data-deviceinfoservice="{{device.deviceInfoServiceAPI}}"
data-devicelocationservice="{{device.deviceLocationServiceAPI}}">
{{device.owner}}'s {{device.name}}

@ -101,9 +101,9 @@
{{#equal this.type "select"}}
<div class="form-group">
<select class="form-control" id="{{this.id}}">
<option>{{this.valueOne}}</option>
<option>{{this.valueTwo}}</option>
<option>{{this.valueThree}}</option>
{{#each this.value}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
{{/equal}}

@ -16,6 +16,24 @@
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.
*/
/*
* On operation click function.
* @param selection: Selected operation
@ -115,41 +133,41 @@ function submitForm(formId) {
$('#' + formId + " .lbl-execution").removeClass("hidden");
var form = $("#" + formId);
var uri = form.attr("action");
var deviceId = form.data("device-id");
var deviceIdList = form.data("device-id");
var contentType = form.data("content-type");
var operationCode = form.data("operation-code");
var uriencodedQueryStr = "";
var uriencodedFormStr = "";
var uriEncodedQueryStr = "";
var uriEncodedFormStr = "";
var payload = {};
form.find("input").each(function () {
var input = $(this);
if (input.data("param-type") == "path") {
var prefix;
if (input.data("param-type") === "path") {
uri = uri.replace("{" + input.attr("id") + "}", input.val());
} else if (input.data("param-type") == "query") {
var prefix = (uriencodedQueryStr == "") ? "?" : "&";
uriencodedQueryStr += prefix + input.attr("id") + "=" + input.val();
} else if (input.data("param-type") == "form") {
var prefix = (uriencodedFormStr == "") ? "" : "&";
uriencodedFormStr += prefix + input.attr("id") + "=" + input.val();
if (input.attr("type") == "text" || input.attr("type") == "password") {
} else if (input.data("param-type") === "query") {
prefix = !uriEncodedQueryStr ? "?" : "&";
uriEncodedQueryStr += prefix + input.attr("id") + "=" + input.val();
} else if (input.data("param-type") === "form") {
prefix = !uriEncodedFormStr ? "" : "&";
uriEncodedFormStr += prefix + input.attr("id") + "=" + input.val();
if (input.attr("type") === "text" || input.attr("type") === "password") {
payload[input.attr("id")] = input.val();
} else if (input.attr("type") == "checkbox") {
} else if (input.attr("type") === "checkbox") {
payload[input.attr("id")] = input.is(":checked");
} else if (input.attr("type") == "radio") {
} else if (input.attr("type") === "radio") {
payload[input.attr("id")] = input.is(":checked");
}
}
});
uri += uriencodedQueryStr;
uri += uriEncodedQueryStr;
var httpMethod = form.attr("method").toUpperCase();
//var contentType = form.attr("enctype");
var validaterString = validatePayload(operationCode, payload);
var validateString = validatePayload(operationCode, payload);
if (validaterString == "OK") {
if (validateString === "OK") {
if (contentType == undefined || contentType == "") {
if (!contentType) {
contentType = "application/x-www-form-urlencoded";
payload = uriencodedFormStr;
payload = uriEncodedFormStr;
}
//setting responses callbacks
@ -179,7 +197,7 @@ function submitForm(formId) {
// console.log(response);
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
var reason = (response.responseText == "null") ? response.statusText : response.responseText;
var reason = (response.responseText === "null") ? response.statusText : response.responseText;
try {
reason = JSON.parse(reason).message;
} catch (err) {
@ -191,15 +209,15 @@ function submitForm(formId) {
$(modalPopupContent).html(content.html());
};
//executing http request
if (httpMethod == "GET") {
if (httpMethod === "GET") {
invokerUtil.get(uri, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "POST") {
var deviceList = [deviceId];
} else if (httpMethod === "POST") {
var deviceList = deviceIdList.split(",");
payload = generatePayload(operationCode, payload, deviceList);
invokerUtil.post(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "PUT") {
} else if (httpMethod === "PUT") {
invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "DELETE") {
} else if (httpMethod === "DELETE") {
invokerUtil.delete(uri, successCallBack, errorCallBack, contentType);
} else {
title.html("An Error Occurred!");
@ -210,7 +228,7 @@ function submitForm(formId) {
}
} else {
resetLoader(formId);
$(".modal #operation-error-msg span").text(validaterString);
$(".modal #operation-error-msg span").text(validateString);
$(".modal #operation-error-msg").removeClass("hidden");
}
}
@ -337,7 +355,15 @@ var generatePayload = function (operationCode, operationData, deviceList) {
"ENSURE_VERIFY_APPS": operationData["ensureVerifyApps"],
"AUTO_TIME": operationData["enableAutoTime"],
"SET_SCREEN_CAPTURE_DISABLED": operationData["disableScreenCapture"],
"SET_STATUS_BAR_DISABLED": operationData["disableStatusBar"]
"SET_STATUS_BAR_DISABLED": operationData["disableStatusBar"],
"DISALLOW_SET_WALLPAPER": operationData["disallowSetWallpaper"],
"DISALLOW_SET_USER_ICON": operationData["disallowSetUserIcon"],
"DISALLOW_REMOVE_MANAGEMENT_PROFILE": operationData["disallowRemoveManagedProfile"],
"DISALLOW_AUTOFILL": operationData["disallowAutoFill"],
"DISALLOW_BLUETOOTH": operationData["disallowBluetooth"],
"DISALLOW_BLUETOOTH_SHARING": operationData["disallowBluetoothSharing"],
"DISALLOW_REMOVE_USER": operationData["disallowRemoveUser"],
"DISALLOW_DATA_ROAMING": operationData["disallowDataRoaming"]
}
};
break;
@ -468,7 +494,7 @@ var generatePayload = function (operationCode, operationData, deviceList) {
break;
case androidOperationConstants["SYSTEM_UPDATE_POLICY_CODE"]:
operationType = operationTypeConstants["PROFILE"];
if (operationData["cosuSystemUpdatePolicyType"] != "window") {
if (operationData["cosuSystemUpdatePolicyType"] !== "window") {
payload = {
"operation": {
"type": operationData["cosuSystemUpdatePolicyType"]
@ -508,7 +534,7 @@ var generatePayload = function (operationCode, operationData, deviceList) {
payload = deviceList;
}
if (operationType == operationTypeConstants["PROFILE"] && deviceList) {
if (operationType === operationTypeConstants["PROFILE"] && deviceList) {
payload["deviceIDs"] = deviceList;
}
return payload;
@ -565,5 +591,13 @@ var androidOperationConstants = {
"SYSTEM_UPDATE_POLICY_CODE": "SYSTEM_UPDATE_POLICY",
"KIOSK_APPS_CODE": "KIOSK_APPS",
"FILE_TRANSFER": "FILE_TRANSFER",
"APP_RESTRICTION_OPERATION_CODE": "REMOTE_APP_CONFIG"
"APP_RESTRICTION_OPERATION_CODE": "REMOTE_APP_CONFIG",
"DISALLOW_SET_WALLPAPER": "DISALLOW_SET_WALLPAPER",
"DISALLOW_SET_USER_ICON": "DISALLOW_SET_USER_ICON",
"DISALLOW_REMOVE_MANAGEMENT_PROFILE": "DISALLOW_REMOVE_MANAGEMENT_PROFILE",
"DISALLOW_AUTOFILL": "DISALLOW_AUTOFILL",
"DISALLOW_BLUETOOTH": "DISALLOW_BLUETOOTH",
"DISALLOW_BLUETOOTH_SHARING": "DISALLOW_BLUETOOTH_SHARING",
"DISALLOW_REMOVE_USER": "DISALLOW_REMOVE_USER",
"DISALLOW_DATA_ROAMING": "DISALLOW_DATA_ROAMING"
};

@ -0,0 +1,184 @@
{{!
Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
Entgra (Pvt) Ltd. 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.
}}
{{#if controlOperations}}
<div class="wr-operations" style="height: 87px; display: block;"
xmlns="http://www.w3.org/1999/html">
<style>
::-webkit-input-placeholder {
color: #B8B8B8;
}
::-moz-placeholder {
color: #B8B8B8;
}
:-ms-input-placeholder {
color: #B8B8B8;
}
input:-moz-placeholder {
color: #B8B8B8;
}
</style>
{{#each controlOperations}}
<a {{#unless isDisabled}} href="javascript:operationSelect('{{operation}}')" {{else}} href="javascript:void(0)" class="op-disabled" title="{{disabledText}}" data-toggle="tooltip" {{/unless}}>
{{#if iconFont}}
<i class="fw {{iconFont}}"></i>
{{else}}
{{#if icon}}
<img src="{{@app.context}}/{{icon}}" style="width: 48px;"/>
{{else}}
<i class="fw fw-service"></i>
{{/if}}
{{/if}}
<span>{{name}}</span>
</a>
<div class="operation" data-operation-code="{{operation}}">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw {{iconFont}} fw-stack-1x"></i>
</span>
{{name}}
<br>
</h3>
<h4>
{{description}}
<br>
</h4>
<div id="operation-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div id="operation-warn-msg" class="info alert-info hidden" role="alert">
<i class="icon fw fw-info"></i><span></span>
</div>
<div id="operation-form">
<form id="form-{{operation}}" action="{{params.0.uri}}" method="{{params.0.method}}"
style="padding-bottom: 20px;"
data-payload="{{payload}}"
data-device-id="{{../devices}}"
data-content-type="{{params.0.contentType}}"
data-operation-code="{{operation}}">
{{#each params.0.pathParams}}
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control"
data-param-type="path" value="{{value}}"/>
<br/>
{{/each}}
{{#each params.0.formParams}}
<input type="{{type}}" id="{{name}}" name="{{name}}" placeholder="{{name}}"
class="form-control" data-param-type="form" value="{{value}}"/>
<br/>
{{/each}}
{{#each params.0.queryParams}}
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control"
data-param-type="query" value="{{value}}"/>
<br/>
{{/each}}
{{#each uiParams}}
{{#equal this.type "select"}}
<div class="form-group">
<select class="form-control" id="{{this.id}}">
{{#each this.value}}
<option>{{this}}</option>
{{/each}}
</select>
</div>
{{/equal}}
{{#equal this.type "radio"}}
<input type="radio" id="{{this.id}}"
name="{{this.name}}"
value="{{this.value}}"
class="radio"
checked="checked"
data-param-type="form"/>
{{this.value}}
{{/equal}}
{{#equal this.type "checkbox"}}
<input type="{{this.type}}" id="{{this.id}}"
class="checkbox"
placeholder="{{this.label}}"
data-param-type="form"/>
{{this.label}}
<br/>
{{/equal}}
{{#equal this.type "password"}}
<input type="{{this.type}}" id="{{this.id}}"
placeholder="{{this.label}}" class="form-control"
data-param-type="form" value=""/>
<br/>
{{/equal}}
{{#equal this.type "text"}}
<input type="{{this.type}}" id="{{this.id}}"
placeholder="{{this.label}}" class="form-control"
data-param-type="form" value=""/>
<br/>
{{/equal}}
{{#equal this.type "info"}}
<div class="form-group" id="{{this.id}}">
<span class="help-block">
{{this.value}}
</span>
</div>
{{/equal}}
{{/each}}
<button type="button" onclick="submitForm('form-{{operation}}')"
class="btn btn-default btnSend">Send
to Device</button>
<label class="wr-input-label hidden"><i
class="fw fw-lifecycle fw-spin fw-2x lblSending"></i> Sending..</label>
<label class="wr-input-label hidden"><i
class="fw fw-check fw-2x lblSent"></i> Sent</label>
<i class="fw fw-wso2-logo fw-pulse fw-2x hidden lbl-execution"> Executing Operation </i>
</form>
</div>
</div>
</div>
</div>
</div>
{{/each}}
</div>
{{/if}}
<div id="operation-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack center-block">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>

@ -100,7 +100,16 @@ var androidOperationModule = function () {
"COSU_PROFILE_CONFIGURATION_OPERATION": "cosu-profile-configuration",
"COSU_PROFILE_CONFIGURATION_OPERATION_CODE": "COSU_PROFILE",
"ENROLLMENT_APP_INSTALL": "enrollment-app-install",
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL"
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL",
"DISALLOW_SET_WALLPAPER": "DISALLOW_SET_WALLPAPER",
"DISALLOW_SET_USER_ICON": "DISALLOW_SET_USER_ICON",
"DISALLOW_REMOVE_MANAGEMENT_PROFILE": "DISALLOW_REMOVE_MANAGEMENT_PROFILE",
"DISALLOW_AUTOFILL": "DISALLOW_AUTOFILL",
"DISALLOW_BLUETOOTH": "DISALLOW_BLUETOOTH",
"DISALLOW_BLUETOOTH_SHARING": "DISALLOW_BLUETOOTH_SHARING",
"DISALLOW_REMOVE_USER": "DISALLOW_REMOVE_USER",
"DISALLOW_DATA_ROAMING": "DISALLOW_DATA_ROAMING",
"CERT_ADD_OPERATION_CODE": "INSTALL_CERT"
};
/**
@ -300,6 +309,17 @@ var androidOperationModule = function () {
"enrollmentAppInstall": operationPayload["enrollmentAppInstall"]
};
break;
case androidOperationConstants["CERT_ADD_OPERATION_CODE"]:
var certList = operationPayload["CERT_LIST"];
var listNew = [];
certList.forEach(function (element) {
element["CERT_CONTENT_VIEW"] = element["CERT_NAME"] + " File";
listNew.push(element);
});
payload = {
"CERT_LIST": listNew
};
break;
}
return payload;
};
@ -345,7 +365,14 @@ var androidOperationModule = function () {
"ENSURE_VERIFY_APPS": operationData["ensureVerifyApps"],
"AUTO_TIME": operationData["enableAutoTime"],
"SET_SCREEN_CAPTURE_DISABLED": operationData["disableScreenCapture"],
"SET_STATUS_BAR_DISABLED": operationData["disableStatusBar"]
"DISALLOW_SET_WALLPAPER": operationData["disallowSetWallpaper"],
"DISALLOW_SET_USER_ICON": operationData["disallowSetWallpaper"],
"DISALLOW_REMOVE_MANAGEMENT_PROFILE": operationData["disallowRemoveManagedProfile"],
"DISALLOW_AUTOFILL": operationData["disallowAutoFill"],
"DISALLOW_BLUETOOTH": operationData["disallowBluetooth"],
"DISALLOW_BLUETOOTH_SHARING": operationData["disallowBluetoothSharing"],
"DISALLOW_REMOVE_USER": operationData["disallowRemoveUser"],
"DISALLOW_DATA_ROAMING": operationData["disallowDataRoaming"]
}
};
break;
@ -653,6 +680,14 @@ var androidOperationModule = function () {
}
};
break;
case androidOperationConstants["CERT_ADD_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"CERT_LIST": operationData["CERT_LIST"]
}
};
break;
default:
// If the operation is neither of above, it is a command operation
operationType = operationTypeConstants["COMMAND"];
@ -1202,6 +1237,30 @@ var androidOperationModule = function () {
} else if (featureCode == androidOperationConstants["SET_STATUS_BAR_DISABLED"]) {
restrictions["disableStatusBar"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_SET_WALLPAPER"]) {
restrictions["disallowSetWallpaper"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_SET_USER_ICON"]) {
restrictions["disallowSetUserIcon"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_REMOVE_MANAGEMENT_PROFILE"]) {
restrictions["disallowRemoveManagedProfile"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_AUTOFILL"]) {
restrictions["disallowAutoFill"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_BLUETOOTH"]) {
restrictions["disallowBluetooth"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_BLUETOOTH_SHARING"]) {
restrictions["disallowBluetoothSharing"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_REMOVE_USER"]) {
restrictions["disallowRemoveUser"] = restriction["enabled"];
continue;
}else if (featureCode == androidOperationConstants["DISALLOW_DATA_ROAMING"]) {
restrictions["disallowDataRoaming"] = restriction["enabled"];
continue;
}
//push the feature-code to the configuration array
configuredOperations.push(featureCode);

@ -91,7 +91,7 @@
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<br>
( ex: org.wso2.iot.agent/org.wso2.iot.agent.services.AgentDeviceAdminReceiver )
( ex: io.entgra.iot.agent/org.wso2.iot.agent.services.AgentDeviceAdminReceiver )
</label>
<input id="android-kiosk-config-admin-component" type="text" class="form-control" >
</div>
@ -132,6 +132,22 @@
<input id="android-kiosk-config-wifi-ssid" type="text" class="form-control" >
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="android-kiosk-config-wifi-sec">
PROVISIONING_WIFI_SECURITY_TYPE
<!--<span class="helper" title="Time interval after which Android agent will contact IoT Server each time to fetch data">-->
<!--<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>-->
<!--</span>-->
<br>
</label>
<select id="android-kiosk-config-wifi-sec" class="form-control" data-default="0">
<option value="NONE">NONE</option>
<option value="WPA">WPA</option>
<option value="WEP">WEP</option>
<option value="EAP">EAP</option>
</select>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="android-kiosk-config-wifi-password">
PROVISIONING_WIFI_PASSWORD

@ -84,6 +84,7 @@ var kioskConfigs = {
"adminComponentName" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME",
"wifiSSID" : "android.app.extra.PROVISIONING_WIFI_SSID",
"wifiPassword" : "android.app.extra.PROVISIONING_WIFI_PASSWORD",
"wifiSecurity" : "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE",
"skipEncryption" : "android.app.extra.PROVISIONING_SKIP_ENCRYPTION",
"checksum" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM",
"downloadURL" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"
@ -139,6 +140,8 @@ $(document).ready(function () {
$("input#android-kiosk-config-admin-component").val(config.value);
} else if (config.name === kioskConfigs["wifiSSID"]) {
$("input#android-kiosk-config-wifi-ssid").val(config.value);
} else if (config.name === kioskConfigs["wifiSecurity"]) {
$("#android-kiosk-config-wifi-sec").val(config.value);
} else if (config.name === kioskConfigs["wifiPassword"]) {
$("input#android-kiosk-config-wifi-password").val(config.value);
} else if (config.name === kioskConfigs["checksum"]) {
@ -190,6 +193,7 @@ $(document).ready(function () {
var wifiSSID = $("input#android-kiosk-config-wifi-ssid").val();
var wifiPassword = $("input#android-kiosk-config-wifi-password").val();
var encryption = $("#android-kiosk-config-encryption").find("option:selected").attr("value");
var wifiSecurity = $("#android-kiosk-config-wifi-sec").find("option:selected").attr("value");
if (notifierType === notifierTypeConstants["LOCAL"] && !notifierFrequency) {
$(errorMsg).text("Notifier frequency is a required field. It cannot be empty.");
@ -259,6 +263,12 @@ $(document).ready(function () {
"contentType": "text"
};
var kioskWifiSecurity = {
"name": kioskConfigs["wifiSecurity"],
"value": wifiSecurity,
"contentType": "text"
};
var kioskWifiPassword = {
"name": kioskConfigs["wifiPassword"],
"value": wifiPassword,
@ -281,6 +291,7 @@ $(document).ready(function () {
configList.push(kioskEncryption);
configList.push(kioskWifiSSID);
configList.push(kioskWifiPassword);
configList.push(kioskWifiSecurity);
if (notifierType === notifierTypeConstants["FCM"]) {
configList.push(fcmKey);

@ -58,7 +58,8 @@ var androidOperationConstants = {
"COSU_PROFILE_CONFIGURATION_OPERATION": "cosu-profile-configuration",
"COSU_PROFILE_CONFIGURATION_OPERATION_CODE": "COSU_PROFILE",
"ENROLLMENT_APP_INSTALL": "enrollment-app-install",
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL"
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL",
"CERT_ADD_OPERATION_CODE": "INSTALL_CERT"
};
/**
@ -172,6 +173,29 @@ var ovpnConfigUploaded = function () {
}
};
var certConfigUploaded = function (val) {
var certFileInput = document.getElementById("cert-file-field");
if ('files' in certFileInput) {
if (certFileInput.files.length === 1) {
var reader = new FileReader();
reader.onload = function (progressEvent) {
var txt = "";
var lines = this.result.split('\n');
for (var line = 0; line < lines.length; line++) {
console.log(lines[line]);
if (lines[line].charAt(0) !== '#') {
txt += lines[line] + '\n';
}
}
//document.getElementById ("cert-config").value = txt;
//console.log(document.getElementById ("cert-config").value);
$(val).next().val(txt);
};
reader.readAsText(certFileInput.files[0]);
}
}
};
/**
* Validates policy profile operations for the windows platform.
*
@ -828,6 +852,32 @@ var validatePolicyProfile = function () {
}
validationStatusArray.push(validationStatus);
}
if ($.inArray(androidOperationConstants["CERT_ADD_OPERATION_CODE"], configuredOperations) != -1) {
//If enrollment app install configured
let isErrorsFound = false;
operation = androidOperationConstants["CERT_ADD_OPERATION_CODE"];
var certList = $("#cert-list").find(".child-input");
for (let j = 0; j < certList.length; j++) {
if ($(certList[j]).val().trim() === "") {
isErrorsFound = true;
break;
}
}
if (isErrorsFound) {
validationStatus = {
"error": true,
"subErrorMsg": "Certificates are not selected to be installed.",
"erroneousFeature": operation
};
validationStatusArray.push(validationStatus);
} else {
validationStatus = {
"error": false,
"okFeature": operation
};
validationStatusArray.push(validationStatus);
}
}
}
// ending validation process
@ -1141,6 +1191,16 @@ var applyDataTable = function() {
lengthMenu: [5, 10, 25, 50, 100]
});
};
var myFrom;
function appendCertInputField(inputElement) {
let element = "<input id=\"cert-file-field\" type=\"file\" class=\"form-control grid-input-text\"\n" +
" data-child-key=\"CERT_CONTENT_VIEW\" maxlength=\"100\" data-default=\"\"\n" +
" placeholder=\"Select certificate file\" onchange=\"certConfigUploaded(this)\"/>\n" +
"<input id=\"cert-config\" class=\"form-control operationDataKeys\" type=\"hidden\"\n" +
" data-child-key=\"CERT_CONTENT\"/>";
inputElement.append(element);
}
$(document).ready(function () {
// Maintains an array of configured features of the profile
@ -1297,15 +1357,23 @@ $(document).ready(function () {
updateGroupedInputVisibility(this);
});
// add form entry click function for grid inputs
$(advanceOperations).on("click", "[data-click-event=add-form]", function () {
$(advanceOperations).on("click", "[data-click-event=add-form]", function (event) {
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");
if ($(this).attr("href") === "#cert-grid") {
if (event.originalEvent !== undefined) {
let inputElement = $(clonedForm).children('td.cert-file-tr');
inputElement.find("input[type=text]").remove();
inputElement.find("input[type=hidden]").remove();
appendCertInputField(inputElement);
$("input, select", clonedForm).addClass("child-input");
}
}
$(addFormContainer).append(clonedForm);
setId(addFormContainer);
showHideHelpText(addFormContainer);

@ -76,6 +76,15 @@
<span id="vpn-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="vpn-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('cert', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security-policy fw-stack-2x"></i>
</span>
Secure Certificates
<span id="cert-configured" class="has-configured status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
{{#unless iscloud}}
<a href="javascript:void(0)" onclick="showAdvanceOperation('work-profile', this)">
<span class="wr-hidden-operations-icon fw-stack">
@ -356,6 +365,7 @@
<b>work-profile owner</b> or <b>device owner</b>.</a>
</ul>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-configuring-credentials-enabled" type="checkbox"
@ -495,6 +505,100 @@
</label>
</div>
<br>
<div>
<ul class="message message-info">
<i class="icon fw fw-info"></i>
<a id="policy-listing-status-msg">Below restrictions will be applied on devices with
Android
version 6.0 Marshmallow onwards only.</a>
</ul>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-set-wallpeper" type="checkbox"
class="operationDataKeys"
data-key="disallowSetWallpaper"/>
<span class="helper" title="Users are restricted from setting wallpapers.">
Disallow set wallpaper
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-set-user-icon" type="checkbox"
class="operationDataKeys"
data-key="disallowSetUserIcon"/>
<span class="helper" title="Users are restricted from changing their icon.">
Disallow set user icon
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-remove-managed-profile" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveManagedProfile"/>
<span class="helper" title="Users are restricted from removing the managed profile.">
Disallow remove managed profile
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-autofill" type="checkbox"
class="operationDataKeys"
data-key="disallowAutoFill"/>
<span class="helper" title="Users are restricted from using Autofill services.">
Disallow autofill
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetooth"/>
<span class="helper" title="Bluetooth is disallowed on the device">
Disallow bluetooth
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth-sharing" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetoothSharing"/>
<span class="helper" title="Users are restricted from Bluetooth sharing on the device.">
Disallow bluetooth sharing
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-remove-user" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveUser"/>
<span class="helper" title="Users are restricted from removing user itself.">
Disallow remove user
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<br>
<div>
<ul class="message message-info">
<i class="icon fw fw-info"></i>
@ -502,6 +606,7 @@
<b>device owner</b>.</a>
</ul>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-SMS-enabled" type="checkbox" class="operationDataKeys"
@ -545,6 +650,7 @@
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="volume-adjust-enabled" type="checkbox" class="operationDataKeys"
@ -732,6 +838,7 @@
version 6.0 Marshmallow onwards only.</a>
</ul>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disable-status-bar-enabled" type="checkbox" class="operationDataKeys"
@ -743,6 +850,19 @@
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-data-roaming" type="checkbox"
class="operationDataKeys"
data-key="disallowDataRoaming"/>
<span class="helper"
title="Users are restricted from using cellular data when roaming.">
Disallow data roaming
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
{{/unless}}
</div>
</div>
@ -1306,6 +1426,107 @@
</div>
<!-- /VPN -->
<!--cert-->
<div class="wr-hidden-operation" data-operation="cert">
<div class="panel panel-default operation-data" data-operation="cert"
data-operation-code="INSTALL_CERT">
<div id="cert-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Secure Certificate Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#cert-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
Configure the Secure Certificate settings on Android devices.
</div>
</div>
<div id="cert-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="cert-body">
<hr/>
<div id="INSTALL_CERT-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="cert-list">
<br><br>Added Certificate List
<span class="helper" title="Add a certificate.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<br/>
<a href="#cert-grid" class="btn btn-secondary grid-input-add "
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-circle-outline fw-stack-2x"></i>
</span>
Add Certificate
</a>
<div id="cert-list"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="CERT_LIST" data-column-count="3">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Certificate Name</th>
<th>Certificate File</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#cert-grid" id="cert-table">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#cert-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="Cert Name">
<input type="text" class="form-control grid-input-text operationDataKeys"
data-child-key="CERT_NAME"
maxlength="100" placeholder="Cert Name"/>
</td>
<td data-title="Cert File" class="cert-file-tr">
<input type="text" class="form-control grid-input-text"
data-child-key="CERT_CONTENT_VIEW" maxlength="100" data-default=""
placeholder="Select certificate file" disabled/>
<input id="cert-config" class="form-control operationDataKeys" type="hidden"
data-child-key="CERT_CONTENT"/>
</td>
<td>
<span class="list-group-item-actions">
<a href="#cert-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--/cert-->
<!--Work-profile-->
<div class="wr-hidden-operation" data-operation="work-profile">
<div class="panel panel-default operation-data" data-operation="work-profile"

@ -59,6 +59,15 @@
<span id="wifi-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="wifi-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('cert', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security-policy fw-stack-2x"></i>
</span>
Secure Certificate
<span id="cert-configured" class="has-configured status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
{{#unless iscloud}}
<a href="javascript:void(0)" onclick="showAdvanceOperation('work-profile', this)">
<span class="wr-hidden-operations-icon fw-stack">
@ -729,6 +738,7 @@
</span>
</label>
</div>
<br>
<br>
<b>
@ -747,6 +757,109 @@
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-set-wallpeper" type="checkbox"
class="operationDataKeys"
data-key="disallowSetWallpaper" disabled/>
<span class="helper" title="Users are restricted from setting wallpapers.">
Disallow set wallpaper
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-set-user-icon" type="checkbox"
class="operationDataKeys"
data-key="disallowSetUserIcon" disabled/>
<span class="helper" title="Users are restricted from changing their icon.">
Disallow set user icon
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-remove-managed-profile" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveManagedProfile" disabled/>
<span class="helper" title="Users are restricted from removing the managed profile.">
Disallow Remove Managed Profile
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-autofill" type="checkbox"
class="operationDataKeys"
data-key="disallowAutoFill" disabled/>
<span class="helper" title="Users are restricted from using Autofill services.">
Disallow autofill
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetooth" disabled/>
<span class="helper" title="Bluetooth is disallowed on the device">
Disallow bluetooth
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth-sharing" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetoothSharing" disabled/>
<span class="helper" title="Users are restricted from Bluetooth sharing on the device.">
Disallow bluetooth sharing
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-remove-user" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveUser" disabled/>
<span class="helper" title="Users are restricted from removing user itself.">
Disallow remove user
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input id="disallow-data-roaming" type="checkbox"
class="operationDataKeys"
data-key="disallowDataRoaming" disabled/>
<span class="helper" title="Users are restricted from using cellular data when roaming.">
Disallow data roaming
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
{{/unless}}
</div>
</div>
@ -2202,6 +2315,104 @@
</div>
<!-- /VPN -->
<!-- Cert -->
<div class="wr-hidden-operation" data-operation="cert">
<div class="panel panel-default operation-data" data-operation="cert"
data-operation-code="INSTALL_CERT">
<div id="cert-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Secure Certificate Settings
<label class="wr-input-control switch hidden" data-toggle="collapse"
data-target="#cert-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
Configure the Secure Certificate settings on Android devices.
</div>
</div>
<div id="cert-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="cert-body">
<hr/>
<div id="cert-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="cert-list">
<br><br>Added Certificate List
<span class="helper" title="Add a certificate.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<br/>
<a href="#cert-grid" class="btn btn-secondary grid-input-add hidden"
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-circle-outline fw-stack-2x"></i>
</span>
Add Certificate
</a>
<div id="cert-list"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="CERT_LIST" data-column-count="3">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Certificate Name</th>
<th>Certificate File</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#cert-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#cert-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="Cert Name">
<input type="text" class="form-control grid-input-text operationDataKeys" data-child-key="CERT_NAME"
maxlength="100" placeholder="Cert Name" disabled/>
</td>
<td data-title="Cert File">
<input type="text" class="form-control grid-input-text"
data-child-key="CERT_CONTENT_VIEW" maxlength="100" data-default=""
placeholder="Select certificate file" disabled/>
</td>
<td>
<span class="list-group-item-actions hidden">
<a href="#cert-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- /Cert -->
<!-- install-applications -->
<!--<div class="wr-hidden-operation" data-operation="install-apps">-->
<!--<div class="panel panel-default operation-data" data-operation="INSTALL_APPLICATION">-->

@ -55,7 +55,8 @@ var androidOperationConstants = {
"COSU_PROFILE_CONFIGURATION_OPERATION": "cosu-profile-configuration",
"COSU_PROFILE_CONFIGURATION_OPERATION_CODE": "COSU_PROFILE",
"ENROLLMENT_APP_INSTALL": "enrollment-app-install",
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL"
"ENROLLMENT_APP_INSTALL_CODE": "ENROLLMENT_APP_INSTALL",
"CERTIFICATE_INSTALL": "INSTALL_CERT"
};
/**
@ -114,6 +115,30 @@ var ovpnConfigUploaded = function () {
}
};
var certConfigUploaded = function (val) {
var certFileInput = document.getElementById("cert-file-field");
if ('files' in certFileInput) {
if (certFileInput.files.length === 1) {
var reader = new FileReader();
reader.onload = function(progressEvent){
var txt = "";
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
console.log(lines[line]);
if (lines[line].charAt(0) !== '#') {
txt += lines[line] + '\n';
}
}
//document.getElementById ("cert-config").value = txt;
//console.log(document.getElementById ("cert-config").value);
$(val).next().val(txt);
};
reader.readAsText(certFileInput.files[0]);
}
}
};
/**
* Validates policy profile operations for the windows platform.
*
@ -761,6 +786,32 @@ var validatePolicyProfile = function () {
}
validationStatusArray.push(validationStatus);
}
if ($.inArray(androidOperationConstants["CERTIFICATE_INSTALL"], configuredOperations) != -1) {
//If enrollment app install configured
let isErrorsFound = false;
operation = androidOperationConstants["CERTIFICATE_INSTALL"];
var certList = $("#cert-list").find(".child-input");
for (let j = 0; j < certList.length; j++) {
if ($(certList[j]).val().trim() === "") {
isErrorsFound = true;
break;
}
}
if (isErrorsFound) {
validationStatus = {
"error": true,
"subErrorMsg": "Certificates are not selected to be installed.",
"erroneousFeature": operation
};
validationStatusArray.push(validationStatus);
} else {
validationStatus = {
"error": false,
"okFeature": operation
};
validationStatusArray.push(validationStatus);
}
}
}
// ending validation process

@ -76,6 +76,15 @@
<span id="vpn-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="vpn-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('cert', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-security-policy fw-stack-2x"></i>
</span>
Secure Certificate
<span id="cert-configured" class="has-configured status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-ok" class="has-success status-icon hidden"><i class="fw fw-success"></i></span>
<span id="cert-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a>
{{#unless iscloud}}
<a href="javascript:void(0)" class="worker-profile" onclick="showAdvanceOperation('work-profile', this)">
<span class="wr-hidden-operations-icon fw-stack">
@ -506,6 +515,98 @@
</label>
</div>
<br>
<div class="">
<ul class="message message-info">
<i class="icon fw fw-info"></i>
<a id="policy-listing-status-msg">Below restrictions will be applied on devices with
Android version 6.0 Marshmallow onwards only.</a>
</ul>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-set-wallpeper" type="checkbox"
class="operationDataKeys"
data-key="disallowSetWallpaper"/>
<span class="helper" title="Users are restricted from setting wallpapers.">
Disallow set wallpaper
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-set-user-icon" type="checkbox"
class="operationDataKeys"
data-key="disallowSetUserIcon"/>
<span class="helper" title="Users are restricted from changing their icon.">
Disallow set user icon
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-remove-managed-profile" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveManagedProfile"/>
<span class="helper" title="Users are restricted from removing the managed profile.">
Disallow Remove Managed Profile
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-autofill" type="checkbox"
class="operationDataKeys"
data-key="disallowAutoFill"/>
<span class="helper" title="Users are restricted from using Autofill services.">
Disallow autofill
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetooth"/>
<span class="helper" title="Bluetooth is disallowed on the device">
Disallow bluetooth
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-bluetooth-sharing" type="checkbox"
class="operationDataKeys"
data-key="disallowBluetoothSharing"/>
<span class="helper" title="Users are restricted from Bluetooth sharing on the device.">
Disallow bluetooth sharing
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="wr-input-control worker-profile-or-owner">
<label class="wr-input-control checkbox">
<input id="disallow-remove-user" type="checkbox"
class="operationDataKeys"
data-key="disallowRemoveUser"/>
<span class="helper" title="Users are restricted from removing user itself.">
Disallow remove user
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
<div class="device-owner">
<ul class="message message-info device-owner">
<i class="icon fw fw-info"></i>
@ -558,6 +659,7 @@
</span>
</label>
</div>
<br>
<div class="wr-input-control device-owner">
<label class="wr-input-control checkbox">
<input id="volume-adjust-enabled" type="checkbox" class="operationDataKeys"
@ -766,6 +868,18 @@
</label>
</div>
<br>
<div class="wr-input-control device-owner">
<label class="wr-input-control checkbox">
<input id="disallow-data-roaming" type="checkbox"
class="operationDataKeys"
data-key="disallowDataRoaming"/>
<span class="helper" title="Users are restricted from using cellular data when roaming.">
Disallow data roaming
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
</div>
<br>
{{/unless}}
</div>
</div>
@ -2225,6 +2339,109 @@
</div>
<!-- /VPN -->
<!--cert-->
<div class="wr-hidden-operation" data-operation="cert">
<div class="panel panel-default operation-data" data-operation="cert"
data-operation-code="INSTALL_CERT">
<div id="cert-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Secure Certificate Settings
<label class="wr-input-control switch" data-toggle="collapse"
data-target="#cert-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
Configure the Secure Certificate settings on Android devices.
</div>
</div>
<div id="cert-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="cert-body">
<hr/>
<div id="INSTALL_CERT-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="wr-input-control">
<label class="wr-input-label" for="cert-list">
<br><br>Added Certificate List
<span class="helper" title="Add a certificate.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
</label>
<br/>
<a href="#cert-grid" class="btn btn-secondary grid-input-add "
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-circle-outline fw-stack-2x"></i>
</span>
Add Certificate
</a>
<div id="cert-list"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="CERT_LIST" data-column-count="3">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Certificate Name</th>
<th>Certificate File</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#cert-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#cert-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="Cert Name">
<input id="cert-name-field" type="text" class="form-control grid-input-text operationDataKeys" data-child-key="CERT_NAME"
maxlength="100" placeholder="Cert Name"/>
<!--<input id="cert-name" class="form-control operationDataKeys" type="hidden"
data-key="CERT_NAME"/>-->
</td>
<td data-title="Cert File">
<input id="cert-file-field" type="file" class="form-control grid-input-text"
data-child-key="CERT_CONTENT" maxlength="100" data-default=""
placeholder="Select certificate file" onchange="certConfigUploaded(this)"/>
<input id="cert-config" class="form-control operationDataKeys" type="hidden"
data-child-key="CERT_CONTENT"/>
</td>
<td>
<span class="list-group-item-actions">
<a href="#cert-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--/cert-->
<!--Work-profile-->
<div class="wr-hidden-operation" data-operation="work-profile">
<div class="panel panel-default operation-data" data-operation="work-profile"

@ -35,6 +35,7 @@ var kioskConfigs = {
"adminComponentName" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME",
"wifiSSID" : "android.app.extra.PROVISIONING_WIFI_SSID",
"wifiPassword" : "android.app.extra.PROVISIONING_WIFI_PASSWORD",
"wifiSecurity" : "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE",
"skipEncryption" : "android.app.extra.PROVISIONING_SKIP_ENCRYPTION",
"checksum" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM",
"downloadURL" : "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION",
@ -108,6 +109,8 @@ function generateKIOSKQRCode(qrCodeClass) {
payload[config.name] = config.value;
} else if (config.name === kioskConfigs["wifiPassword"]) {
payload[config.name] = config.value;
} else if (config.name === kioskConfigs["wifiSecurity"]) {
payload[config.name] = config.value;
} else if (config.name === kioskConfigs["checksum"]) {
payload[config.name] = config.value;
} else if (config.name === kioskConfigs["downloadURL"]) {

@ -22,7 +22,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -46,7 +46,6 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.0</version>
<extensions>true</extensions>
<configuration>
<instructions>

@ -14,6 +14,22 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl;
@ -25,6 +41,7 @@ import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
@ -34,6 +51,7 @@ import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformDetails;
import org.wso2.carbon.device.mgt.mobile.android.impl.util.AndroidPluginConstants;
import org.wso2.carbon.device.mgt.mobile.android.internal.AndroidDeviceManagementDataHolder;
@ -123,6 +141,11 @@ public class AndroidDeviceManagementService implements DeviceManagementService {
return null;
}
@Override
public StartupOperationConfig getStartupOperationConfig() {
return null;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return null;
@ -138,6 +161,9 @@ public class AndroidDeviceManagementService implements DeviceManagementService {
return null;
}
@Override
public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; }
private String getConfigProperty(List<ConfigurationEntry> configs, String propertyName) {
for (ConfigurationEntry entry : configs) {
if (propertyName.equals(entry.getName())) {

@ -16,8 +16,28 @@
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Feature;
@ -32,6 +52,7 @@ import org.wso2.carbon.device.mgt.mobile.android.impl.util.MobileDeviceManagemen
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class AndroidFeatureManager implements FeatureManager {
@ -97,11 +118,40 @@ public class AndroidFeatureManager implements FeatureManager {
public List<Feature> getFeatures() throws DeviceManagementException {
try {
List<MobileFeature> mobileFeatures = featureDAO.getAllFeatures();
List<Feature> featureList = new ArrayList<Feature>(mobileFeatures.size());
for (MobileFeature mobileFeature : mobileFeatures) {
featureList.add(MobileDeviceManagementUtil.convertToFeature(mobileFeature));
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
}
}
@Override
public List<Feature> getFeatures(String featureType) throws DeviceManagementException {
if (StringUtils.isEmpty(featureType)) {
return this.getFeatures();
}
return featureList;
try {
List<MobileFeature> mobileFeatures = featureDAO.getFeaturesByFeatureType(featureType);
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
}
}
@Override
public List<Feature> getFeatures(String featureType, boolean isHidden) throws DeviceManagementException {
try {
List<MobileFeature> mobileFeatures;
if (StringUtils.isNotEmpty(featureType)) {
mobileFeatures = featureDAO.getFeaturesByFeatureType(featureType, isHidden);
} else {
mobileFeatures = featureDAO.getAllFeatures(isHidden);
}
return mobileFeatures.stream().map(MobileDeviceManagementUtil::convertToFeature).collect(
Collectors.toList());
} catch (MobileDeviceManagementDAOException e) {
throw new DeviceManagementException("Error occurred while retrieving the list of features registered for " +
"Android platform", e);
@ -469,6 +519,54 @@ public class AndroidFeatureManager implements FeatureManager {
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SET_WALLPAPER");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_SET_USER_ICON");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_REMOVE_MANAGEMENT_PROFILE");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_AUTOFILL");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_BLUETOOTH");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_BLUETOOTH_SHARING");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_REMOVE_USER");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
feature = new Feature();
feature.setCode("DISALLOW_DATA_ROAMING");
feature.setName("Device Unlock");
feature.setDescription("Unlock the device");
supportedFeatures.add(feature);
return supportedFeatures;
}
}

@ -16,6 +16,24 @@
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl.dao;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileFeature;
@ -107,4 +125,32 @@ public interface MobileFeatureDAO {
* @throws MobileDeviceManagementDAOException
*/
List<MobileFeature> getAllFeatures() throws MobileDeviceManagementDAOException;
/**
* Get all the MobileFeatures by a given ui visibility
*
* @param isHidden Whether the operation is hidden from UI or not.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getAllFeatures(boolean isHidden) throws MobileDeviceManagementDAOException;
/**
* Retrieve all MobileFeatures of a given feature type
*
* @param featureType Feature type.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getFeaturesByFeatureType(String featureType) throws MobileDeviceManagementDAOException;
/**
* Retrieve all MobileFeatures of a given feature type and ui visibility
*
* @param featureType Feature type.
* @param isHidden Whether the operation is hidden from UI or not.
* @return {@link MobileFeature} object list.
* @throws MobileDeviceManagementDAOException If an error occurred while retrieving the Feature list
*/
List<MobileFeature> getFeaturesByFeatureType(String featureType, boolean isHidden) throws MobileDeviceManagementDAOException;
}

@ -16,6 +16,25 @@
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl.dao.impl;
import org.apache.commons.logging.Log;
@ -51,11 +70,13 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "INSERT INTO AD_FEATURE(CODE, NAME, DESCRIPTION) VALUES (?, ?, ?)";
String sql = "INSERT INTO AD_FEATURE(CODE, NAME, TYPE, HIDDEN, DESCRIPTION) VALUES (?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getDescription());
stmt.setString(3, mobileFeature.getType());
stmt.setBoolean(4, mobileFeature.isHidden());
stmt.setString(5, mobileFeature.getDescription());
stmt.executeUpdate();
status = true;
} catch (SQLException e) {
@ -71,28 +92,27 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
@Override
public boolean addFeatures(List<MobileFeature> mobileFeatures) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
MobileFeature mobileFeature;
boolean status = false;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
stmt = conn.prepareStatement("INSERT INTO AD_FEATURE(CODE, NAME, DESCRIPTION) VALUES (?, ?, ?)");
for (int i = 0; i < mobileFeatures.size(); i++) {
mobileFeature = mobileFeatures.get(i);
stmt = conn.prepareStatement("INSERT INTO AD_FEATURE(CODE, NAME, TYPE, HIDDEN, DESCRIPTION) " +
"VALUES (?, ?, ?, ?, ?)");
for (MobileFeature mobileFeature : mobileFeatures) {
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getDescription());
stmt.setString(3, mobileFeature.getType());
stmt.setBoolean(4, mobileFeature.isHidden());
stmt.setString(5, mobileFeature.getDescription());
stmt.addBatch();
}
stmt.executeBatch();
status = true;
return true;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException(
"Error occurred while adding android features into the metadata repository", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, null);
}
return status;
}
@Override
@ -103,13 +123,15 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
try {
conn = AndroidDAOFactory.getConnection();
String updateDBQuery =
"UPDATE AD_FEATURE SET NAME = ?, DESCRIPTION = ?" +
"UPDATE AD_FEATURE SET NAME = ?, TYPE = ?, HIDDEN = ? ,DESCRIPTION = ?" +
"WHERE CODE = ?";
stmt = conn.prepareStatement(updateDBQuery);
stmt.setString(1, mobileFeature.getName());
stmt.setString(2, mobileFeature.getDescription());
stmt.setString(3, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getType());
stmt.setBoolean(3, mobileFeature.isHidden());
stmt.setString(4, mobileFeature.getDescription());
stmt.setString(5, mobileFeature.getCode());
int rows = stmt.executeUpdate();
if (rows > 0) {
@ -156,7 +178,7 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
@Override
public boolean deleteFeatureByCode(String mblFeatureCode) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
boolean status = false;
boolean status;
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
@ -182,7 +204,7 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
Connection conn;
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, DESCRIPTION FROM AD_FEATURE WHERE ID = ?";
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, mblFeatureId);
rs = stmt.executeQuery();
@ -193,6 +215,8 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setType(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_TYPE));
mobileFeature.setHidden(rs.getBoolean(AndroidPluginConstants.ANDROID_FEATURE_HIDDEN));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.
ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setDeviceType(
@ -217,21 +241,14 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, DESCRIPTION FROM AD_FEATURE WHERE CODE = ?";
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE CODE = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, mblFeatureCode);
rs = stmt.executeQuery();
MobileFeature mobileFeature = null;
if (rs.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.
ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setDeviceType(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
mobileFeature = populateMobileFeature(rs);
}
return mobileFeature;
} catch (SQLException e) {
@ -258,28 +275,123 @@ public class AndroidFeatureDAOImpl implements MobileFeatureDAO {
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, DESCRIPTION FROM AD_FEATURE";
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
MobileFeature mobileFeature = null;
while (rs.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setDeviceType(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
features.add(mobileFeature);
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all " +
"android features from the android database.", e);
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features " +
"from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getAllFeatures(boolean isHidden) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn = null;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE HIDDEN = ?";
stmt = conn.prepareStatement(sql);
stmt.setBoolean(1, isHidden);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features " +
"from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getFeaturesByFeatureType(String featureType) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION FROM AD_FEATURE WHERE TYPE = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, featureType);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features of " +
"type " + featureType + " from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
@Override
public List<MobileFeature> getFeaturesByFeatureType(String featureType, boolean isHidden) throws MobileDeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Connection conn;
List<MobileFeature> features = new ArrayList<>();
try {
conn = AndroidDAOFactory.getConnection();
String sql = "SELECT ID, CODE, NAME, TYPE, HIDDEN, DESCRIPTION " +
"FROM AD_FEATURE " +
"WHERE TYPE = ? AND HIDDEN = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, featureType);
stmt.setBoolean(2, isHidden);
rs = stmt.executeQuery();
while (rs.next()) {
features.add(populateMobileFeature(rs));
}
return features;
} catch (SQLException e) {
throw new AndroidFeatureManagementDAOException("Error occurred while retrieving all android features of " +
"[type: " + featureType + " & hidden: " + isHidden + "] from the android database.", e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(stmt, rs);
AndroidDAOFactory.closeConnection();
}
}
/**
* Generate {@link MobileFeature} from the SQL {@link ResultSet}
*
* @param rs Result set
* @return populated {@link MobileFeature}
* @throws SQLException if unable to extract data from {@link ResultSet}
*/
private MobileFeature populateMobileFeature(ResultSet rs) throws SQLException {
MobileFeature mobileFeature = new MobileFeature();
mobileFeature.setId(rs.getInt(AndroidPluginConstants.ANDROID_FEATURE_ID));
mobileFeature.setCode(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_CODE));
mobileFeature.setName(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_NAME));
mobileFeature.setDescription(rs.getString(AndroidPluginConstants.
ANDROID_FEATURE_DESCRIPTION));
mobileFeature.setType(rs.getString(AndroidPluginConstants.ANDROID_FEATURE_TYPE));
mobileFeature.setHidden(rs.getBoolean(AndroidPluginConstants.ANDROID_FEATURE_HIDDEN));
mobileFeature.setDeviceType(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
return mobileFeature;
}
}

@ -1,336 +0,0 @@
/*
* Copyright (c) 2014, 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.mobile.android.impl.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileDeviceManagementDAOException;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.MobileFeatureDAO;
import org.wso2.carbon.device.mgt.mobile.android.impl.dao.util.MobileDeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.mobile.android.impl.dto.MobileFeature;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Implementation of MobileFeatureDAO.
*/
public class MobileFeatureDAOImpl implements MobileFeatureDAO {
private DataSource dataSource;
private static final Log log = LogFactory.getLog(MobileFeatureDAOImpl.class);
public MobileFeatureDAOImpl(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public boolean addFeature(MobileFeature mobileFeature)
throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
String createDBQuery =
"INSERT INTO AD_FEATURE(CODE, NAME, DESCRIPTION, DEVICE_TYPE) VALUES (?, ?, ?, ?)";
stmt = conn.prepareStatement(createDBQuery);
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getDescription());
stmt.setString(4, mobileFeature.getDeviceType());
int rows = stmt.executeUpdate();
if (rows > 0) {
if (log.isDebugEnabled()) {
log.debug("Added a new MobileFeature " + mobileFeature.getCode() + " to the MDM database.");
}
status = true;
}
} catch (SQLException e) {
String msg = "Error occurred while adding feature code - '" +
mobileFeature.getCode() + "' to feature table";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, null);
}
return status;
}
@Override
public boolean addFeatures(List<MobileFeature> mobileFeatures) throws MobileDeviceManagementDAOException {
return false;
}
@Override
public boolean updateFeature(MobileFeature mobileFeature)
throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
String updateDBQuery =
"UPDATE AD_FEATURE SET CODE = ?, NAME = ?, DESCRIPTION = ?, DEVICE_TYPE = ?" +
" WHERE ID = ?";
stmt = conn.prepareStatement(updateDBQuery);
stmt.setString(1, mobileFeature.getCode());
stmt.setString(2, mobileFeature.getName());
stmt.setString(3, mobileFeature.getDescription());
stmt.setString(4, mobileFeature.getDeviceType());
stmt.setInt(5, mobileFeature.getId());
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Updated MobileFeature " + mobileFeature.getCode());
}
}
} catch (SQLException e) {
String msg = "Error occurred while updating the feature with feature code - '" +
mobileFeature.getId() + "'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, null);
}
return status;
}
@Override
public boolean deleteFeatureByCode(String mblFeatureCode)
throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
String deleteDBQuery =
"DELETE FROM AD_FEATURE WHERE CODE = ?";
stmt = conn.prepareStatement(deleteDBQuery);
stmt.setString(1, mblFeatureCode);
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Deleted MobileFeature code " + mblFeatureCode + " from the MDM database.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while deleting feature with code - " + mblFeatureCode;
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, null);
}
return status;
}
@Override
public boolean deleteFeatureById(int mblFeatureId)
throws MobileDeviceManagementDAOException {
boolean status = false;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = this.getConnection();
String deleteDBQuery =
"DELETE FROM AD_FEATURE WHERE ID = ?";
stmt = conn.prepareStatement(deleteDBQuery);
stmt.setInt(1, mblFeatureId);
int rows = stmt.executeUpdate();
if (rows > 0) {
status = true;
if (log.isDebugEnabled()) {
log.debug("Deleted MobileFeature id " + mblFeatureId + " from the MDM database.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while deleting feature with id - " + mblFeatureId;
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, null);
}
return status;
}
@Override
public MobileFeature getFeatureByCode(String mblFeatureCode)
throws MobileDeviceManagementDAOException {
Connection conn = null;
PreparedStatement stmt = null;
MobileFeature mobileFeature = null;
ResultSet resultSet = null;
try {
conn = this.getConnection();
String selectDBQuery =
"SELECT ID, CODE, NAME, DESCRIPTION, DEVICE_TYPE FROM AD_FEATURE " +
"WHERE CODE = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, mblFeatureCode);
resultSet = stmt.executeQuery();
if (resultSet.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(resultSet.getInt(1));
mobileFeature.setCode(resultSet.getString(2));
mobileFeature.setName(resultSet.getString(3));
mobileFeature.setDescription(resultSet.getString(4));
mobileFeature.setDeviceType(resultSet.getString(5));
if (log.isDebugEnabled()) {
log.debug("Fetched MobileFeature " + mblFeatureCode + " from the MDM database.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while fetching feature code - '" + mblFeatureCode + "'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, resultSet);
}
return mobileFeature;
}
@Override
public MobileFeature getFeatureById(int mblFeatureId)
throws MobileDeviceManagementDAOException {
Connection conn = null;
PreparedStatement stmt = null;
MobileFeature mobileFeature = null;
ResultSet resultSet = null;
try {
conn = this.getConnection();
String selectDBQuery =
"SELECT ID, CODE, NAME, DESCRIPTION, DEVICE_TYPE FROM AD_FEATURE" +
" WHERE ID = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setInt(1, mblFeatureId);
resultSet = stmt.executeQuery();
if (resultSet.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(resultSet.getInt(1));
mobileFeature.setCode(resultSet.getString(2));
mobileFeature.setName(resultSet.getString(3));
mobileFeature.setDescription(resultSet.getString(4));
mobileFeature.setDeviceType(resultSet.getString(5));
if (log.isDebugEnabled()) {
log.debug("Fetched MobileFeatureId" + mblFeatureId + " from the MDM database.");
}
}
} catch (SQLException e) {
String msg = "Error occurred while fetching feature id - '" + mblFeatureId + "'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, resultSet);
}
return mobileFeature;
}
@Override
public List<MobileFeature> getAllFeatures() throws MobileDeviceManagementDAOException {
Connection conn = null;
PreparedStatement stmt = null;
MobileFeature mobileFeature;
List<MobileFeature> mobileFeatures = new ArrayList<MobileFeature>();
ResultSet resultSet = null;
try {
conn = this.getConnection();
String selectDBQuery =
"SELECT ID, CODE, NAME, DESCRIPTION, DEVICE_TYPE FROM AD_FEATURE";
stmt = conn.prepareStatement(selectDBQuery);
resultSet = stmt.executeQuery();
while (resultSet.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(resultSet.getInt(1));
mobileFeature.setCode(resultSet.getString(2));
mobileFeature.setName(resultSet.getString(3));
mobileFeature.setDescription(resultSet.getString(4));
mobileFeature.setDeviceType(resultSet.getString(5));
mobileFeatures.add(mobileFeature);
}
if (log.isDebugEnabled()) {
log.debug("Fetched all MobileFeatures from the MDM database.");
}
return mobileFeatures;
} catch (SQLException e) {
String msg = "Error occurred while fetching all features.'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, resultSet);
}
}
@Override
public List<MobileFeature> getFeatureByDeviceType(String deviceType) throws MobileDeviceManagementDAOException {
Connection conn = null;
PreparedStatement stmt = null;
MobileFeature mobileFeature;
List<MobileFeature> mobileFeatures = new ArrayList<>();
ResultSet resultSet = null;
try {
conn = this.getConnection();
String selectDBQuery =
"SELECT ID, CODE, NAME, DESCRIPTION, DEVICE_TYPE FROM AD_FEATURE" +
" WHERE DEVICE_TYPE = ?";
stmt = conn.prepareStatement(selectDBQuery);
stmt.setString(1, deviceType);
resultSet = stmt.executeQuery();
while (resultSet.next()) {
mobileFeature = new MobileFeature();
mobileFeature.setId(resultSet.getInt(1));
mobileFeature.setCode(resultSet.getString(2));
mobileFeature.setName(resultSet.getString(3));
mobileFeature.setDescription(resultSet.getString(4));
mobileFeature.setDeviceType(resultSet.getString(5));
mobileFeatures.add(mobileFeature);
}
if (log.isDebugEnabled()) {
log.debug("Fetched all MobileFeatures of type " + deviceType + " from the MDM" +
" database.");
}
return mobileFeatures;
} catch (SQLException e) {
String msg = "Error occurred while fetching all features.'";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
} finally {
MobileDeviceManagementDAOUtil.cleanupResources(conn, stmt, resultSet);
}
}
private Connection getConnection() throws MobileDeviceManagementDAOException {
try {
return dataSource.getConnection();
} catch (SQLException e) {
String msg = "Error occurred while obtaining a connection from the mobile specific " +
"datasource.";
log.error(msg, e);
throw new MobileDeviceManagementDAOException(msg, e);
}
}
}

@ -16,6 +16,24 @@
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl.dto;
import java.io.Serializable;
@ -29,6 +47,8 @@ public class MobileFeature implements Serializable {
private String deviceType;
private String code;
private String name;
private String type;
private boolean hidden;
private String description;
public int getId() {
@ -55,6 +75,22 @@ public class MobileFeature implements Serializable {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public String getDescription() {
return description;
}

@ -16,6 +16,24 @@
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl.util;
/**
@ -43,6 +61,8 @@ public final class AndroidPluginConstants {
public static final String ANDROID_FEATURE_ID = "ID";
public static final String ANDROID_FEATURE_CODE = "CODE";
public static final String ANDROID_FEATURE_NAME = "NAME";
public static final String ANDROID_FEATURE_TYPE = "TYPE";
public static final String ANDROID_FEATURE_HIDDEN = "HIDDEN";
public static final String ANDROID_FEATURE_DESCRIPTION = "DESCRIPTION";
public static final class NotifierType {

@ -16,6 +16,24 @@
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.mobile.android.impl.util;
import org.apache.commons.logging.Log;
@ -42,7 +60,13 @@ import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Provides utility methods required by the mobile device management bundle.
@ -202,6 +226,8 @@ public class MobileDeviceManagementUtil {
mobileFeature.setCode(feature.getCode());
mobileFeature.setDescription(feature.getDescription());
mobileFeature.setDeviceType(feature.getDeviceType());
mobileFeature.setType(feature.getType());
mobileFeature.setHidden(feature.isHidden());
return mobileFeature;
}
@ -211,6 +237,8 @@ public class MobileDeviceManagementUtil {
feature.setDeviceType(mobileFeature.getDeviceType());
feature.setCode(mobileFeature.getCode());
feature.setName(mobileFeature.getName());
feature.setType(mobileFeature.getType());
feature.setHidden(mobileFeature.isHidden());
return feature;
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mobile-plugins</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>windows-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,13 +23,13 @@
<parent>
<artifactId>windows-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.mobile.windows.ui</artifactId>
<version>4.2.5-SNAPSHOT</version>
<version>4.2.7-SNAPSHOT</version>
<name>WSO2 Carbon - Mobile Windows UI</name>
<packaging>pom</packaging>

@ -46,7 +46,7 @@
<div class="operation-title">
<h4>Device Operations</h4>
</div>
{{unit "cdmf.unit.device.type.windows.new.operation-bar" device=device
{{unit "cdmf.unit.device.type.windows.operation-bar" device=device
backendApiUri=backendApiUri autoCompleteParams=autoCompleteParams}}
</div>
{{/if}}

@ -1,65 +0,0 @@
/*
* 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.
*/
function onRequest(context) {
var log = new Log("operation.js");
var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"];
var device = context.unit.params.device;
var autoCompleteParams = context.unit.params.autoCompleteParams;
var encodedFeaturePayloads=context.unit.params.encodedFeaturePayloads;
var controlOperations = operationModule.getControlOperations(device);
var queryParams = [];
var formParams = [];
var pathParams = [];
for (var i = 0; i < controlOperations.length; i++) {
var currentParamList = controlOperations[i]["params"];
var uiParamList = controlOperations[i]["uiParams"];
for (var j = 0; j < currentParamList.length; j++) {
var currentParam = currentParamList[j];
currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams);
currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams);
currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams);
}
controlOperations[i]["uiParams"] = uiParamList;
if (encodedFeaturePayloads) {
controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]);
}
}
return {"control_operations": controlOperations, "device": device};
}
function processParams(paramsList, autoCompleteParams) {
for (var i = 0; i < paramsList.length; i++) {
var paramName = paramsList[i];
var paramValue = "";
var paramType = "text";
for (var k = 0; k < autoCompleteParams.length; k++) {
if (paramName == autoCompleteParams[k].name) {
paramValue = autoCompleteParams[k].value;
paramType = "hidden";
}
}
paramsList[i] = {"name": paramName, "value": paramValue, "type": paramType};
}
return paramsList;
}
function getPayload(featuresPayload, featureCode){
var featuresJSONPayloads = JSON.parse(featuresPayload);
return featuresJSONPayloads[featureCode];
}

@ -1,227 +0,0 @@
/*
* 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.
*/
/*
* On operation click function.
* @param selection: Selected operation
*/
function operationSelect(selection) {
$(modalPopupContent).addClass("operation-data");
$(modalPopupContent).html($(" .operation[data-operation-code=" + selection + "]").html());
$(modalPopupContent).data("operation-code", selection);
showPopup();
}
function submitForm(formId) {
var form = $("#" + formId);
var uri = form.attr("action");
var deviceId = form.data("device-id");
var contentType = form.data("content-type");
var operationCode = form.data("operation-code");
var uriencodedQueryStr = "";
var uriencodedFormStr = "";
var payload = {};
form.find("input").each(function () {
var input = $(this);
if (input.data("param-type") == "path") {
uri = uri.replace("{" + input.attr("id") + "}", input.val());
} else if (input.data("param-type") == "query") {
var prefix = (uriencodedQueryStr == "") ? "?" : "&";
uriencodedQueryStr += prefix + input.attr("id") + "=" + input.val();
} else if (input.data("param-type") == "form") {
var prefix = (uriencodedFormStr == "") ? "" : "&";
uriencodedFormStr += prefix + input.attr("id") + "=" + input.val();
if(input.attr("type") == "text"){
payload[input.attr("id")] = input.val();
} else if(input.attr("type") == "checkbox"){
payload[input.attr("id")] = input.is(":checked");
}
}
});
uri += uriencodedQueryStr;
var httpMethod = form.attr("method").toUpperCase();
//var contentType = form.attr("enctype");
if (contentType == undefined || contentType == "") {
contentType = "application/x-www-form-urlencoded";
payload = uriencodedFormStr;
}
//setting responses callbacks
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#operation-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var description = content.find("#description");
description.html("");
var successCallBack = function (response) {
var res = response;
try {
res = JSON.parse(response).messageFromServer;
} catch (err) {
//do nothing
}
title.html("Operation Triggered!");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
description.html(res);
console.log("success!");
$(modalPopupContent).html(content.html());
};
var errorCallBack = function (response) {
console.log(response);
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
var reason = (response.responseText == "null")?response.statusText:response.responseText;
try {
reason = JSON.parse(reason).message;
} catch (err) {
//do nothing
}
description.html(reason);
console.log("Error!");
$(modalPopupContent).html(content.html());
};
//executing http request
if (httpMethod == "GET") {
invokerUtil.get(uri, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "POST") {
var deviceList = [deviceId];
payload = generatePayload(operationCode, payload, deviceList);
invokerUtil.post(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "PUT") {
invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod == "DELETE") {
invokerUtil.delete(uri, successCallBack, errorCallBack, contentType);
} else {
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
description.html("This operation requires http method: " + httpMethod + " which is not supported yet!");
$(modalPopupContent).html(content.html());
}
}
$(document).on('submit', 'form', function (e) {
cosole.log("darn!!");
e.preventDefault();
var postOperationRequest = $.ajax({
url: $(this).attr("action") + '&' + $(this).serialize(),
method: "post"
});
var btnSubmit = $('#btnSend', this);
btnSubmit.addClass('hidden');
var lblSending = $('#lblSending', this);
lblSending.removeClass('hidden');
var lblSent = $('#lblSent', this);
postOperationRequest.done(function (data) {
lblSending.addClass('hidden');
lblSent.removeClass('hidden');
setTimeout(function () {
hidePopup();
}, 3000);
});
postOperationRequest.fail(function (jqXHR, textStatus) {
lblSending.addClass('hidden');
lblSent.addClass('hidden');
});
});
// Constants to define operation types available
var operationTypeConstants = {
"PROFILE": "profile",
"CONFIG": "config",
"COMMAND": "command"
};
var generatePayload = function (operationCode, operationData, deviceList) {
var payload;
var operationType;
switch (operationCode) {
case windowsOperationConstants["CAMERA_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"enabled": operationData["cameraEnabled"]
}
};
break;
case windowsOperationConstants["CHANGE_LOCK_CODE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"lockCode": operationData["lockCode"]
}
};
break;
case windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"encrypted": operationData["encryptStorageEnabled"]
}
};
break;
case windowsOperationConstants["NOTIFICATION_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"message": operationData["message"]
}
};
break;
case windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"allowSimple": operationData["passcodePolicyAllowSimple"],
"requireAlphanumeric": operationData["passcodePolicyRequireAlphanumeric"],
"minLength": operationData["passcodePolicyMinLength"],
"minComplexChars": operationData["passcodePolicyMinComplexChars"],
"maxPINAgeInDays": operationData["passcodePolicyMaxPasscodeAgeInDays"],
"pinHistory": operationData["passcodePolicyPasscodeHistory"],
"maxFailedAttempts": operationData["passcodePolicyMaxFailedAttempts"]
}
};
break;
default:
// If the operation is neither of above, it is a command operation
operationType = operationTypeConstants["COMMAND"];
// Operation payload of a command operation is simply an array of device IDs
payload = deviceList;
}
if (operationType == operationTypeConstants["PROFILE"] && deviceList) {
payload["deviceIDs"] = deviceList;
}
return payload;
};
// Constants to define Windows Operation Constants
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE",
"NOTIFICATION_OPERATION_CODE": "NOTIFICATION",
"CHANGE_LOCK_CODE_OPERATION_CODE": "CHANGE_LOCK_CODE"
};

@ -15,18 +15,132 @@
specific language governing permissions and limitations
under the License.
}}
{{#if control_operations}}
<div class="wr-operations" style="height: 87px; display: block;"
xmlns="http://www.w3.org/1999/html">
<style>
::-webkit-input-placeholder {
color: #B8B8B8;
}
{{unit "cdmf.unit.device.type.windows.date-range-picker"}}
::-moz-placeholder {
color: #B8B8B8;
}
{{#zone "content"}}
<div id="operations-mod" data-permissions="{{permissions}}" data-device-type="{{deviceType}}" data-ownership="{{ownership}}">
{{unit "cdmf.unit.device.type.windows.operation-mod"}}
:-ms-input-placeholder {
color: #B8B8B8;
}
input:-moz-placeholder {
color: #B8B8B8;
}
</style>
{{#each control_operations}}
<a class="operation-tile" href="javascript:operationSelect('{{operation}}')">
{{#if iconFont}}
<i class="fw {{iconFont}}"></i>
{{else}}
{{#if icon}}
<img src="{{@app.context}}/{{icon}}" style="width: 48px;"/>
{{else}}
<i class="fw fw-service"></i>
{{/if}}
{{/if}}
<span>{{name}}</span>
</a>
<div class="operation" data-operation-code="{{operation}}">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw {{iconFont}} fw-stack-1x"></i>
</span>
{{name}}
<br>
</h3>
<h4>
{{description}}
<br>
</h4>
<form action="{{params.0.uri}}" method="{{params.0.method}}"
style="padding-bottom: 20px;"
data-payload="{{payload}}" id="form-{{operation}}"
data-device-id="{{../device.deviceIdentifier}}"
data-content-type="{{params.0.contentType}}"
data-operation-code="{{operation}}">
{{#each params.0.pathParams}}
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="path" value="{{value}}" />
<br />
{{/each}}
{{#each params.0.formParams}}
<input type="{{type}}" id="{{name}}" name="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="form" value="{{value}}" />
<br />
{{/each}}
{{#each params.0.queryParams}}
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="query" value="{{value}}" />
<br />
{{/each}}
{{#each uiParams}}
{{#equal this.type "checkbox"}}
<input type="{{this.type}}" id="{{this.id}}"
class="checkbox"
placeholder="{{this.label}}"
data-param-type="form"/>
{{this.label}}
<br/>
{{/equal}}
{{#equal this.type "text"}}
<input type="{{this.type}}" id="{{this.id}}"
placeholder="{{this.label}}" class="form-control"
data-param-type="form" value=""/>
<br/>
{{/equal}}
{{/each}}
<button id="btnSend" type="button" onclick="submitForm('form-{{operation}}')" class="btn btn-default">&nbsp;&nbsp;&nbsp;&nbsp;Send
to Device&nbsp;&nbsp;&nbsp;&nbsp;</button>
<label id="lblSending" class="wr-input-label hidden"><i
class="fw fw-lifecycle fw-spin fw-2x"></i> Sending..</label>
<label id="lblSent" class="wr-input-label hidden"><i
class="fw fw-check fw-2x"></i> Sent</label>
</form>
</div>
{{/zone}}
</div>
</div>
</div>
{{/each}}
</div>
{{else}}
<div align="center">
<h4 style="color: #D8000C"><i class="icon fw fw-error" style="color: #D8000C"></i>
Operations Loading Failed!</h4>
</div>
{{/if}}
<div id="operation-response-template" style="display: none">
<div class="content">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<h3>
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
</span>
<br>
</h3>
<h4>
<span id="title"></span>
<br>
</h4>
<span id="description"></span>
</div>
</div>
</div>
</div>
{{#zone "bottomJs"}}
<!--suppress HtmlUnknownTarget -->
<script id="operations-bar" src="{{@unit.publicUri}}/templates/operations.hbs"
type="text/x-handlebars-template"></script>
{{js "js/operation-bar.js"}}
{{/zone}}

@ -17,90 +17,49 @@
*/
function onRequest(context) {
var log = new Log("cdmf.unit.device.type.windows.operation-bar");
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var viewModel = {};
var permissions = {};
// adding android operations related permission checks
permissions["android"] = [];
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/ring")) {
permissions["android"].push("DEVICE_RING");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/lock")) {
permissions["android"].push("DEVICE_LOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/unlock")) {
permissions["android"].push("DEVICE_UNLOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/location")) {
permissions["android"].push("DEVICE_LOCATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/clear-password")) {
permissions["android"].push("CLEAR_PASSWORD");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/reboot")) {
permissions["android"].push("DEVICE_REBOOT");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/upgrade-firmware")) {
permissions["android"].push("UPGRADE_FIRMWARE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/mute")) {
permissions["android"].push("DEVICE_MUTE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/send-notification")) {
permissions["android"].push("NOTIFICATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/change-lock-code")) {
permissions["android"].push("CHANGE_LOCK_CODE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/enterprise-wipe")) {
permissions["android"].push("ENTERPRISE_WIPE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning-device/operations/android/wipe")) {
permissions["android"].push("WIPE_DATA");
}
// adding ios operations related permission checks
permissions["ios"] = [];
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/ios/lock")) {
permissions["ios"].push("DEVICE_LOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/ios/location")) {
permissions["ios"].push("LOCATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/ios/enterprise-wipe")) {
permissions["ios"].push("ENTERPRISE_WIPE");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/ios/notification")) {
permissions["ios"].push("NOTIFICATION");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/ios/ring")) {
permissions["ios"].push("RING");
}
var log = new Log("operation.js");
var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"];
var device = context.unit.params.device;
var autoCompleteParams = context.unit.params.autoCompleteParams;
var encodedFeaturePayloads=context.unit.params.encodedFeaturePayloads;
var controlOperations = operationModule.getControlOperations(device);
var queryParams = [];
var formParams = [];
var pathParams = [];
for (var i = 0; i < controlOperations.length; i++) {
var currentParamList = controlOperations[i]["params"];
var uiParamList = controlOperations[i]["uiParams"];
for (var j = 0; j < currentParamList.length; j++) {
var currentParam = currentParamList[j];
currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams);
currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams);
currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams);
}
controlOperations[i]["uiParams"] = uiParamList;
if (encodedFeaturePayloads) {
controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]);
}
}
return {"control_operations": controlOperations, "device": device};
}
// adding windows operations related permission checks
permissions["windows"] = [];
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/windows/lock")) {
permissions["windows"].push("DEVICE_LOCK");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/disenroll/windows")) {
permissions["windows"].push("DISENROLL");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/windows/wipe")) {
permissions["windows"].push("WIPE_DATA");
function processParams(paramsList, autoCompleteParams) {
for (var i = 0; i < paramsList.length; i++) {
var paramName = paramsList[i];
var paramValue = "";
var paramType = "text";
for (var k = 0; k < autoCompleteParams.length; k++) {
if (paramName == autoCompleteParams[k].name) {
paramValue = autoCompleteParams[k].value;
paramType = "hidden";
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/windows/ring")) {
permissions["windows"].push("DEVICE_RING");
}
if (userModule.isAuthorized("/permission/admin/device-mgt/devices/owning/operations/windows/lock-reset")) {
permissions["windows"].push("LOCK_RESET");
paramsList[i] = {"name": paramName, "value": paramValue, "type": paramType};
}
return paramsList;
}
viewModel["permissions"] = stringify(permissions);
viewModel["deviceType"] = context.unit.params.deviceType;
viewModel["ownership"] = context.unit.params.ownership;
return viewModel;
function getPayload(featuresPayload, featureCode){
var featuresJSONPayloads = JSON.parse(featuresPayload);
return featuresJSONPayloads[featureCode];
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* 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
@ -17,232 +17,227 @@
*/
/*
* Setting-up global variables.
*/
var operations = '.wr-operations',
modalPopup = '.modal',
modalPopupContent = modalPopup + ' .modal-content',
navHeight = $('#nav').height(),
headerHeight = $('header').height(),
offset = (headerHeight + navHeight),
deviceSelection = '.device-select',
platformTypeConstants = {
"ANDROID": "android",
"IOS": "ios",
"WINDOWS": "windows"
},
ownershipTypeConstants = {
"BYOD": "BYOD",
"COPE": "COPE"
},
operationBarModeConstants = {
"BULK": "BULK_OPERATION_MODE",
"SINGLE": "SINGLE_OPERATION_MODE"
};
/*
* Function to get selected devices ID's
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. 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.
*/
function getSelectedDeviceIds() {
var deviceIdentifierList = [];
$(deviceSelection).each(function (index) {
var device = $(this);
var deviceId = device.data('deviceid');
var deviceType = device.data('type');
deviceIdentifierList.push({
"id": deviceId,
"type": deviceType
});
});
if (deviceIdentifierList.length == 0) {
var thisTable = $(".DTTT_selected").closest('.dataTables_wrapper').find('.dataTable').dataTable();
thisTable.api().rows().every(function () {
if ($(this.node()).hasClass('DTTT_selected')) {
var deviceId = $(thisTable.api().row(this).node()).data('deviceid');
var deviceType = $(thisTable.api().row(this).node()).data('devicetype');
deviceIdentifierList.push({
"id": deviceId,
"type": deviceType
});
}
});
}
return deviceIdentifierList;
}
/*
* On operation click function.
* @param selection: Selected operation
*/
function operationSelect(selection) {
var deviceIdList = getSelectedDeviceIds();
if (deviceIdList == 0) {
$(modalPopupContent).html($("#errorOperations").html());
} else {
$(modalPopupContent).addClass("operation-data");
$(modalPopupContent).html($(operations + " .operation[data-operation-code=" + selection + "]").html());
$(modalPopupContent).html($(" .operation[data-operation-code=" + selection + "]").html());
$(modalPopupContent).data("operation-code", selection);
}
showPopup();
}
function getDevicesByTypes(deviceList) {
var deviceTypes = {};
$.each(deviceList, function (index, item) {
if (!deviceTypes[item.type]) {
deviceTypes[item.type] = [];
function submitForm(formId) {
var form = $("#" + formId);
var uri = form.attr("action");
var deviceIdList = form.data("device-id");
var contentType = form.data("content-type");
var operationCode = form.data("operation-code");
var uriEncodedQueryStr = "";
var uriEncodedFormStr = "";
var payload = {};
form.find("input").each(function () {
var input = $(this);
var prefix;
if (input.data("param-type") === "path") {
uri = uri.replace("{" + input.attr("id") + "}", input.val());
} else if (input.data("param-type") === "query") {
prefix = !uriEncodedQueryStr ? "?" : "&";
uriEncodedQueryStr += prefix + input.attr("id") + "=" + input.val();
} else if (input.data("param-type") === "form") {
prefix = !uriEncodedFormStr ? "" : "&";
uriEncodedFormStr += prefix + input.attr("id") + "=" + input.val();
if(input.attr("type") === "text"){
payload[input.attr("id")] = input.val();
} else if(input.attr("type") === "checkbox"){
payload[input.attr("id")] = input.is(":checked");
}
if (item.type == platformTypeConstants.ANDROID ||
item.type == platformTypeConstants.IOS || item.type == platformTypeConstants.WINDOWS) {
deviceTypes[item.type].push(item.id);
}
});
return deviceTypes;
}
//function unloadOperationBar() {
// $("#showOperationsBtn").addClass("hidden");
// $(".wr-operations").html("");
//}
function loadOperationBar(deviceType, ownership, mode) {
var operationBar = $("#operations-bar");
var operationBarSrc = operationBar.attr("src");
$.template("operations-bar", operationBarSrc, function (template) {
var serviceURL = "/api/device-mgt/v1.0/devices/" + deviceType + "/*/features";
invokerUtil.get(
serviceURL,
// success callback
function (data) {
var permittedOperations = [];
var i;
var permissionList = $("#operations-mod").data("permissions");
var totalFeatures = JSON.parse(data);
for (i = 0; i < permissionList[deviceType].length; i++) {
var j;
for (j = 0; j < totalFeatures.length; j++) {
if (permissionList[deviceType][i] == totalFeatures[j]["code"]) {
if (deviceType == platformTypeConstants.ANDROID) {
if (totalFeatures[j]["code"] == "DEVICE_UNLOCK") {
if (ownership == ownershipTypeConstants.COPE) {
permittedOperations.push(totalFeatures[j]);
}
} else if (totalFeatures[j]["code"] == "WIPE_DATA") {
if (mode == operationBarModeConstants.BULK) {
if (ownership == ownershipTypeConstants.COPE) {
permittedOperations.push(totalFeatures[j]);
}
} else {
permittedOperations.push(totalFeatures[j]);
}
} else {
permittedOperations.push(totalFeatures[j]);
}
uri += uriEncodedQueryStr;
var httpMethod = form.attr("method").toUpperCase();
if (!contentType) {
contentType = "application/x-www-form-urlencoded";
payload = uriEncodedFormStr;
}
//setting responses callbacks
var defaultStatusClasses = "fw fw-stack-1x";
var content = $("#operation-response-template").find(".content");
var title = content.find("#title");
var statusIcon = content.find("#status-icon");
var description = content.find("#description");
description.html("");
var successCallBack = function (response) {
var res = response;
try {
res = JSON.parse(response).messageFromServer;
} catch (err) {
//do nothing
}
title.html("Operation Triggered!");
statusIcon.attr("class", defaultStatusClasses + " fw-check");
description.html(res);
console.log("success!");
$(modalPopupContent).html(content.html());
};
var errorCallBack = function (response) {
console.log(response);
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
var reason = (response.responseText === "null")?response.statusText:response.responseText;
try {
reason = JSON.parse(reason).message;
} catch (err) {
//do nothing
}
description.html(reason);
console.log("Error!");
$(modalPopupContent).html(content.html());
};
//executing http request
if (httpMethod === "GET") {
invokerUtil.get(uri, successCallBack, errorCallBack, contentType);
} else if (httpMethod === "POST") {
var deviceList = deviceIdList.split(",");
payload = generatePayload(operationCode, payload, deviceList);
invokerUtil.post(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod === "PUT") {
invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType);
} else if (httpMethod === "DELETE") {
invokerUtil.delete(uri, successCallBack, errorCallBack, contentType);
} else {
permittedOperations.push(totalFeatures[j]);
}
}
}
title.html("An Error Occurred!");
statusIcon.attr("class", defaultStatusClasses + " fw-error");
description.html("This operation requires http method: " + httpMethod + " which is not supported yet!");
$(modalPopupContent).html(content.html());
}
}
var viewModel = {};
permittedOperations = permittedOperations.filter(function (current) {
var iconName;
switch (deviceType) {
case platformTypeConstants.ANDROID:
iconName = operationModule.getAndroidIconForFeature(current.code);
break;
case platformTypeConstants.WINDOWS:
iconName = operationModule.getWindowsIconForFeature(current.code);
break;
case platformTypeConstants.IOS:
iconName = operationModule.getIOSIconForFeature(current.code);
break;
}
$(document).on('submit', 'form', function (e) {
e.preventDefault();
var postOperationRequest = $.ajax({
url: $(this).attr("action") + '&' + $(this).serialize(),
method: "post"
});
/* adding ownership in addition to device-type
as it's vital in cases where UI for the same feature should change
according to ownership
*/
if (ownership) {
current.ownership = ownership;
}
var btnSubmit = $('#btnSend', this);
btnSubmit.addClass('hidden');
if (iconName) {
current.icon = iconName;
}
var lblSending = $('#lblSending', this);
lblSending.removeClass('hidden');
return current;
var lblSent = $('#lblSent', this);
postOperationRequest.done(function (data) {
lblSending.addClass('hidden');
lblSent.removeClass('hidden');
setTimeout(function () {
hidePopup();
}, 3000);
});
viewModel.features = permittedOperations;
var content = template(viewModel);
$(".wr-operations").html(content);
},
// error callback
function (message) {
$(".wr-operations").html(message);
});
postOperationRequest.fail(function (jqXHR, textStatus) {
lblSending.addClass('hidden');
lblSent.addClass('hidden');
});
}
});
function runOperation(operationName) {
var deviceIdList = getSelectedDeviceIds();
var list = getDevicesByTypes(deviceIdList);
// Constants to define operation types available
var operationTypeConstants = {
"PROFILE": "profile",
"CONFIG": "config",
"COMMAND": "command"
};
var successCallback = function (data) {
if (operationName == "NOTIFICATION") {
$(modalPopupContent).html($("#messageSuccess").html());
} else {
$(modalPopupContent).html($("#operationSuccess").html());
var generatePayload = function (operationCode, operationData, deviceList) {
var payload;
var operationType;
switch (operationCode) {
case windowsOperationConstants["CAMERA_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"enabled": operationData["cameraEnabled"]
}
showPopup();
};
var errorCallback = function (data) {
$(modalPopupContent).html($("#errorOperationUnexpected").html());
showPopup();
break;
case windowsOperationConstants["CHANGE_LOCK_CODE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"lockCode": operationData["lockCode"]
}
};
var payload, serviceEndPoint;
if (list[platformTypeConstants.IOS]) {
payload =
operationModule.generatePayload(platformTypeConstants.IOS, operationName, list[platformTypeConstants.IOS]);
serviceEndPoint = operationModule.getIOSServiceEndpoint(operationName);
} else if (list[platformTypeConstants.ANDROID]) {
payload = operationModule
.generatePayload(platformTypeConstants.ANDROID, operationName, list[platformTypeConstants.ANDROID]);
serviceEndPoint = operationModule.getAndroidServiceEndpoint(operationName);
} else if (list[platformTypeConstants.WINDOWS]) {
payload = operationModule.generatePayload(platformTypeConstants.WINDOWS, operationName,
list[platformTypeConstants.WINDOWS]);
serviceEndPoint = operationModule.getWindowsServiceEndpoint(operationName);
break;
case windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"encrypted": operationData["encryptStorageEnabled"]
}
if (operationName == "NOTIFICATION") {
var errorMsgWrapper = "#notification-error-msg";
var errorMsg = "#notification-error-msg span";
var messageTitle = $("#messageTitle").val();
var messageText = $("#messageText").val();
if (!(messageTitle && messageText)) {
$(errorMsg).text("Enter a message. It cannot be empty.");
$(errorMsgWrapper).removeClass("hidden");
} else {
invokerUtil.post(serviceEndPoint, payload, successCallback, errorCallback);
$(modalPopupContent).removeData();
hidePopup();
};
break;
case windowsOperationConstants["NOTIFICATION_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"message": operationData["message"]
}
} else {
invokerUtil.post(serviceEndPoint, payload, successCallback, errorCallback);
$(modalPopupContent).removeData();
hidePopup();
};
break;
case windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]:
operationType = operationTypeConstants["PROFILE"];
payload = {
"operation": {
"allowSimple": operationData["passcodePolicyAllowSimple"],
"requireAlphanumeric": operationData["passcodePolicyRequireAlphanumeric"],
"minLength": operationData["passcodePolicyMinLength"],
"minComplexChars": operationData["passcodePolicyMinComplexChars"],
"maxPINAgeInDays": operationData["passcodePolicyMaxPasscodeAgeInDays"],
"pinHistory": operationData["passcodePolicyPasscodeHistory"],
"maxFailedAttempts": operationData["passcodePolicyMaxFailedAttempts"]
}
};
break;
default:
// If the operation is neither of above, it is a command operation
operationType = operationTypeConstants["COMMAND"];
// Operation payload of a command operation is simply an array of device IDs
payload = deviceList;
}
}
/*
* DOM ready functions.
*/
$(document).ready(function () {
$(operations).show();
});
if (operationType === operationTypeConstants["PROFILE"] && deviceList) {
payload["deviceIDs"] = deviceList;
}
return payload;
};
// Constants to define Windows Operation Constants
var windowsOperationConstants = {
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
"CAMERA_OPERATION_CODE": "CAMERA",
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE",
"NOTIFICATION_OPERATION_CODE": "NOTIFICATION",
"CHANGE_LOCK_CODE_OPERATION_CODE": "CHANGE_LOCK_CODE"
};

@ -1,286 +0,0 @@
<div class="row no-gutter">
<div class="wr-hidden-operations-nav col-lg-4">
<a href="javascript:void(0)" onclick="showAdvanceOperation('security', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-padlock fw-stack-2x"></i>
</span>
Security
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('restriction', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-settings fw-stack-2x"></i>
</span>
Restrictions
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('application', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-padlock fw-stack-2x"></i>
</span>
Applications
</a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('wifi', this)">
<span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-wifi fw-stack-2x"></i>
</span>
Wi-fi
</a>
</div>
<div class="wr-hidden-operations-content col-lg-8">
<!-- security -->
<div class="wr-hidden-operation" data-operation="security" style="display: block">
<div class="panel panel-default operation-data" data-operation="{{features.ENCRYPT_STORAGE.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#enableEncryptionTab"
aria-expanded="true" aria-controls="enableEncryptionTab">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Encryption Enable/Disable
</a>
</h2>
</div>
<div id="enableEncryptionTab" class="panel-collapse panel-body collapse in" role="tabpanel"
aria-labelledby="enableEncryptionTab">
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input type="checkbox" class="operationDataKeys" id="enableEncryption"
data-key="enableEncryption"/>
<span class="helper" title="Enable Encryption">Enable Encryption<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>
</label>
</div>
<a href="javascript:runOperation('{{features.ENCRYPT_STORAGE.code}}')" class="btn-operations">Configure</a>
</div>
</div>
<div class="panel panel-default operation-data" data-operation="{{features.PASSCODE_POLICY.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#passCodePolicy" aria-expanded="false"
aria-controls="passCodePolicy" class="collapsed">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Passcode Policy
</a>
</h2>
</div>
<div id="passCodePolicy" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="passCodePolicy">
<label class="wr-input-label col-sm-4" for="maxFailedAttempts">Maximum Failed Attempts</label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="maxFailedAttempts"
data-key="maxFailedAttempts" placeholder="Enter maximum Failed Attempts">
</div>
<label class="wr-input-label col-sm-4" for="minLength">Minimum Length</label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="minLength" data-key="minLength"
placeholder="Enter minimum Length">
</div>
<label class="wr-input-label col-sm-4" for="pinHistory">PIN History</label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="pinHistory" data-key="pinHistory"
placeholder="Enter PIN History">
</div>
<label class="wr-input-label col-sm-4" for="minComplexChars">Minimum complex characters</label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="minComplexChars"
data-key="minComplexChars" placeholder="Enter minimum complex characters">
</div>
<label class="wr-input-label col-sm-4" for="lockcode">Minimum PIN Age in days</label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="maxPINAgeInDays"
data-key="maxPINAgeInDays" placeholder="Enter minimum PIN age in days">
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input type="checkbox" class="operationDataKeys" id="requireAlphanumeric"
data-key="requireAlphanumeric"/>
<span class="helper" title="Require Alphanumeric">Require Alphanumeric<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>
</label>
</div>
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input type="checkbox" class="operationDataKeys" id="allowSimple" data-key="allowSimple"/>
<span class="helper" title="Allow simple PIN">Allow simple PIN<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>
</label>
</div>
<a href="javascript:runOperation('{{features.PASSCODE_POLICY.code}}')" class="btn-operations">Configure</a>
</div>
</div>
</div>
<!-- /security -->
<!-- wi-fi -->
<div class="wr-hidden-operation panel-body" data-operation="wifi">
<div class="operation-data" data-operation="{{features.WIFI.code}}">
<label class="wr-input-label" title="Identification of the wireless network to connect to">Service Set
Identifier<span class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<!--span>Identification of the wireless network to connect to</span-->
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="ssid" data-key="ssid"
placeholder="Enter SSID"/>
</div>
<label class="wr-input-label" title="Password for the wireless network">Password<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<!--span>Password for the wireless network</span-->
<div class="wr-input-control">
<input type="password" class="form-control operationDataKeys" id="password" data-key="password"
placeholder="Password"/>
</div>
<a href="javascript:runOperation('{{features.WIFI.code}}')" class="btn-operations">Configure</a>
</div>
</div>
<!-- /wi-fi -->
<!-- application -->
<div class="wr-hidden-operation" data-operation="application">
<div class="panel panel-default operation-data" data-operation="{{features.INSTALL_APPLICATION.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#installApp" aria-expanded="true"
aria-controls="installApp">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Install App
</a>
</h2>
</div>
<div id="installApp" class="panel-collapse panel-body collapse in" role="tabpanel"
aria-labelledby="installApp">
<label class="wr-input-label" title="Application Identifier">App Identifier<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="package-name"
data-key="packageName" placeholder="Enter App Identifer"/>
</div>
<div class="wr-input-control">
<label class="wr-input-control dropdown">
<span class="helper" title="App Type">App Type<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>
<select class="form-control col-sm-8 operationDataKeys appTypesInput" id="type"
data-key="type">
<option>Public</option>
<option>Enterprise</option>
</select>
</label>
</div>
<label class="wr-input-label" title="URL">URL<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="url" data-key="url"
placeholder="Enter URL"/>
</div>
<a href="javascript:runOperation('{{features.INSTALL_APPLICATION.code}}')" class="btn-operations">Install</a>
</div>
</div>
<div class="panel panel-default operation-data" data-operation="{{features.WEBCLIP.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#installWebClip" aria-expanded="true"
aria-controls="installWebClip" class="collapsed">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Install Web Clip
</a>
</h2>
</div>
<div id="installWebClip" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="installWebClip">
<label class="wr-input-label" title="Title of the web clip">Title<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="title" data-key="title"
placeholder="Enter Title"/>
</div>
<label class="wr-input-label" title="URL">URL<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="url" data-key="url"
placeholder="Enter URL"/>
</div>
<a href="javascript:runOperation('{{features.WEBCLIP.code}}')" class="btn-operations">Install</a>
</div>
</div>
<div class="panel panel-default operation-data" data-operation="{{features.UNINSTALL_APPLICATION.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#uninstallApp" aria-expanded="true"
aria-controls="uninstallApp" class="collapsed">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Uninstall App
</a>
</h2>
</div>
<div id="uninstallApp" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="uninstallApp">
<label class="wr-input-label" title="Application Identifier">App Identifier<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></label>
<!--span>Identification of the wireless network to connect to</span-->
<div class="wr-input-control">
<input type="text" class="form-control operationDataKeys" id="package-name"
data-key="packageName" placeholder="Enter App Identifer"/>
</div>
<a href="javascript:runOperation('{{features.UNINSTALL_APPLICATION.code}}')" class="btn-operations">Uninstall</a>
</div>
</div>
</div>
<!-- /application -->
<!-- Restriction -->
<div class="wr-hidden-operation" data-operation="restriction">
<div class="panel panel-default operation-data" data-operation="{{features.CAMERA.code}}">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#cameraDisable" aria-expanded="true"
aria-controls="cameraDisable">
<span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-arrow fw-down-arrow fw-stack-1x"></i>
</span>
Camera Enable/Disable
</a>
</h2>
</div>
<div id="cameraDisable" class="panel-collapse panel-body collapse in" role="tabpanel"
aria-labelledby="cameraDisable">
<div class="wr-input-control">
<label class="wr-input-control checkbox">
<input type="checkbox" class="operationDataKeys" id="enableCamera" data-key="enableCamera"
checked/>
<span class="helper" title="Remove App upon dis-enrollment">Enable Camera<span
class="wr-help-tip glyphicon glyphicon-question-sign"></span></span>
</label>
</div>
<a href="javascript:runOperation('{{features.CAMERA.code}}')" class="btn-operations">Configure</a>
</div>
</div>
</div>
<!-- /Restriction -->
</div>
</div>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save