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

Commit 093e0a8a authored by Zhi Dou's avatar Zhi Dou Committed by Gerrit Code Review
Browse files

Merge "Return default value if fingerprint doesn't match" into main

parents 396e7c01 0508c32a
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -102,9 +102,7 @@
    {
      // aconfig_storage file java integration tests
      "name": "aconfig_storage_file.test.java"
    }
  ],
  "postsubmit": [
    },
    {
      // aconfig_storage read functional test
      "name": "aconfig_storage_read_functional"
+6 −29
Original line number Diff line number Diff line
@@ -543,7 +543,6 @@ mod tests {
        import android.compat.annotation.UnsupportedAppUsage;
        import android.os.Build;
        import android.os.flagging.PlatformAconfigPackageInternal;
        import android.os.flagging.AconfigStorageReadException;
        import android.util.Log;
        /** @hide */
        public final class FeatureFlagsImpl implements FeatureFlags {
@@ -556,38 +555,16 @@ mod tests {
            private void init() {
                try {
                    PlatformAconfigPackageInternal reader = PlatformAconfigPackageInternal.load("system", "com.android.aconfig.test", 0x5081CE7221C77064L);
                    AconfigStorageReadException error = reader.getException();
                    if (error == null) {
                    disabledRw = reader.getBooleanFlagValue(0);
                    disabledRwExported = reader.getBooleanFlagValue(1);
                    enabledRw = reader.getBooleanFlagValue(7);
                    disabledRwInOtherNamespace = reader.getBooleanFlagValue(2);
                    } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) {
                        disabledRw = reader.getBooleanFlagValue("disabled_rw", false);
                        disabledRwExported = reader.getBooleanFlagValue("disabled_rw_exported", false);
                        enabledRw = reader.getBooleanFlagValue("enabled_rw", true);
                        disabledRwInOtherNamespace = reader.getBooleanFlagValue("disabled_rw_in_other_namespace", false);
                    } else {
                        if (error.getMessage() != null) {
                            Log.e(TAG, error.getMessage());
                        } else {
                            Log.e(TAG, "Encountered a null AconfigStorageReadException");
                        }
                    }
                } catch (Exception e) {
                    if (e.getMessage() != null) {
                        Log.e(TAG, e.getMessage());
                    } else {
                        Log.e(TAG, "Encountered a null Exception");
                    }
                    Log.e(TAG, e.toString());
                } catch (NoClassDefFoundError e) {
                    // for mainline module running on older devices.
                    // This should be replaces to version check, after the version bump.
                    if (e.getMessage() != null) {
                        Log.e(TAG, e.getMessage());
                    } else {
                        Log.e(TAG, "Encountered a null NoClassDefFoundError");
                    }
                    Log.e(TAG, e.toString());
                }
                isCached = true;
            }
+9 −35
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ import android.os.flagging.PlatformAconfigPackageInternal;
{{ -else }}
import android.os.flagging.AconfigPackageInternal;
{{ -endif }}
import android.os.flagging.AconfigStorageReadException;
import android.util.Log;
{{ -endif }}
/** @hide */
@@ -32,44 +31,19 @@ public final class FeatureFlagsImpl implements FeatureFlags \{
{{ -else }}
            AconfigPackageInternal reader = AconfigPackageInternal.load("{container}", "{package_name}", {package_fingerprint});
{{ -endif }}
            AconfigStorageReadException error = reader.getException();
            if (error == null) \{
            {{ for namespace_with_flags in namespace_flags }}
        {{ -for namespace_with_flags in namespace_flags }}
        {{ -for flag in namespace_with_flags.flags }}
        {{ -if flag.is_read_write }}
            {flag.method_name} = reader.getBooleanFlagValue({flag.flag_offset});
            {{ endif }}
            {{ -endfor }}
            {{ -endfor }}
            } else if (Build.VERSION.SDK_INT > 35 && error.getErrorCode() == 5 /* fingerprint doesn't match*/) \{
            {{ for namespace_with_flags in namespace_flags }}
            {{ -for flag in namespace_with_flags.flags }}
            {{ -if flag.is_read_write }}
                {flag.method_name} = reader.getBooleanFlagValue("{flag.flag_name}", {flag.default_value});
        {{ -endif }}
        {{ -endfor }}
        {{ -endfor }}
            } else \{
                if (error.getMessage() != null) \{
                    Log.e(TAG, error.getMessage());
                } else \{
                    Log.e(TAG, "Encountered a null AconfigStorageReadException");
                }
            }
        } catch (Exception e) \{
            if (e.getMessage() != null) \{
                Log.e(TAG, e.getMessage());
            } else \{
                Log.e(TAG, "Encountered a null Exception");
            }
            Log.e(TAG, e.toString());
        } catch (NoClassDefFoundError e) \{
            // for mainline module running on older devices.
            // This should be replaces to version check, after the version bump.
            if (e.getMessage() != null) \{
                Log.e(TAG, e.getMessage());
            } else \{
                Log.e(TAG, "Encountered a null NoClassDefFoundError");
            }
            Log.e(TAG, e.toString());
        }
        isCached = true;
    }
+0 −4
Original line number Diff line number Diff line
@@ -58,10 +58,6 @@ public class StorageFileProviderTest {
                new StorageFileProvider(TestDataUtils.TESTDATA_PATH, TestDataUtils.TESTDATA_PATH);
        PackageTable pt = p.getPackageTable("mock.v1");
        assertNotNull(pt);
        pt =
                StorageFileProvider.getPackageTable(
                        Paths.get(TestDataUtils.TESTDATA_PATH, "mock.v1.package.map"));
        assertNotNull(pt);
        FlagTable f = p.getFlagTable("mock.v1");
        assertNotNull(f);
        FlagValueList v = p.getFlagValueList("mock.v1");
+30 −159
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.os.flagging;

import android.aconfig.storage.AconfigStorageException;
import android.aconfig.storage.FlagTable;
import android.aconfig.storage.FlagValueList;
import android.aconfig.storage.PackageTable;
import android.aconfig.storage.StorageFileProvider;
@@ -41,75 +40,13 @@ import android.os.StrictMode;
 */
public class PlatformAconfigPackageInternal {

    private final FlagTable mFlagTable;
    private final FlagValueList mFlagValueList;
    private final int mPackageId;
    private final int mPackageBooleanStartOffset;
    private final AconfigStorageReadException mException;

    private PlatformAconfigPackageInternal(
            FlagValueList flagValueList,
            FlagTable flagTable,
            int packageBooleanStartOffset,
            int packageId,
            AconfigStorageReadException exception) {
            FlagValueList flagValueList, int packageBooleanStartOffset) {
        this.mFlagValueList = flagValueList;
        this.mFlagTable = flagTable;
        this.mPackageBooleanStartOffset = packageBooleanStartOffset;
        this.mPackageId = packageId;
        this.mException = exception;
    }

    /**
     * Loads an Aconfig Package from platform Aconfig Storage.
     *
     * <p>This method is intended for internal use only and may be changed or removed without
     * notice.
     *
     * <p>This method loads the specified Aconfig Package from the given container.
     *
     * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage.
     * The specific error code can be got using {@link #getException()}.
     *
     * @param container The name of the container.
     * @param packageName The name of the Aconfig package to load.
     * @return An instance of {@link PlatformAconfigPackageInternal}
     * @hide
     */
    @UnsupportedAppUsage
    public static PlatformAconfigPackageInternal load(String container, String packageName) {
        return load(container, packageName, StorageFileProvider.getDefaultProvider());
    }

    /** @hide */
    public static PlatformAconfigPackageInternal load(
            String container, String packageName, StorageFileProvider fileProvider) {
        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
        try {
            PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName);

            if (pNode == null) {
                return createExceptionInstance(
                        AconfigStorageException.ERROR_PACKAGE_NOT_FOUND,
                        "package "
                                + packageName
                                + " in container "
                                + container
                                + " cannot be found on the device");
            }

            return new PlatformAconfigPackageInternal(
                    fileProvider.getFlagValueList(container),
                    fileProvider.getFlagTable(container),
                    pNode.getBooleanStartIndex(),
                    pNode.getPackageId(),
                    null);

        } catch (AconfigStorageException e) {
            return createExceptionInstance(e.getErrorCode(), e.getMessage());
        } finally {
            StrictMode.setThreadPolicy(oldPolicy);
        }
    }

    /**
@@ -118,9 +55,6 @@ public class PlatformAconfigPackageInternal {
     * <p>This method is intended for internal use only and may be changed or removed without
     * notice.
     *
     * <p>AconfigStorageException will be stored if there is an error reading from Aconfig Storage.
     * The specific error code can be got using {@link #getException()}.
     *
     * @param container The name of the container.
     * @param packageName The name of the Aconfig package.
     * @param packageFingerprint The expected fingerprint of the package.
@@ -145,48 +79,40 @@ public class PlatformAconfigPackageInternal {
            long packageFingerprint,
            StorageFileProvider fileProvider) {
        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
        PackageTable.Node pNode = null;
        FlagValueList vList = null;
        try {
            PackageTable.Node pNode = fileProvider.getPackageTable(container).get(packageName);
            pNode = fileProvider.getPackageTable(container).get(packageName);
            vList = fileProvider.getFlagValueList(container);
        } catch (AconfigStorageException e) {
            throw new AconfigStorageReadException(e.getErrorCode(), e.toString());
        } finally {
            StrictMode.setThreadPolicy(oldPolicy);
        }

            if (pNode == null) {
                return createExceptionInstance(
        if (pNode == null || vList == null) {
            throw new AconfigStorageReadException(
                    AconfigStorageReadException.ERROR_PACKAGE_NOT_FOUND,
                    String.format(
                            "package "
                                    + packageName
                                    + " in container "
                                    + container
                                + " cannot be found on the device");
                                    + " cannot be found on the device"));
        }

            if (pNode.hasPackageFingerprint()
                    && packageFingerprint != pNode.getPackageFingerprint()) {
                return new PlatformAconfigPackageInternal(
                        fileProvider.getFlagValueList(container),
                        fileProvider.getFlagTable(container),
                        pNode.getBooleanStartIndex(),
                        pNode.getPackageId(),
                        new AconfigStorageReadException(
                                AconfigStorageException.ERROR_FILE_FINGERPRINT_MISMATCH,
                                "The fingerprint provided for the Aconfig package "
        if (pNode.hasPackageFingerprint() && packageFingerprint != pNode.getPackageFingerprint()) {
            throw new AconfigStorageReadException(
                    5, // AconfigStorageReadException.ERROR_FILE_FINGERPRINT_MISMATCH,
                    String.format(
                            "package "
                                    + packageName
                                    + " in container "
                                    + container
                                        + " does not match"
                                        + " the fingerprint of the package found on the device."));
                                    + " cannot be found on the device"));
        }

            return new PlatformAconfigPackageInternal(
                    fileProvider.getFlagValueList(container),
                    null,
                    pNode.getBooleanStartIndex(),
                    0,
                    null);

        } catch (AconfigStorageException e) {
            return createExceptionInstance(e.getErrorCode(), e.getMessage());
        } finally {
            StrictMode.setThreadPolicy(oldPolicy);
        }
        return new PlatformAconfigPackageInternal(vList, pNode.getBooleanStartIndex());
    }

    /**
@@ -198,10 +124,6 @@ public class PlatformAconfigPackageInternal {
     * <p>This method retrieves the value of a flag within the loaded Aconfig package using its
     * index. The index is generated at build time and may vary between builds.
     *
     * <p>To ensure you are using the correct index, verify that the package's fingerprint matches
     * the expected fingerprint before calling this method. If the fingerprints do not match, use
     * {@link #getBooleanFlagValue(String, boolean)} instead.
     *
     * @param index The index of the flag within the package.
     * @return The boolean value of the flag.
     * @hide
@@ -210,55 +132,4 @@ public class PlatformAconfigPackageInternal {
    public boolean getBooleanFlagValue(int index) {
        return mFlagValueList.getBoolean(index + mPackageBooleanStartOffset);
    }

    /**
     * Retrieves the value of a boolean flag using its name.
     *
     * <p>This method is intended for internal use only and may be changed or removed without
     * notice.
     *
     * <p>This method retrieves the value of a flag within the loaded Aconfig package using its
     * name.
     *
     * @param flagName The name of the flag.
     * @param defaultValue The default value to return if the flag is not found.
     * @return The boolean value of the flag.
     * @hide
     */
    @UnsupportedAppUsage
    public boolean getBooleanFlagValue(String flagName, boolean defaultValue) {
        FlagTable.Node fNode = mFlagTable.get(mPackageId, flagName);
        if (fNode == null) {
            return defaultValue;
        }
        return mFlagValueList.getBoolean(fNode.getFlagIndex() + mPackageBooleanStartOffset);
    }

    /**
     * Returns any exception that occurred during the loading of the Aconfig package.
     *
     * <p>This method is intended for internal use only and may be changed or removed without
     * notice.
     *
     * @return The exception that occurred, or {@code null} if no exception occurred.
     * @hide
     */
    @UnsupportedAppUsage
    public AconfigStorageReadException getException() {
        return mException;
    }

    /**
     * Creates a new {@link PlatformAconfigPackageInternal} instance with an {@link
     * AconfigStorageException}.
     *
     * @param errorCode The error code for the exception.
     * @param message The error message for the exception.
     * @return A new {@link PlatformAconfigPackageInternal} instance with the specified exception.
     */
    private static PlatformAconfigPackageInternal createExceptionInstance(
            int errorCode, String message) {
        return new PlatformAconfigPackageInternal(
                null, null, 0, 0, new AconfigStorageReadException(errorCode, message));
    }
}
Loading