Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b5aa407 authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Handle saving and restoring ints in application restrictions

Unit tests for restrictions types and proper escaping.

Change-Id: Iac35521faf5798398a89fecbad82fcdd256a4146
parent 82ed45da
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ public class UserManagerService extends IUserManager.Stub {
    private static final String ATTR_TYPE_STRING_ARRAY = "sa";
    private static final String ATTR_TYPE_STRING = "s";
    private static final String ATTR_TYPE_BOOLEAN = "b";
    private static final String ATTR_TYPE_INTEGER = "i";

    private static final String USER_INFO_DIR = "system" + File.separator + "users";
    private static final String USER_LIST_FILENAME = "userlist.xml";
@@ -1532,16 +1533,18 @@ public class UserManagerService extends IUserManager.Stub {
                        String [] valueStrings = new String[values.size()];
                        values.toArray(valueStrings);
                        restrictions.putStringArray(key, valueStrings);
                    } else if (ATTR_TYPE_BOOLEAN.equals(valType)) {
                        restrictions.putBoolean(key, Boolean.parseBoolean(
                                parser.nextText().trim()));
                    } else {
                        String value = parser.nextText().trim();
                        if (ATTR_TYPE_BOOLEAN.equals(valType)) {
                            restrictions.putBoolean(key, Boolean.parseBoolean(value));
                        } else if (ATTR_TYPE_INTEGER.equals(valType)) {
                            restrictions.putInt(key, Integer.parseInt(value));
                        } else {
                            restrictions.putString(key, value);
                        }
                    }
                }

            }
        } catch (IOException ioe) {
        } catch (XmlPullParserException pe) {
        } finally {
@@ -1581,6 +1584,9 @@ public class UserManagerService extends IUserManager.Stub {
                if (value instanceof Boolean) {
                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
                    serializer.text(value.toString());
                } else if (value instanceof Integer) {
                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
                    serializer.text(value.toString());
                } else if (value == null || value instanceof String) {
                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
                    serializer.text(value != null ? (String) value : "");
+11 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />

    <application>
        <uses-library android:name="android.test.runner" />
@@ -53,6 +54,15 @@
          </intent-filter>
        </service>

        <receiver android:name="com.android.server.devicepolicy.ApplicationRestrictionsTest$AdminReceiver"
                android:permission="android.permission.BIND_DEVICE_ADMIN">
            <meta-data android:name="android.app.device_admin"
                       android:resource="@xml/device_admin_sample" />
            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>

    </application>

    <instrumentation
+29 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
        <watch-login />
        <reset-password />
        <force-lock />
        <wipe-data />
        <expire-password />
        <encrypted-storage />
        <disable-camera />
        <disable-keyguard-features />
    </uses-policies>
</device-admin>
+135 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.devicepolicy;

import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * Tests for application restrictions persisting via profile owner:
 *   make -j FrameworksServicesTests
 *   runtest --path frameworks/base/services/tests/servicestests/ \
 *       src/com/android/server/devicepolicy/ApplicationRestrictionsTest.java
 */
public class ApplicationRestrictionsTest extends AndroidTestCase {

    static DevicePolicyManager sDpm;
    static ComponentName sAdminReceiver;
    private static final String RESTRICTED_APP = "com.example.restrictedApp";
    static boolean sAddBack = false;

    public static class AdminReceiver extends DeviceAdminReceiver {

        @Override
        public void onDisabled(Context context, Intent intent) {
            if (sAddBack) {
                sDpm.setActiveAdmin(sAdminReceiver, false);
                sAddBack = false;
            }

            super.onDisabled(context, intent);
        }
    }

    @Override
    public void setUp() {
        final Context context = getContext();
        sAdminReceiver = new ComponentName(mContext.getPackageName(),
                AdminReceiver.class.getName());
        sDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        Settings.Secure.putInt(context.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0);
        sDpm.setProfileOwner(context.getPackageName(), "Test", UserHandle.myUserId());
        Settings.Secure.putInt(context.getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 1);
        // Remove the admin if already registered. It's async, so add it back
        // when the admin gets a broadcast. Otherwise add it back right away.
        if (sDpm.isAdminActive(sAdminReceiver)) {
            sAddBack = true;
            sDpm.removeActiveAdmin(sAdminReceiver);
        } else {
            sDpm.setActiveAdmin(sAdminReceiver, false);
        }
    }

    @Override
    public void tearDown() {
        Settings.Secure.putInt(getContext().getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 0);
        sDpm.removeActiveAdmin(sAdminReceiver);
        Settings.Secure.putInt(getContext().getContentResolver(),
                Settings.Secure.USER_SETUP_COMPLETE, 1);
    }

    public void testSettingRestrictions() {
        Bundle restrictions = new Bundle();
        restrictions.putString("KEY_STRING", "Foo");
        assertNotNull(sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP));
        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
        assertNotNull(returned);
        assertEquals(returned.size(), 1);
        assertEquals(returned.get("KEY_STRING"), "Foo");
        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, new Bundle());
        returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
        assertEquals(returned.size(), 0);
    }

    public void testRestrictionTypes() {
        Bundle restrictions = new Bundle();
        restrictions.putString("KEY_STRING", "Foo");
        restrictions.putInt("KEY_INT", 7);
        restrictions.putBoolean("KEY_BOOLEAN", true);
        restrictions.putBoolean("KEY_BOOLEAN_2", false);
        restrictions.putString("KEY_STRING_2", "Bar");
        restrictions.putStringArray("KEY_STR_ARRAY", new String[] { "Foo", "Bar" });
        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
        assertTrue(returned.getBoolean("KEY_BOOLEAN"));
        assertFalse(returned.getBoolean("KEY_BOOLEAN_2"));
        assertFalse(returned.getBoolean("KEY_BOOLEAN_3"));
        assertEquals(returned.getInt("KEY_INT"), 7);
        assertTrue(returned.get("KEY_BOOLEAN") instanceof Boolean);
        assertTrue(returned.get("KEY_INT") instanceof Integer);
        assertEquals(returned.get("KEY_STRING"), "Foo");
        assertEquals(returned.get("KEY_STRING_2"), "Bar");
        assertTrue(returned.getStringArray("KEY_STR_ARRAY") instanceof String[]);
        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, new Bundle());
    }

    public void testTextEscaping() {
        String fancyText = "<This contains XML/> <JSON> "
                + "{ \"One\": { \"OneOne\": \"11\", \"OneTwo\": \"12\" }, \"Two\": \"2\" } <JSON/>";
        Bundle restrictions = new Bundle();
        restrictions.putString("KEY_FANCY_TEXT", fancyText);
        sDpm.setApplicationRestrictions(sAdminReceiver, RESTRICTED_APP, restrictions);
        Bundle returned = sDpm.getApplicationRestrictions(sAdminReceiver, RESTRICTED_APP);
        assertEquals(returned.getString("KEY_FANCY_TEXT"), fancyText);
    }
}
 No newline at end of file