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

Commit b214bc44 authored by Neil Fuller's avatar Neil Fuller
Browse files

Split query permission from update permission

Split time zone rules query permission from update permission.
This would allow an app like Settings to determine the current rules
update state, which would enable it to show the version of rules
the device came with, if there have been any updates and whether
a reboot is needed for changes to take effect.

Test: PTS: run -m PtsTimeZoneTestCases
Test: atest FrameworksServicesTests:RulesManagerServiceTest
Bug: 69443060
Change-Id: Ia5d31814d7caee842f5e28870fab61f7c7129386
parent d93e8866
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ package android {
    field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
    field public static final java.lang.String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
    field public static final java.lang.String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
    field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
    field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
    field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
    field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
+7 −4
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ import java.util.Arrays;
 * <p>This interface is intended for use with the default APK-based time zone rules update
 * application but it can also be used by OEMs if that mechanism is turned off using configuration.
 * All callers must possess the {@link android.Manifest.permission#UPDATE_TIME_ZONE_RULES} system
 * permission.
 * permission unless otherwise stated.
 *
 * <p>When using the default mechanism, when properly configured the Android system will send a
 * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with a
@@ -120,9 +120,12 @@ public final class RulesManager {

    /**
     * Returns information about the current time zone rules state such as the IANA version of
     * the system and any currently installed distro. This method is intended to allow clients to
     * determine if the current state can be improved; for example by passing the information to a
     * server that may provide a new distro for download.
     * the system and any currently installed distro. This method allows clients to determine the
     * current device state, perhaps to see if it can be improved; for example by passing the
     * information to a server that may provide a new distro for download.
     *
     * <p>Callers must possess the {@link android.Manifest.permission#QUERY_TIME_ZONE_RULES} system
     * permission.
     */
    public RulesState getRulesState() {
        try {
+6 −0
Original line number Diff line number Diff line
@@ -2397,6 +2397,12 @@
    <permission android:name="android.permission.UPDATE_CONFIG"
        android:protectionLevel="signature|privileged" />

    <!-- Allows an application to query the current time zone rules state
         on device.
         @SystemApi @hide -->
    <permission android:name="android.permission.QUERY_TIME_ZONE_RULES"
                android:protectionLevel="signature|privileged" />

    <!-- Allows a time zone rule updater application to request
         the system installs / uninstalls timezone rules.
         <p>An application requesting this permission is responsible for
+4 −1
Original line number Diff line number Diff line
@@ -92,6 +92,9 @@ public final class RulesManagerService extends IRulesManager.Stub {
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final String REQUIRED_UPDATER_PERMISSION =
            android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final String REQUIRED_QUERY_PERMISSION =
            android.Manifest.permission.QUERY_TIME_ZONE_RULES;
    private static final File SYSTEM_TZ_DATA_FILE = new File("/system/usr/share/zoneinfo/tzdata");
    private static final File TZ_DATA_DIR = new File("/data/misc/zoneinfo");

@@ -131,7 +134,7 @@ public final class RulesManagerService extends IRulesManager.Stub {

    @Override // Binder call
    public RulesState getRulesState() {
        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
        mPermissionHelper.enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);

        return getRulesStateInternal();
    }
+12 −5
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import javax.annotation.Nullable;

import libcore.io.IoUtils;

import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -91,25 +92,25 @@ public class RulesManagerServiceTest {

    @Test(expected = SecurityException.class)
    public void getRulesState_noCallerPermission() throws Exception {
        configureCallerDoesNotHavePermission();
        configureCallerDoesNotHaveQueryPermission();
        mRulesManagerService.getRulesState();
    }

    @Test(expected = SecurityException.class)
    public void requestInstall_noCallerPermission() throws Exception {
        configureCallerDoesNotHavePermission();
        configureCallerDoesNotHaveUpdatePermission();
        mRulesManagerService.requestInstall(null, null, null);
    }

    @Test(expected = SecurityException.class)
    public void requestUninstall_noCallerPermission() throws Exception {
        configureCallerDoesNotHavePermission();
        configureCallerDoesNotHaveUpdatePermission();
        mRulesManagerService.requestUninstall(null, null);
    }

    @Test(expected = SecurityException.class)
    public void requestNothing_noCallerPermission() throws Exception {
        configureCallerDoesNotHavePermission();
        configureCallerDoesNotHaveUpdatePermission();
        mRulesManagerService.requestNothing(null, true);
    }

@@ -916,12 +917,18 @@ public class RulesManagerServiceTest {
                .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
    }

    private void configureCallerDoesNotHavePermission() {
    private void configureCallerDoesNotHaveUpdatePermission() {
        doThrow(new SecurityException("Simulated permission failure"))
                .when(mMockPermissionHelper)
                .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
    }

    private void configureCallerDoesNotHaveQueryPermission() {
        doThrow(new SecurityException("Simulated permission failure"))
                .when(mMockPermissionHelper)
                .enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);
    }

    private void configureStageInstallExpectation(int resultCode)
            throws Exception {
        when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(any(TimeZoneDistro.class)))