diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/ApplicationRestriction.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/ApplicationRestriction.java new file mode 100644 index 000000000..b3773376d --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/ApplicationRestriction.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) 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.mdm.services.android.bean; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * This class represents the information of sending application config operation. + */ +@ApiModel(value = "ApplicationRestriction", + description = "Details related to application config passed to device.") +public class ApplicationRestriction extends AndroidOperation implements Serializable { + private static final long serialVersionUID = 1995401458L; + + @ApiModelProperty(name = "appIdentifier", value = "The application identifier to be sent.", required = true) + private String appIdentifier; + + @ApiModelProperty(name = "restrictionPayload", value = "The restriction payload to be sent.", required = true) + private String restrictionPayload; + + public String getAppIdentifier() { + return appIdentifier; + } + + public void setAppIdentifier(String appIdentifier) { + this.appIdentifier = appIdentifier; + } + + public String getRestrictionPayload() { + return restrictionPayload; + } + + public void setRestrictionPayload(String restrictionPayload) { + this.restrictionPayload = restrictionPayload; + } +} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/wrapper/ApplicationRestrictionBeanWrapper.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/wrapper/ApplicationRestrictionBeanWrapper.java new file mode 100644 index 000000000..147a577da --- /dev/null +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/bean/wrapper/ApplicationRestrictionBeanWrapper.java @@ -0,0 +1,55 @@ + +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) 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.mdm.services.android.bean.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.mdm.services.android.bean.ApplicationRestriction; + +import java.util.List; + +/** + * This class is used to wrap the Notification bean with devices. + */ +@ApiModel(value = "ApplicationRestrictionBeanWrapper", + description = "Mapping between application restriction operation and device list to be applied.") +public class ApplicationRestrictionBeanWrapper { + + @ApiModelProperty(name = "deviceIDs", value = "List of device Ids", required = true) + private List deviceIDs; + @ApiModelProperty(name = "operation", value = "The information of application restriction operation", + required = true) + private ApplicationRestriction operation; + + public List getDeviceIDs() { + return deviceIDs; + } + + public void setDeviceIDs(List deviceIDs) { + this.deviceIDs = deviceIDs; + } + + public ApplicationRestriction getOperation() { + return operation; + } + + public void setOperation(ApplicationRestriction operation) { + this.operation = operation; + } +} \ No newline at end of file diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java index 998503b13..beebf032c 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/DeviceManagementAdminService.java @@ -245,6 +245,12 @@ import java.util.List; description = "Transferring a file to android devices", key = "perm:android:file-transfer", permissions = {"/device-mgt/devices/owning-device/operations/android/file-transfer"} + ), + @Scope( + name = "Send app restrictions", + description = "Send app restrictions to an application in the device", + key = "perm:android:send-app-restrictions", + permissions = {"/device-mgt/devices/owning-device/operations/android/send-app-conf"} ) } ) @@ -1856,6 +1862,68 @@ public interface DeviceManagementAdminService { value = "The properties to set the web clip.", required = true) WebClipBeanWrapper webClipBeanWrapper); + @POST + @Path("/send-app-conf") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Sending an app restrictions to Android Devices", + notes = "Send application restrictions to Android devices.", + response = Activity.class, + tags = "Android Device Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = AndroidConstants.SCOPE, + value = "perm:android:send-app-restrictions") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully sent the application configuration.", + response = Activity.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "URL of the activity instance that refers to the scheduled operation."), + @ResponseHeader( + name = "Content-Type", + description = "Content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while adding a new send application config operation.") + }) + Response sendApplicationConfiguration( + @ApiParam( + name = "notification", + value = "The properties required to send application restrictions. Provide the restriction you " + + "wish to send and the ID of the Android device. Multiple device IDs can be added by using" + + " comma separated values.", + required = true) + ApplicationRestrictionBeanWrapper applicationRestrictionBeanWrapper); @POST @Path("/configure-global-proxy") diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementAdminServiceImpl.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementAdminServiceImpl.java index 0941a66a9..efddc8764 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementAdminServiceImpl.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/services/impl/DeviceManagementAdminServiceImpl.java @@ -37,7 +37,7 @@ package org.wso2.carbon.mdm.services.android.services.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.json.JSONException; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; @@ -45,6 +45,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementExcept import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; import org.wso2.carbon.mdm.services.android.bean.ApplicationInstallation; +import org.wso2.carbon.mdm.services.android.bean.ApplicationRestriction; import org.wso2.carbon.mdm.services.android.bean.ApplicationUninstallation; import org.wso2.carbon.mdm.services.android.bean.ApplicationUpdate; import org.wso2.carbon.mdm.services.android.bean.BlacklistApplications; @@ -63,6 +64,7 @@ import org.wso2.carbon.mdm.services.android.bean.WebClip; import org.wso2.carbon.mdm.services.android.bean.Wifi; import org.wso2.carbon.mdm.services.android.bean.WipeData; import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationInstallationBeanWrapper; +import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationRestrictionBeanWrapper; import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUninstallationBeanWrapper; import org.wso2.carbon.mdm.services.android.bean.wrapper.ApplicationUpdateBeanWrapper; import org.wso2.carbon.mdm.services.android.bean.wrapper.BlacklistApplicationsBeanWrapper; @@ -82,6 +84,7 @@ import org.wso2.carbon.mdm.services.android.bean.wrapper.WipeDataBeanWrapper; import org.wso2.carbon.mdm.services.android.exception.BadRequestException; import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException; import org.wso2.carbon.mdm.services.android.services.DeviceManagementAdminService; +import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils; import org.wso2.carbon.mdm.services.android.util.AndroidConstants; import org.wso2.carbon.mdm.services.android.util.AndroidDeviceUtils; @@ -528,7 +531,8 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @POST @Path("/install-application") @Override - public Response installApplication(ApplicationInstallationBeanWrapper applicationInstallationBeanWrapper) { + public Response installApplication( + ApplicationInstallationBeanWrapper applicationInstallationBeanWrapper) { if (log.isDebugEnabled()) { log.debug("Invoking 'InstallApplication' operation"); } @@ -554,11 +558,6 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe Activity activity = AndroidDeviceUtils .getOperationResponse(applicationInstallationBeanWrapper.getDeviceIDs(), operation); return Response.status(Response.Status.CREATED).entity(activity).build(); - } catch (JSONException e) { - String errorMessage = "Invalid payload for the operation."; - log.error(errorMessage); - throw new BadRequestException( - new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); } catch (InvalidDeviceException e) { String errorMessage = "Invalid Device Identifiers found."; log.error(errorMessage, e); @@ -616,7 +615,8 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @POST @Path("/uninstall-application") @Override - public Response uninstallApplication(ApplicationUninstallationBeanWrapper applicationUninstallationBeanWrapper) { + public Response uninstallApplication( + ApplicationUninstallationBeanWrapper applicationUninstallationBeanWrapper) { if (log.isDebugEnabled()) { log.debug("Invoking 'UninstallApplication' operation"); } @@ -1022,6 +1022,46 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe new ErrorResponse.ErrorResponseBuilder().setCode(500L).setMessage(errorMessage).build()); } } + @POST + @Path("/send-app-conf") + @Override + public Response sendApplicationConfiguration( + ApplicationRestrictionBeanWrapper applicationRestrictionBeanWrapper) { + if (log.isDebugEnabled()) { + log.debug("Invoking 'send application configuration' operation"); + } + + try { + if (applicationRestrictionBeanWrapper == null || applicationRestrictionBeanWrapper.getOperation() == null) { + String errorMessage = "The payload of the application configuration operation is incorrect"; + log.error(errorMessage); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); + } + ApplicationRestriction applicationRestriction = applicationRestrictionBeanWrapper.getOperation(); + ProfileOperation operation = new ProfileOperation(); + operation.setCode(AndroidConstants.OperationCodes.REMOTE_APP_CONFIG); + operation.setType(Operation.Type.PROFILE); + operation.setPayLoad(applicationRestriction.toJSON()); + return (Response) AndroidAPIUtils.getOperationResponse(applicationRestrictionBeanWrapper.getDeviceIDs(), + operation); + } catch (InvalidDeviceException e) { + String errorMessage = "Invalid Device Identifiers found."; + log.error(errorMessage, e); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build()); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service instance"; + log.error(errorMessage, e); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(errorMessage).build()); + } + } private static void validateApplicationUrl(String apkUrl) { try { diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java index f8c37fe5f..318c23d83 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidAPIUtils.java @@ -23,12 +23,26 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.analytics.api.AnalyticsDataAPI; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.mdm.services.android.bean.ErrorResponse; +import org.wso2.carbon.mdm.services.android.exception.BadRequestException; import org.wso2.carbon.policy.mgt.core.PolicyManagerService; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + /** * AndroidAPIUtil class provides utility functions used by Android REST-API classes. */ @@ -135,4 +149,25 @@ public class AndroidAPIUtils { return analyticsDataAPI; } + public static Response getOperationResponse(List deviceIDs, Operation operation) + throws DeviceManagementException, OperationManagementException, InvalidDeviceException { + if (deviceIDs == null || deviceIDs.size() == 0) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage).build()); + } + DeviceIdentifier deviceIdentifier; + List deviceIdentifiers = new ArrayList<>(); + for (String deviceId : deviceIDs) { + deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(AndroidConstants.DEVICE_TYPE_ANDROID); + deviceIdentifiers.add(deviceIdentifier); + } + Activity activity = getDeviceManagementService().addOperation( + DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, operation, deviceIdentifiers); + return Response.status(Response.Status.CREATED).entity(activity).build(); + } + } diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidConstants.java b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidConstants.java index 96842c956..9db77c7f4 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidConstants.java +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.api/src/main/java/org/wso2/carbon/mdm/services/android/util/AndroidConstants.java @@ -140,6 +140,7 @@ public final class AndroidConstants { public static final String WORK_PROFILE = "WORK_PROFILE"; public static final String NOTIFIER_FREQUENCY = "NOTIFIER_FREQUENCY"; public static final String GLOBAL_PROXY = "SET_GLOBAL_PROXY"; + public static final String REMOTE_APP_CONFIG = "REMOTE_APP_CONFIG"; } public final class StatusCodes { diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/public/js/operation-bar.js b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/public/js/operation-bar.js index 854a2eaee..c6e811fae 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/public/js/operation-bar.js +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.operation-bar/public/js/operation-bar.js @@ -491,6 +491,15 @@ var generatePayload = function (operationCode, operationData, deviceList) { } }; break; + case androidOperationConstants["APP_RESTRICTION_OPERATION_CODE"]: + operationType = operationTypeConstants["PROFILE"]; + payload = { + "operation": { + "appIdentifier": operationData["app-id"], + "restrictionPayload": operationData["payload"] + } + }; + break; default: // If the operation is neither of above, it is a command operation operationType = operationTypeConstants["COMMAND"]; @@ -554,5 +563,6 @@ var androidOperationConstants = { "APPLICATION_OPERATION_CODE": "APP-RESTRICTION", "SYSTEM_UPDATE_POLICY_CODE": "SYSTEM_UPDATE_POLICY", "KIOSK_APPS_CODE": "KIOSK_APPS", - "FILE_TRANSFER": "FILE_TRANSFER" + "FILE_TRANSFER": "FILE_TRANSFER", + "APP_RESTRICTION_OPERATION_CODE": "REMOTE_APP_CONFIG" }; diff --git a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/private/config.json b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/private/config.json index 1f8a82010..82394b258 100644 --- a/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/private/config.json +++ b/components/mobile-plugins/android-plugin/org.wso2.carbon.device.mgt.mobile.android.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android.type-view/private/config.json @@ -36,7 +36,8 @@ "perm:android:unlock-devices", "perm:android:control-camera", "perm:android:reboot", - "perm:android:logcat" + "perm:android:logcat", + "perm:android:send-app-restrictions" ], "features": { "DEVICE_RING": { @@ -214,6 +215,24 @@ } ], "permission": "/device-mgt/devices/owning-device/operations/android/wipe" + }, + "REMOTE_APP_CONFIG": { + "icon": "fw-lock", + "formParams": [ + { + "type": "text", + "id": "app-id", + "optional": false, + "label": "Application identifier" + }, + { + "type": "text", + "id": "payload", + "optional": false, + "label": "Application restriction payload" + } + ], + "permission": "/device-mgt/devices/owning-device/operations/android/send-app-conf" } } } diff --git a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml index 30fc71bd6..27e8e19a2 100644 --- a/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml +++ b/features/mobile-plugins-feature/android-plugin-feature/org.wso2.carbon.device.mgt.mobile.android.feature/src/main/resources/devicetypes/android.xml @@ -347,6 +347,13 @@ Unlock the device Unlock the device + + Send app restriction + Send remote configurations to app + + + true