Class Overview
This class supports MDM(EMM) to create a workspace(container) protected with Dual DAR and
provides APIs to access and set Dual DAR configurations.
Usage
Following code snippet represents how an MDM Agent shall create a Dual DAR container
// Create Android For Work manage provisioning intent
Intent intent = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, EDMAppAdmin.getComponentName(mContext));
// Create Dual DAR configuration bundle
PersistableBundle dualDARConfig = new PersistableBundle();
dualDARConfig.putBoolean(DualDARPolicy.KEY_DUAL_DAR_CONFIG,true);
dualDARConfig.putString(DualDARPolicy.KEY_CONFIG_CLIENT_PACKAGE,"<client_package_name>");
dualDARConfig.putString(DualDARPolicy.KEY_CONFIG_CLIENT_SIGNATURE,"<client_package_signature>");
intent.putExtra(android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, dualDARConfig);
// Start workspace provisioning
startActivityForResult(intent, RESULT_PROVISION_MANAGED_PROFILE);
If the KEY_CONFIG_CLIENT_PACKAGE is not specified (or empty) during workspace(container) creation,
then the inner layer encryption is performed by an independent FIPS 140-2 certified cryptographic
module included on the device.
NOTE: This class is only applicable to Dual DAR enabled workspace(container).
|
Summary
Nested Classes |
class |
DualDARPolicy.DUAL_DAR_VERSION_CODES |
Enumeration of the currently known DUAL DAR version codes. |
[Expand]
Inherited Methods |
From class
java.lang.Object
Object
|
clone()
|
boolean
|
equals(Object arg0)
|
void
|
finalize()
|
final
Class<?>
|
getClass()
|
int
|
hashCode()
|
final
void
|
notify()
|
final
void
|
notifyAll()
|
String
|
toString()
|
final
void
|
wait(long arg0, int arg1)
|
final
void
|
wait(long arg0)
|
final
void
|
wait()
|
|
Constants
public
static
final
int
ERROR_FAILURE_IN_SETTING_DATA_LOCK_TIMEOUT
Since: API level 28
Signifies FAILURE in setting data lock timeout
Usage
Error code used by an application to identify the result of the execution is failure in case of setting data lock timeout. |
Constant Value:
-1
(0xffffffff)
public
static
final
int
ERROR_FAILURE_IN_SETTING_DE_RESTRICTION
Since: API level 28
Signifies FAILURE in setting DE storage restriction
Usage
Error code used by an application to identify the result of the execution is failure in case of setting DE storage restriction. |
Constant Value:
-3
(0xfffffffd)
public
static
final
int
ERROR_FAILURE_IN_SETTING_WHITELIST_PACKAGES
Since: API level 28
Signifies FAILURE in setting data lock whitelisted packages
Usage
Error code used by an application to identify the result of the execution is failure in case of setting whitelisted packages. |
Constant Value:
-2
(0xfffffffe)
public
static
final
int
ERROR_NONE
Since: API level 28
Usage
Error code used by an application to identify the result of the execution is success. |
Constant Value:
0
(0x00000000)
public
static
final
String
KEY_CONFIG_CLIENT_LOCATION
Since: API level 33
Used to set Dual DAR Client App's location during workspace(container) creation time.
Usage
Used as a String param field in admin extras bundle passed as
DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE with
DevicePolicyManager#PROVISIONING_MODE_MANAGED_PROFILE extra value.
Client location should be an external storage(sdcard area) and should be passed with "file://" prefix.
// Create Dual DAR with configuration bundle
PersistableBundle adminExtras = new PersistableBundle();
adminExtras.putBoolean(DualDARPolicy.KEY_DUAL_DAR_CONFIG, true);
adminExtras.putString(DualDARPolicy.KEY_CONFIG_CLIENT_PACKAGE, DUALDAR_CLIENT_EXAMPLE_PACKAGE_NAME);
adminExtras.putString(DualDARPolicy.KEY_CONFIG_CLIENT_SIGNATURE, DUALDAR_CLIENT_EXAMPLE_PACKAGE_SHA256_SIGNATURE);
// Set the file path of the client exist location adding with "file://" prefix.
String DUALDAR_CLIENT_PACKAGE_DOWNLOAD_LOCATION = getExternalFilesDir(null) + "/client_example_app.apk";
adminExtras.putString(DualDARPolicy.KEY_CONFIG_CLIENT_LOCATION, "file://" + DUALDAR_CLIENT_PACKAGE_DOWNLOAD_LOCATION);
// Param field in admin extras bundle passed as DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
Intent intent = new Intent();
if (adminExtras !=null && adminExtras.size() > 0) {
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtras);
}
// Return DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE in DevicePolicyManager.EXTRA_PROVISIONING_MODE as result.
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_MODE, DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE);
// Since KNOX 3.8 DualDAR supports on DO Mode. The extra value needs to be replaced with PROVISIONING_MODE_FULLY_MANAGED_DEVICE.
//intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_MODE, DevicePolicyManager.PROVISIONING_MODE_FULLY_MANAGED_DEVICE);
Note: To be used during either container(WPCOD) or Device Owner provisioning time. |
Constant Value:
"dualdar-config-client-location"
public
static
final
String
KEY_CONFIG_CLIENT_PACKAGE
Since: API level 28
Used to set Dual DAR Client App's package name during workspace(container) creation time.
Also used in getConfig()
to get Client App's package name.
Constant Value:
"dualdar-config-client-package"
public
static
final
String
KEY_CONFIG_CLIENT_SIGNATURE
Since: API level 28
Used to set Dual DAR Client App's signature during workspace(container) creation time.
Also used in getConfig()
to get Client App's signature.
Constant Value:
"dualdar-config-client-signature"
public
static
final
String
KEY_CONFIG_DATA_LOCK_TIMEOUT
Since: API level 28
Usage
Used as a Long by the application that is administering the workspace(container) to set the
data lock timeout.
The timeout can range from 1*60*1000 to Long.MAX_VALUE milliseconds for a given Managed Profile.
The timeout can range from 1*60*1000*5 to Long.MAX_VALUE milliseconds for a given Managed Device.
The default timeout is set to infinity. To set timeout to infinity use -1
Note: To be used as bundle params key with
getConfig() and setConfig(Bundle) only. |
Constant Value:
"dualdar-config-datalock-timeout"
public
static
final
String
KEY_CONFIG_DE_RESTRICTION
Since: API level 28
Used to enable/disable DE storage access to applications running in Dual DAR enabled workspace(container).
Usage
Used as a Boolean by the application that is administering the workspace(container) to allow/disallow
packages to access DE storage. If enabled (set to true ), only whitelisted applications
(refer KEY_CONFIG_WHITELISTED_DATA_LOCK_STATE_PACKAGES ) can access DE storage.
If disabled (set to false ) all applications can access DE storage.
Note: To be used as bundle params key with
getConfig() and setConfig(Bundle) only. Default value is false . |
Constant Value:
"dualdar-config-de-restriction"
public
static
final
String
KEY_CONFIG_WHITELISTED_DATA_LOCK_STATE_PACKAGES
Since: API level 28
Usage
Used as a Parcelable(AppIdentity ) Array by the application that is administering the workspace(container) to set the
whitelisted packages to run in data locked state.
This will overwrite previously set list of applications.
Setting an empty list will clear previously set list.
Note: To be used as bundle params key with
getConfig() and setConfig(Bundle) only. |
Constant Value:
"dualdar-config-datalock-whitelistpackages"
public
static
final
String
KEY_DUAL_DAR_CONFIG
Since: API level 28
Used to mark workspace(container) for Dual DAR protection during creation time.
Constant Value:
"dualdar-config"
Public Methods
public
boolean
clearResetPasswordTokenForInner
()
API to revoke current inner layer password token at DualDAR for fully managed devices use case
Returns
- true if the operation is successful, false otherwise
Usage
Called by a device owner to revoke the current token which was set via
setResetPasswordTokenForInner(byte[]) .
The device must be enrolled as DualDAR for fully managed devices in order to call this API, otherwise a Security Exception will be thrown.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
boolean result = dualDARPolicy.clearResetPasswordTokenForInner();
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
Bundle
getConfig
()
API to get active DualDAR Config
Returns
- returns current active DualDAR config
For Container:
// When you create workspace(container) successfully, containerID will be returned via intent.
// Use this containerID in below API.
EnterpriseKnoxManager ekm = EnterpriseKnoxManager.getInstance(context);
KnoxContainerManager kcm = ekm.getKnoxContainerManager(containerID);
DualDARPolicy dualDARPolicy = kcm.getDualDARPolicy();
try {
// get Dual DAR active config
Bundle config = dualDARPolicy.getConfig();
String clientPackage = config.getString(DualDARPolicy.KEY_CONFIG_CLIENT_PACKAGE);
String clientSignature = config.getString(DualDARPolicy.KEY_CONFIG_CLIENT_SIGNATURE);
long dataLockTimeout = config.getLong(DualDARPolicy.KEY_CONFIG_DATA_LOCK_TIMEOUT);
boolean deRestriction = config.getBoolean(DualDARPolicy.KEY_CONFIG_DE_RESTRICTION);
Parcelable[] parcelables = config.getParcelableArray(DualDARPolicy.KEY_CONFIG_WHITELISTED_DATA_LOCK_STATE_PACKAGES);
AppIdentity[] datalockWhitelistedPackages = new AppIdentity[parcelables.length];
for(int i=0;i<parcelables.length;i++) {
datalockWhitelistedPackages[i] = (AppIdentity) parcelables[i];
}
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
static
String
getDualDARVersion
()
Get the Dual DAR version.
Format: <major.minor.patch>
where major, minor and patch are the string representations of the
version number's three components: major version number, minor version number
and patch. The components must appear in the specified order, and must be separated
by periods.
The components are used by convention as follows:
Major:
A higher version number might indicate a major rewrite of a product where backward
compatibility cannot be assumed.
Minor:
If the major version number remains the same, but the
minor version number is increased, then this indicates significant enhancement with the
intention of backward compatibility. A higher minor version number might indicate
fully backward-compatible new version of a product.
Patch:
If the major and minor version numbers are same but
patches is increased, then the product is intended to be fully interchangeable.
A higher patch number might indicate bug fixes and security patches.
Returns
null
if DualDAR feature not available, else DualDAR version in <major.minor.patch> format.
Usage
Administrator can get the DualDAR version on the product. |
public
int
getPasswordMinimumLengthForInner
()
API to get password minimum length for inner layer password at DualDAR for fully managed devices use case
Returns
- minimum required length for inner layer password
Usage
Retrieves the most restrictive value for inner password.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
int length = dualDARPolicy.getPasswordMinimumLength();
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
boolean
isActivePasswordSufficientForInner
()
API to verify if current inner layer password is sufficient at DualDAR for fully managed devices use case
Returns
- true if password fills all required policies, false otherwise
Usage
Retrieves whether the inner layer password meets all password policy requirements (quality, minimum length) that have been requested.
The device must be enrolled as DualDAR for fully managed devices in order to call this API, otherwise a Security Exception will be thrown.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
boolean isSufficient = dualDARPolicy.isActivePasswordSufficientForInner();
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
boolean
isResetPasswordTokenActiveForInner
()
API to check if current inner layer password token is active at DualDAR for fully managed devices use case
Returns
- true if the token is active, false otherwise
Usage
Called by a device owner to check if the current inner layer password token is active. The device must be enrolled
as DualDAR for fully managed devices in order to call this API, otherwise a Security Exception will be thrown.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
boolean isActive = dualDARPolicy.isResetPasswordTokenActiveForInner();
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
boolean
resetPasswordWithTokenForInner
(String password, byte[] token)
API to force the device to set a new password for inner layer at DualDAR for fully managed devices use case
Parameters
password
| The new password for inner layer. null or empty clears the password |
token
| the password reset token previously provisioned by setResetPasswordToken |
Returns
- true if the password was applied, or false if it is not acceptable for the current constraints
Usage
Force a new unlock password on the device owner profile.
The supplied token must have been previously provisioned via setResetPasswordTokenForInner(byte[]) , and in active state
isResetPasswordTokenActiveForInner() .
The given password must be sufficient for the current password quality and length constraints as returned by
getPasswordQuality(ComponentName)
and getPasswordMinimumLengthForInner() ; if it does not meet these constraints, then it will be rejected and false returned. Note that
the password must be stronger than requested quality, for example, a password containing alphanumeric characters when the requested quality is only numeric.
The device must be enrolled as DualDAR for fully managed devices in order to call this API, otherwise a Security Exception will be thrown.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
byte[] token = createToken();
String newPassword = "test123";
// Set token before reset password
dualDARPolicy.setResetPasswordWithTokenForInner(token);
// Set new password
boolean result = dualDARPolicy.resetPasswordWithTokenForInner(password, token);
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
int
setConfig
(Bundle config)
API to set DualDAR Config
Parameters
config
| new Dual DAR configuration to be set |
For Container:
// When you create workspace(container) successfully, containerID will be returned via intent.
// Use this containerID in below API.
EnterpriseKnoxManager ekm = EnterpriseKnoxManager.getInstance(context);
KnoxContainerManager kcm = ekm.getKnoxContainerManager(containerID);
DualDARPolicy dualDARPolicy = kcm.getDualDARPolicy();
try {
// set new Dual DAR config
Bundle newConfig = new Bundle();
newConfig.putBoolean(DualDARPolicy.KEY_CONFIG_DE_RESTRICTION, false);
newConfig.putLong(DualDARPolicy.KEY_CONFIG_DATA_LOCK_TIMEOUT, 62000);
List<AppIdentity> whitelistPackages = new ArrayList<>();
whitelistPackages.add(new AppIdentity("com.test.app1","sign1"));
whitelistPackages.add(new AppIdentity("com.test.app2","sign2"));
newConfig.putParcelableArray(DualDARPolicy.KEY_CONFIG_WHITELISTED_DATA_LOCK_STATE_PACKAGES,
(Parcelable[]) whitelistPackages.toArray(new AppIdentity[0]));
newConfig.putBoolean(DualDARPolicy.KEY_CONFIG_DE_RESTRICTION, true);
dualDARPolicy.setConfig(newConfig);
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
boolean
setPasswordMinimumLengthForInner
(int length)
API to set password minimum length for inner layer password at DualDAR for fully managed devices use case
Parameters
length
| new inner layer password minimum length |
Returns
- true if the operation is successful, false otherwise
Usage
Called by a device owner to set the minimum allowed password length. After setting this, the user
will not be able to enter a new password that is not at least as restrictive as what has been set. This constraint is only imposed if the
administrator has also requested either
PASSWORD_QUALITY_NUMERIC,
PASSWORD_QUALITY_ALPHABETIC,
PASSWORD_QUALITY_ALPHANUMERIC,
or PASSWORD_QUALITY_COMPLEX
with setPasswordQuality(ComponentName, int).
The device must be enrolled as DualDAR for fully managed devices in order to call this API, otherwise a Security
Exception will be thrown.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
int minimumLength = 5;
try {
dualDARPolicy.setPasswordMinimumLengthForInner(minimumLength);
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |
public
boolean
setResetPasswordTokenForInner
(byte[] token)
API to set a token before reset inner layer password at DualDAR for fully managed devices use case
Parameters
token
| a secure token at least 32-byte long, which must be generated by a
cryptographically strong random number generator |
Returns
- true if the operation is successful, false otherwise
Usage
Called by a device owner to provision a token which can
later be used to reset the second password via resetPasswordWithTokenForInner(String, byte[]) .
If the inner layer currently has a lockscreen password, the provisioned token will not be immediately usable; it only becomes
active after the user performs a confirm credential operation, which happens after user turns off and on the screen in order to
confirm the second credential, or the device owner can call
DevicePolicyManager.lockNow()
If the user has no lockscreen password, the token is activated immediately. In all cases, the active state of the current
token can be checked by isResetPasswordTokenActiveForInner() . For security reasons, un-activated
tokens are only stored in memory and will be lost once the device reboots. In this case a new token needs to be provisioned again.
Once provisioned and activated, the token will remain effective even if the user changes or clears the lockscreen password.
The device must be enrolled as DualDAR for fully managed devices in order to call this API, otherwise a Security Exception will be
thrown.
NOTE : This token is highly sensitive and should be treated at the same level as user credentials.
In particular, NEVER store this token on device in plaintext. Do not store the plaintext token in device-encrypted
storage if it will be needed to reset password on file-based encryption devices before user unlocks.
Consider carefully how any password token will be stored on your server and who
will need access to them. Tokens may be the subject of legal access requests.
EnterpriseDeviceManager edm = EnterpriseDeviceManager.getInstance(context);
DualDARPolicy dualDARPolicy = edm.getDualDARPolicy();
try {
// Generating a secure token
byte[] generatedToken = createSecureToken();
// Setting setResetPasswordTokenForInner with generated secure token
boolean result = dualDARPolicy.setResetPasswordTokenForInner(generatedToken);
} catch (SecurityException e) {
Log.w(TAG, "SecurityException: " + e);
}
|
Permission
The use of this API requires the caller to have the
"com.samsung.android.knox.permission.KNOX_DUAL_DAR" permission with a
protection level of signature. |