• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.providers.media;
17 
18 import android.compat.testing.PlatformCompatChangeRule;
19 import android.content.Context;
20 import android.os.Build;
21 import android.os.Environment;
22 import android.os.Parcel;
23 import android.os.UserHandle;
24 import android.os.storage.StorageManager;
25 import android.os.storage.StorageVolume;
26 import android.platform.test.annotations.RequiresFlagsEnabled;
27 import android.platform.test.flag.junit.CheckFlagsRule;
28 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
29 import android.provider.MediaStore;
30 
31 import androidx.test.ext.junit.runners.AndroidJUnit4;
32 import androidx.test.filters.SdkSuppress;
33 import androidx.test.platform.app.InstrumentationRegistry;
34 
35 import com.android.providers.media.flags.Flags;
36 
37 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
38 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
39 
40 import junit.framework.Assert;
41 
42 import org.junit.Before;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.rules.TestRule;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 import org.mockito.Mockito;
49 import org.mockito.MockitoAnnotations;
50 
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Set;
54 
55 @RunWith(AndroidJUnit4.class)
56 @RequiresFlagsEnabled({Flags.FLAG_EXCLUDE_UNRELIABLE_VOLUMES})
57 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
58 public class GetExternalVolumesBehaviorModificationTest {
59     @Rule
60     public TestRule compatChangeRule = new PlatformCompatChangeRule();
61 
62     @Rule
63     public final CheckFlagsRule mCheckFlagsRule =
64             DeviceFlagsValueProvider.createCheckFlagsRule();
65 
66     @Mock
67     private Context mContext;
68 
69     private static final String RELIABLE_STORAGE = "reliable";
70     private static final String UNRELIABLE_STORAGE = "unreliable";
71 
72     @Before
setup()73     public void setup() {
74         MockitoAnnotations.initMocks(this);
75 
76         // create a testing storage volume which behaves as a reliable storage and hence have a
77         // directory starting with storage/. Naming this volume as reliable.
78         Parcel parcel = Parcel.obtain();
79         parcel.writeString8("1"); // id
80         parcel.writeString8("Storage/emulated/testDir"); // path
81         parcel.writeString8("Storage/emulated/testDir"); // internalPath
82         parcel.writeString8(""); // description
83         parcel.writeInt(0); // removable (boolean)
84         parcel.writeInt(1); // primary (boolean)
85         parcel.writeInt(0); // emulated (boolean)
86         parcel.writeInt(0); // allowMassStorage (boolean)
87         parcel.writeInt(0); // allowFullBackup (boolean)
88         parcel.writeLong(1000); // maxFileSize
89         parcel.writeParcelable(UserHandle.CURRENT, 0); // owner (UserHandle)
90         parcel.writeInt(0); // uuid
91         parcel.writeString8(RELIABLE_STORAGE); // name
92         parcel.writeString8(Environment.MEDIA_MOUNTED); // state
93 
94         parcel.setDataPosition(0);
95 
96         StorageVolume reliableStorage = StorageVolume.CREATOR.createFromParcel(parcel);
97 
98         // create a testing storage volume which behaves as a unreliable storage and hence have a
99         // directory starting with mnt/. Naming this volume as unreliable.
100         Parcel parcel2 = Parcel.obtain();
101         parcel2.writeString8("2"); // id
102         parcel2.writeString8("mnt/testDir"); // path
103         parcel2.writeString8("mnt/testDir"); // internalPath
104         parcel2.writeString8(""); // description
105         parcel2.writeInt(0); // removable (boolean)
106         parcel2.writeInt(1); // primary (boolean)
107         parcel2.writeInt(0); // emulated (boolean)
108         parcel2.writeInt(0); // allowMassStorage (boolean)
109         parcel2.writeInt(0); // allowFullBackup (boolean)
110         parcel2.writeLong(1000); // maxFileSize
111         parcel2.writeParcelable(UserHandle.CURRENT, 0); // owner (UserHandle)
112         parcel2.writeInt(0); // uuid
113         parcel2.writeString8(UNRELIABLE_STORAGE); // name
114         parcel2.writeString8(Environment.MEDIA_MOUNTED); // state
115 
116         parcel2.setDataPosition(0);
117 
118         StorageVolume unreliableStorage = StorageVolume.CREATOR.createFromParcel(parcel2);
119 
120         // Creating a mock storage manager which on being queried for storage volumes return the
121         // list of both reliable and unreliable storage.
122         StorageManager mockedStorageManager = Mockito.mock(StorageManager.class);
123         Mockito.when(mockedStorageManager.getStorageVolumes()).thenReturn(new ArrayList<>(
124                 Arrays.asList(reliableStorage, unreliableStorage)));
125 
126         // Creating a mock for context so that it returns the mocked storage manager.
127         mContext = Mockito.mock(Context.class);
128         Mockito.when(mContext.getSystemServiceName(StorageManager.class)).thenReturn(
129                 Context.STORAGE_SERVICE);
130         Mockito.when(mContext.getApplicationInfo()).thenReturn(
131                 InstrumentationRegistry.getInstrumentation().getContext().getApplicationInfo());
132         Mockito.when(mContext.getSystemService(StorageManager.class)).thenReturn(
133                 mockedStorageManager);
134     }
135 
136     /**
137      * This test verifies the behaviour of MediaStore.getExternalVolumeNames() before enabling the
138      * EXCLUDE_UNRELIABLE_STORAGE_VOLUMES appcompat flag.
139      */
140     @Test
141     @DisableCompatChanges({MediaProvider.EXCLUDE_UNRELIABLE_STORAGE_VOLUMES})
test_getExternalVolumes_returnsAllVolumes()142     public void test_getExternalVolumes_returnsAllVolumes() {
143         Set<String> result = MediaStore.getExternalVolumeNames(mContext);
144 
145         // Verify result is not null and both unreliable and reliable storage is returned.
146         Assert.assertNotNull(result);
147         Assert.assertEquals(2, result.size());
148         Assert.assertTrue(result.contains(RELIABLE_STORAGE));
149         Assert.assertTrue(result.contains(UNRELIABLE_STORAGE));
150     }
151 
152     /**
153      * This test verifies the behaviour of MediaStore.getExternalVolumeNames() before enabling the
154      * EXCLUDE_UNRELIABLE_STORAGE_VOLUMES appcompat flag.
155      */
156     @Test
157     @EnableCompatChanges({MediaProvider.EXCLUDE_UNRELIABLE_STORAGE_VOLUMES})
test_getExternalVolumes_returnsFilteredVolumes()158     public void test_getExternalVolumes_returnsFilteredVolumes() {
159         Set<String> result = MediaStore.getExternalVolumeNames(mContext);
160 
161         // Verify result is not null and only reliable storage is returned.
162         Assert.assertNotNull(result);
163         Assert.assertEquals(1, result.size());
164         Assert.assertTrue(result.contains(RELIABLE_STORAGE));
165         Assert.assertFalse(result.contains(UNRELIABLE_STORAGE));
166     }
167 }
168 
169