Verifier: Enable and disable non-market apps
A profile owner app may now set the INSTALL_NON_MARKET_APPS setting which
changes whether apps may request packages to be installed.
Bug: 16542504
Change-Id: Ie98c7b0789c530540b4691aa5a962883070a9001
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index cef1625..45fb2ed 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1371,6 +1371,7 @@
<intent-filter>
<action android:name="com.android.cts.verifier.managedprovisioning.BYOD_QUERY" />
<action android:name="com.android.cts.verifier.managedprovisioning.BYOD_REMOVE" />
+ <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK" />
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index e8cca29..ebe3021 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1097,6 +1097,20 @@
<string name="widget_pass">Pass</string>
<string name="widget_fail">Fail</string>
+ <string name="provisioning_byod_nonmarket_allow">Enable non-market apps</string>
+ <string name="provisioning_byod_nonmarket_allow_info">
+ This test verifies that non-market apps can be installed if permitted.\n
+ 1. A package installation UI should appear.\n
+ 2. Accept the package and verify that it installs.
+ </string>
+
+ <string name="provisioning_byod_nonmarket_deny">Disable non-market apps</string>
+ <string name="provisioning_byod_nonmarket_deny_info">
+ This test verifies that non-market apps cannot be installed unless permitted.\n
+ 1. A package installation UI should appear.\n
+ 2. Verify that the installation of the package is refused.
+ </string>
+
<!-- Strings for DeskClock -->
<string name="deskclock_tests">Alarms and Timers Tests</string>
<string name="deskclock_tests_info">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index b697be8..12aa37b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -75,6 +75,8 @@
private TestItem mDeviceAdminVisibleTest;
private TestItem mWorkAppVisibleTest;
private TestItem mCrossProfileIntentFiltersTest;
+ private TestItem mDisableNonMarketTest;
+ private TestItem mEnableNonMarketTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -179,6 +181,16 @@
}
};
+ mDisableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_deny,
+ R.string.provisioning_byod_nonmarket_deny_info,
+ new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
+ .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, false));
+
+ mEnableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_allow,
+ R.string.provisioning_byod_nonmarket_allow_info,
+ new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
+ .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true));
+
Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
Intent chooser = Intent.createChooser(intent, getResources().getString(R.string.provisioning_cross_profile_chooser));
mCrossProfileIntentFiltersTest = new TestItem(this,
@@ -191,6 +203,8 @@
mTests.add(mDeviceAdminVisibleTest);
mTests.add(mWorkAppVisibleTest);
mTests.add(mCrossProfileIntentFiltersTest);
+ mTests.add(mDisableNonMarketTest);
+ mTests.add(mEnableNonMarketTest);
}
@Override
@@ -389,5 +403,4 @@
return view;
}
}
-
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 5dac4bd..277324c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -24,10 +24,14 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
+import static android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS;
+
import com.android.cts.verifier.R;
import com.android.cts.verifier.managedprovisioning.ByodFlowTestActivity.TestResult;
@@ -53,17 +57,33 @@
public static final String EXTRA_PROVISIONED = "extra_provisioned";
- private ComponentName mAdminReceiverComponent;
+ // Primary -> managed intent: set unknown sources restriction and install package
+ public static final String ACTION_INSTALL_APK = "com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK";
+ public static final String EXTRA_ALLOW_NON_MARKET_APPS = INSTALL_NON_MARKET_APPS;
+ private static final int REQUEST_INSTALL_PACKAGE = 1;
+
+ private static final String ORIGINAL_SETTINGS_NAME = "original settings";
+ private Bundle mOriginalSettings;
+
+ private ComponentName mAdminReceiverComponent;
private DevicePolicyManager mDevicePolicyManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ Log.w(TAG, "Restored state");
+ mOriginalSettings = savedInstanceState.getBundle(ORIGINAL_SETTINGS_NAME);
+ } else {
+ mOriginalSettings = new Bundle();
+ }
+
mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
mDevicePolicyManager = (DevicePolicyManager) getSystemService(
Context.DEVICE_POLICY_SERVICE);
- String action = getIntent().getAction();
+ Intent intent = getIntent();
+ String action = intent.getAction();
Log.d(TAG, "ByodHelperActivity.onCreate: " + action);
// we are explicitly started by {@link DeviceAdminTestReceiver} after a successful provisioning.
@@ -83,16 +103,70 @@
mDevicePolicyManager.wipeData(0);
showToast(R.string.provisioning_byod_profile_deleted);
}
+ } else if (action.equals(ACTION_INSTALL_APK)) {
+ boolean allowNonMarket = intent.getBooleanExtra(EXTRA_ALLOW_NON_MARKET_APPS, false);
+ boolean wasAllowed = getAllowNonMarket();
+
+ // Update permission to install non-market apps
+ setAllowNonMarket(allowNonMarket);
+ mOriginalSettings.putBoolean(INSTALL_NON_MARKET_APPS, wasAllowed);
+
+ // Request to install a non-market application- easiest way is to reinstall ourself
+ final Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE)
+ .setData(Uri.parse("package:" + getPackageName()))
+ .putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
+ .putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ startActivityForResult(installIntent, REQUEST_INSTALL_PACKAGE);
+
+ // Not yet ready to finish- wait until the result comes back
+ return;
}
// This activity has no UI and is only used to respond to CtsVerifier in the primary side.
finish();
}
+ @Override
+ protected void onSaveInstanceState(final Bundle savedState) {
+ super.onSaveInstanceState(savedState);
+
+ savedState.putBundle(ORIGINAL_SETTINGS_NAME, mOriginalSettings);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_INSTALL_PACKAGE: {
+ Log.w(TAG, "Received REQUEST_INSTALL_PACKAGE, resultCode = " + resultCode);
+ if (mOriginalSettings.containsKey(INSTALL_NON_MARKET_APPS)) {
+ // Restore original setting
+ setAllowNonMarket(mOriginalSettings.getBoolean(INSTALL_NON_MARKET_APPS));
+ mOriginalSettings.remove(INSTALL_NON_MARKET_APPS);
+ }
+ finish();
+ break;
+ }
+ default: {
+ Log.wtf(TAG, "Unknown requestCode " + requestCode + "; data = " + data);
+ break;
+ }
+ }
+ }
+
private boolean isProfileOwner() {
return mDevicePolicyManager.isAdminActive(mAdminReceiverComponent) &&
mDevicePolicyManager.isProfileOwnerApp(mAdminReceiverComponent.getPackageName());
}
+ private boolean getAllowNonMarket() {
+ String value = Settings.Secure.getString(getContentResolver(), INSTALL_NON_MARKET_APPS);
+ return "1".equals(value);
+ }
+
+ private void setAllowNonMarket(boolean allow) {
+ mDevicePolicyManager.setSecureSetting(mAdminReceiverComponent, INSTALL_NON_MARKET_APPS,
+ (allow ? "1" : "0"));
+ }
+
private void startActivityInPrimary(Intent intent) {
// Disable app components in the current profile, so only the counterpart in the other
// profile can respond (via cross-profile intent filter)
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index 8dccac3..1f78daf 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -50,6 +50,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
filter.addAction(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
+ filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK);
filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
dpm.addCrossProfileIntentFilter(getWho(context), filter,
DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);