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

Commit ebd99983 authored by Michal Karpinski's avatar Michal Karpinski Committed by Android (Google) Code Review
Browse files

Merge "Add SettingsValidators class and a test for validators enforcement"

parents 480e156b 2c37b085
Loading
Loading
Loading
Loading
+138 −162

File changed.

Preview size limit exceeded, changes collapsed.

+130 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.provider;

import android.content.ComponentName;
import android.net.Uri;

import com.android.internal.util.ArrayUtils;

/**
 * This class provides both interface for validation and common validators
 * used to ensure Settings have meaningful values.
 *
 * @hide
 */
public class SettingsValidators {

    public static final Validator BOOLEAN_VALIDATOR =
            new DiscreteValueValidator(new String[] {"0", "1"});

    public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() {
        @Override
        public boolean validate(String value) {
            try {
                return Integer.parseInt(value) >= 0;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    };

    public static final Validator URI_VALIDATOR = new Validator() {
        @Override
        public boolean validate(String value) {
            try {
                Uri.decode(value);
                return true;
            } catch (IllegalArgumentException e) {
                return false;
            }
        }
    };

    public static final Validator COMPONENT_NAME_VALIDATOR = new Validator() {
        @Override
        public boolean validate(String value) {
            return ComponentName.unflattenFromString(value) != null;
        }
    };

    public static final Validator LENIENT_IP_ADDRESS_VALIDATOR = new Validator() {
        private static final int MAX_IPV6_LENGTH = 45;

        @Override
        public boolean validate(String value) {
            return value.length() <= MAX_IPV6_LENGTH;
        }
    };

    public interface Validator {
        boolean validate(String value);
    }

    public static final class DiscreteValueValidator implements Validator {
        private final String[] mValues;

        public DiscreteValueValidator(String[] values) {
            mValues = values;
        }

        @Override
        public boolean validate(String value) {
            return ArrayUtils.contains(mValues, value);
        }
    }

    public static final class InclusiveIntegerRangeValidator implements Validator {
        private final int mMin;
        private final int mMax;

        public InclusiveIntegerRangeValidator(int min, int max) {
            mMin = min;
            mMax = max;
        }

        @Override
        public boolean validate(String value) {
            try {
                final int intValue = Integer.parseInt(value);
                return intValue >= mMin && intValue <= mMax;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }

    public static final class InclusiveFloatRangeValidator implements Validator {
        private final float mMin;
        private final float mMax;

        public InclusiveFloatRangeValidator(float min, float max) {
            mMin = min;
            mMax = max;
        }

        @Override
        public boolean validate(String value) {
            try {
                final float floatValue = Float.parseFloat(value);
                return floatValue >= mMin && floatValue <= mMax;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }
}
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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 android.provider;

import static org.junit.Assert.fail;

import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests that ensure all backed up settings have non-null validators. */
@Presubmit
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SettingsValidatorsTest {

    @Test
    public void ensureAllBackedUpSystemSettingsHaveValidators() {
        StringBuilder offenders = new StringBuilder();
        for (String setting : Settings.System.SETTINGS_TO_BACKUP) {
            if (Settings.System.VALIDATORS.get(setting) == null) {
                offenders.append(setting).append(" ");
            }
        }

        // if there're any offenders fail the test and report them
        String offendersStr = offenders.toString();
        if (offendersStr.length() > 0) {
            fail("All Settings.System settings that are backed up have to have a non-null"
                    + " validator, but those don't: " + offendersStr);
        }
    }
}
+21 −1
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
import android.provider.SettingsValidators;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.text.TextUtils;
@@ -297,6 +298,10 @@ public class SettingsProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        Settings.setInSystemServer();

        // fail to boot if there're any backed up settings that don't have a non-null validator
        ensureAllBackedUpSystemSettingsHaveValidators();

        synchronized (mLock) {
            mUserManager = UserManager.get(getContext());
            mPackageManager = AppGlobals.getPackageManager();
@@ -314,6 +319,21 @@ public class SettingsProvider extends ContentProvider {
        return true;
    }

    private void ensureAllBackedUpSystemSettingsHaveValidators() {
        StringBuilder offenders = new StringBuilder();
        for (String setting : Settings.System.SETTINGS_TO_BACKUP) {
            if (Settings.System.VALIDATORS.get(setting) == null) {
                offenders.append(setting).append(" ");
            }
        }

        String offendersStr = offenders.toString();
        if (offendersStr.length() > 0) {
            throw new RuntimeException("All Settings.System settings that are backed up must"
                    + " have a non-null validator, but those don't: " + offendersStr);
        }
    }

    @Override
    public Bundle call(String method, String name, Bundle args) {
        final int requestingUserId = getRequestingUserId(args);
@@ -1472,7 +1492,7 @@ public class SettingsProvider extends ContentProvider {
    }

    private void validateSystemSettingValue(String name, String value) {
        Settings.System.Validator validator = Settings.System.VALIDATORS.get(name);
        SettingsValidators.Validator validator = Settings.System.VALIDATORS.get(name);
        if (validator != null && !validator.validate(value)) {
            throw new IllegalArgumentException("Invalid value: " + value
                    + " for setting: " + name);