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

Commit 3887bf91 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Android (Google) Code Review
Browse files

Merge "Add SDK version checks for Trash feature" into main

parents 1dfaf53c c7e1fa6a
Loading
Loading
Loading
Loading
+31 −28
Original line number Diff line number Diff line
@@ -21,12 +21,9 @@ import android.util.Log
import com.android.documentsui.flags.Flags
import com.android.modules.utils.build.SdkLevel

/**
 * Wrap aconfig generated flags to allow us to override flags in tests.
 */
class FlagUtils private constructor(
    private val overrides: MutableMap<String, Boolean> = mutableMapOf()
) {
/** Wrap aconfig generated flags to allow us to override flags in tests. */
class FlagUtils
private constructor(private val overrides: MutableMap<String, Boolean> = mutableMapOf()) {
    companion object {
        private const val TAG = "FlagUtils"
        @Volatile private var instance: FlagUtils = FlagUtils()
@@ -69,27 +66,26 @@ class FlagUtils private constructor(

        @JvmStatic
        fun isSearchV2Enabled(): Boolean {
            val flag = getInstance().overrides.getOrDefault(
                Flags.FLAG_USE_SEARCH_V2_READ_ONLY,
                Flags.useSearchV2ReadOnly()
            )
            val flag =
                getInstance()
                    .overrides
                    .getOrDefault(Flags.FLAG_USE_SEARCH_V2_READ_ONLY, Flags.useSearchV2ReadOnly())
            return flag && isUseMaterial3FlagEnabled()
        }

        @JvmStatic
        fun isDesktopFileHandlingFlagEnabled(): Boolean {
            return getInstance().overrides.getOrDefault(
                Flags.FLAG_DESKTOP_FILE_HANDLING_RO,
                Flags.desktopFileHandlingRo()
            )
            return getInstance()
                .overrides
                .getOrDefault(Flags.FLAG_DESKTOP_FILE_HANDLING_RO, Flags.desktopFileHandlingRo())
        }

        @JvmStatic
        fun isDesktopUxPhase2FlagEnabled(): Boolean {
            val flag = getInstance().overrides.getOrDefault(
                Flags.FLAG_DESKTOP_UX_PHASE_2_RO,
                Flags.desktopUxPhase2Ro()
            )
            val flag =
                getInstance()
                    .overrides
                    .getOrDefault(Flags.FLAG_DESKTOP_UX_PHASE_2_RO, Flags.desktopUxPhase2Ro())
            return flag && isUseMaterial3FlagEnabled()
        }

@@ -102,10 +98,10 @@ class FlagUtils private constructor(

        @JvmStatic
        fun isVisualSignalsFlagEnabled(): Boolean {
            val flag = getInstance().overrides.getOrDefault(
                Flags.FLAG_VISUAL_SIGNALS_RO,
                Flags.visualSignalsRo()
            )
            val flag =
                getInstance()
                    .overrides
                    .getOrDefault(Flags.FLAG_VISUAL_SIGNALS_RO, Flags.visualSignalsRo())
            return flag && isUseMaterial3FlagEnabled()
        }

@@ -118,17 +114,24 @@ class FlagUtils private constructor(

        @JvmStatic
        fun isTrashFlowEnabled(): Boolean {
            if (!SdkLevel.isAtLeastB()) {
            // Check if the platform SDK is newer than Android Baklava (SDK 36).
            // The Trash feature relies on DocumentsContract APIs introduced in the
            // Android release after Baklava.
            // This specific Trash feature is NOT backward compatible with platforms
            // at or below Baklava because the required APIs are missing.
            // This check ensures the feature is only considered enabled on
            // supported platform versions, preventing runtime errors if the module
            // runs on an older base OS.
            if (!VersionUtils.isGreaterThanB()) {
                return false
            }
            // If API flag is not enabled, then trash flow will be disabled
            if (!enableDocumentsTrashApi()) {
                return false
            }
            return getInstance().overrides.getOrDefault(
                Flags.FLAG_ENABLE_TRASH_FLOW_RO,
                Flags.enableTrashFlowRo()
            )
            return getInstance()
                .overrides
                .getOrDefault(Flags.FLAG_ENABLE_TRASH_FLOW_RO, Flags.enableTrashFlowRo())
        }

        @JvmStatic
+9 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.documentsui.util;

import android.os.Build;

import com.android.modules.utils.build.SdkLevel;

/**
@@ -40,4 +42,11 @@ public class VersionUtils {
    public static boolean isAtLeastS() {
        return SdkLevel.isAtLeastS();
    }

    /**
     * Returns whether the device is running on a version newer than Android BAKLAVA.
     */
    public static boolean isGreaterThanB() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.BAKLAVA;
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -86,9 +86,11 @@ public abstract class AbstractJobTest<T extends Job> {

    @After
    public void tearDown() throws Exception {
        if (mDocs != null) {
            resetStorage();
            mDocs.cleanUp();
        }
    }

    private void resetStorage() throws RemoteException {
        mDocs.clear(null, null);
+15 −3
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.app.Notification.CATEGORY_ERROR
import android.app.Notification.EXTRA_TEXT
import android.app.Notification.EXTRA_TITLE
import android.net.Uri
import android.os.Build
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.CheckFlagsRule
@@ -28,12 +27,13 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.provider.DocumentsContract.buildDocumentUri
import android.provider.Flags.FLAG_ENABLE_DOCUMENTS_TRASH_API
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.android.documentsui.TrashDocumentHelper
import com.android.documentsui.flags.Flags
import com.android.documentsui.rules.OverrideFlagsRule
import com.android.documentsui.services.FileOperationService.OPERATION_RESTORE
import com.android.documentsui.util.VersionUtils
import com.google.common.truth.Truth.assertThat
import org.junit.Assume.assumeTrue
import org.junit.Rule
import org.junit.Test

@@ -52,13 +52,25 @@ import org.junit.Test
 * directories (<parent_1>, <parent_2>) inside ".trash-storage" are then removed.
 */
@MediumTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
internal class RestoreJobTest : AbstractJobTest<TrashJob>() {
    @get:Rule val setFlags = OverrideFlagsRule()

    @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()

    override fun setUp() {
        // Skip test if the platform SDK is not newer than Android Baklava (SDK 36).
        // The Trash feature under test relies on DocumentsContract APIs introduced in the
        // Android release after Baklava (SDK 36).
        // As DocumentsUI is a Mainline module, it's subject to MTS testing, which runs on
        // older Android base builds to verify backward compatibility. However, this specific
        // Trash feature lacks backward compatibility with platforms at or below Baklava.
        // This assumption prevents failures when the test runs on an older base OS
        // without the necessary APIs.
        assumeTrue(VersionUtils.isGreaterThanB())
        super.setUp()
    }

    /**
     * Tests the restoration of a single file. Verifies that the file is moved to its original path
     * and that the parent directories within the trash are removed.
+16 −7
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.app.Notification.CATEGORY_ERROR
import android.app.Notification.EXTRA_TEXT
import android.app.Notification.EXTRA_TITLE
import android.net.Uri
import android.os.Build
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.RequiresFlagsEnabled
import android.platform.test.flag.junit.CheckFlagsRule
@@ -28,26 +27,39 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.provider.DocumentsContract.buildDocumentUri
import android.provider.Flags.FLAG_ENABLE_DOCUMENTS_TRASH_API
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.android.documentsui.TrashDocumentHelper
import com.android.documentsui.base.DocumentInfo
import com.android.documentsui.flags.Flags
import com.android.documentsui.rules.OverrideFlagsRule
import com.android.documentsui.services.FileOperationService.OPERATION_TRASH
import com.android.documentsui.util.VersionUtils
import com.google.common.truth.Truth.assertThat
import org.junit.Assume.assumeTrue
import org.junit.Rule
import org.junit.Test

/** Tests TrashJob. */
@MediumTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
internal class TrashJobTest : AbstractJobTest<TrashJob>() {
    @get:Rule val setFlags = OverrideFlagsRule()

    @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()

    override fun setUp() {
        // Skip test if the platform SDK is not newer than Android Baklava (SDK 36).
        // The Trash feature under test relies on DocumentsContract APIs introduced in the
        // Android release after Baklava (SDK 36).
        // As DocumentsUI is a Mainline module, it's subject to MTS testing, which runs on
        // older Android base builds to verify backward compatibility. However, this specific
        // Trash feature lacks backward compatibility with platforms at or below Baklava.
        // This assumption prevents failures when the test runs on an older base OS
        // without the necessary APIs.
        assumeTrue(VersionUtils.isGreaterThanB())
        super.setUp()
    }

    @Test
    @RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
    @EnableFlags(Flags.FLAG_ENABLE_TRASH_FLOW_RO)
    fun testTrashSingleFile() {
        val testDir1 = mDocs.createFolder(mSrcRoot, "dir1")
@@ -92,7 +104,6 @@ internal class TrashJobTest : AbstractJobTest<TrashJob>() {
    }

    @Test
    @RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
    @EnableFlags(Flags.FLAG_ENABLE_TRASH_FLOW_RO)
    fun testTrashMultipleFile() {
        val testDir1 = mDocs.createFolder(mSrcRoot, "dir1")
@@ -140,7 +151,6 @@ internal class TrashJobTest : AbstractJobTest<TrashJob>() {
    }

    @Test
    @RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
    @EnableFlags(Flags.FLAG_ENABLE_TRASH_FLOW_RO)
    fun testTrashFolder() {
        val testDir1 = mDocs.createFolder(mSrcRoot, "dir1")
@@ -203,7 +213,6 @@ internal class TrashJobTest : AbstractJobTest<TrashJob>() {
    }

    @Test
    @RequiresFlagsEnabled(FLAG_ENABLE_DOCUMENTS_TRASH_API)
    @EnableFlags(Flags.FLAG_ENABLE_TRASH_FLOW_RO)
    fun testTrashFailedNoFileFound() {
        // create a document in mDestRoot, trashDocument only working for mSrcRoot,
Loading