1 /*
2  * Copyright (C) 2021 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 
17 package com.android.settings.deviceinfo;
18 
19 import static org.mockito.Mockito.atLeastOnce;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.never;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.os.storage.DiskInfo;
29 import android.os.storage.StorageManager;
30 import android.os.storage.VolumeInfo;
31 import android.os.storage.VolumeRecord;
32 import android.view.Menu;
33 
34 import androidx.fragment.app.Fragment;
35 import androidx.test.core.app.ApplicationProvider;
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 
38 import com.android.settings.deviceinfo.storage.StorageEntry;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.Answers;
44 import org.mockito.Mock;
45 import org.mockito.MockitoAnnotations;
46 
47 @RunWith(AndroidJUnit4.class)
48 public class VolumeOptionMenuControllerTest {
49 
50     private static final String INTERNAL_VOLUME_ID = "1";
51     private static final String EXTERNAL_VOLUME_ID = "2";
52     private static final String DISK_ID = "3";
53     private static final String VOLUME_RECORD_FSUUID = "volume_record_fsuuid";
54 
55     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
56     private Menu mMenu;
57     @Mock private PackageManager mPackageManager;
58     @Mock private StorageManager mStorageManager;
59     @Mock private VolumeInfo mExternalVolumeInfo;
60     @Mock private VolumeInfo mInternalVolumeInfo;
61 
62     private Context mContext;
63     private VolumeOptionMenuController mController;
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68 
69         mContext = spy(ApplicationProvider.getApplicationContext());
70         when(mContext.getPackageManager()).thenReturn(mPackageManager);
71         when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
72 
73         when(mInternalVolumeInfo.getId()).thenReturn(INTERNAL_VOLUME_ID);
74         when(mInternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
75         when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
76         when(mInternalVolumeInfo.isMountedWritable()).thenReturn(true);
77         when(mExternalVolumeInfo.getId()).thenReturn(EXTERNAL_VOLUME_ID);
78 
79         final StorageEntry selectedStorageEntry = new StorageEntry(mContext, mInternalVolumeInfo);
80         mController = new VolumeOptionMenuController(mContext, mock(Fragment.class),
81                 selectedStorageEntry);
82     }
83 
84     @Test
onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible()85     public void onPrepareOptionsMenu_unSupportedDiskInfo_formatIsVisible() {
86         final StorageEntry unsupportedStorageEntry =
87                 new StorageEntry(new DiskInfo(DISK_ID, 0 /* flags */));
88         mController.setSelectedStorageEntry(unsupportedStorageEntry);
89 
90         mController.onPrepareOptionsMenu(mMenu);
91 
92         verify(mController.mFormat, atLeastOnce()).setVisible(true);
93         verify(mController.mRename, never()).setVisible(true);
94         verify(mController.mMount, never()).setVisible(true);
95         verify(mController.mUnmount, never()).setVisible(true);
96         verify(mController.mFormatAsPortable, never()).setVisible(true);
97         verify(mController.mFormatAsInternal, never()).setVisible(true);
98         verify(mController.mMigrate, never()).setVisible(true);
99         verify(mController.mFree, never()).setVisible(true);
100         verify(mController.mForget, never()).setVisible(true);
101     }
102 
103     @Test
onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible()104     public void onPrepareOptionsMenu_missingVolumeRecord_forgetIsVisible() {
105         final StorageEntry missingStorageEntry =
106                 new StorageEntry(new VolumeRecord(0 /* type */, VOLUME_RECORD_FSUUID));
107         mController.setSelectedStorageEntry(missingStorageEntry);
108 
109         mController.onPrepareOptionsMenu(mMenu);
110 
111         verify(mController.mForget, atLeastOnce()).setVisible(true);
112         verify(mController.mRename, never()).setVisible(true);
113         verify(mController.mMount, never()).setVisible(true);
114         verify(mController.mUnmount, never()).setVisible(true);
115         verify(mController.mFormat, never()).setVisible(true);
116         verify(mController.mFormatAsPortable, never()).setVisible(true);
117         verify(mController.mFormatAsInternal, never()).setVisible(true);
118         verify(mController.mMigrate, never()).setVisible(true);
119         verify(mController.mFree, never()).setVisible(true);
120     }
121 
122     @Test
onPrepareOptionsMenu_unmountedStorage_mountIsVisible()123     public void onPrepareOptionsMenu_unmountedStorage_mountIsVisible() {
124         when(mInternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_UNMOUNTED);
125         mController.setSelectedStorageEntry(new StorageEntry(mContext, mInternalVolumeInfo));
126 
127         mController.onPrepareOptionsMenu(mMenu);
128 
129         verify(mController.mMount, atLeastOnce()).setVisible(true);
130         verify(mController.mRename, never()).setVisible(true);
131         verify(mController.mUnmount, never()).setVisible(true);
132         verify(mController.mFormat, never()).setVisible(true);
133         verify(mController.mFormatAsPortable, never()).setVisible(true);
134         verify(mController.mFormatAsInternal, never()).setVisible(true);
135         verify(mController.mMigrate, never()).setVisible(true);
136         verify(mController.mFree, never()).setVisible(true);
137         verify(mController.mForget, never()).setVisible(true);
138     }
139 
140     @Test
onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible()141     public void onPrepareOptionsMenu_privateNotDefaultInternal_someMenusAreVisible() {
142         mController.onPrepareOptionsMenu(mMenu);
143 
144         verify(mController.mRename, atLeastOnce()).setVisible(true);
145         verify(mController.mUnmount, atLeastOnce()).setVisible(true);
146         verify(mController.mFormatAsPortable, atLeastOnce()).setVisible(true);
147         verify(mController.mMount, never()).setVisible(true);
148         verify(mController.mFormat, never()).setVisible(true);
149         verify(mController.mFormatAsInternal, never()).setVisible(true);
150         verify(mController.mFree, never()).setVisible(true);
151         verify(mController.mForget, never()).setVisible(true);
152     }
153 
154     @Test
onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible()155     public void onPrepareOptionsMenu_privateDefaultInternal_mostMenusAreNotVisible() {
156         when(mInternalVolumeInfo.getId()).thenReturn(VolumeInfo.ID_PRIVATE_INTERNAL);
157         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
158 
159         mController.onPrepareOptionsMenu(mMenu);
160 
161         verify(mController.mRename, never()).setVisible(true);
162         verify(mController.mUnmount, never()).setVisible(true);
163         verify(mController.mFormatAsPortable, never()).setVisible(true);
164         verify(mController.mMount, never()).setVisible(true);
165         verify(mController.mFormat, never()).setVisible(true);
166         verify(mController.mFormatAsInternal, never()).setVisible(true);
167         verify(mController.mFree, never()).setVisible(true);
168         verify(mController.mForget, never()).setVisible(true);
169     }
170 
171     @Test
onPrepareOptionsMenu_publicStorage_someMenusArcVisible()172     public void onPrepareOptionsMenu_publicStorage_someMenusArcVisible() {
173         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PUBLIC);
174         when(mExternalVolumeInfo.getState()).thenReturn(VolumeInfo.STATE_MOUNTED);
175         when(mExternalVolumeInfo.getDiskId()).thenReturn(DISK_ID);
176         final DiskInfo externalDiskInfo = mock(DiskInfo.class);
177         when(mStorageManager.findDiskById(DISK_ID)).thenReturn(externalDiskInfo);
178         mController.setSelectedStorageEntry(new StorageEntry(mContext, mExternalVolumeInfo));
179 
180         mController.onPrepareOptionsMenu(mMenu);
181 
182         verify(mController.mRename, atLeastOnce()).setVisible(true);
183         verify(mController.mUnmount, atLeastOnce()).setVisible(true);
184         verify(mController.mFormat, atLeastOnce()).setVisible(true);
185         verify(mController.mMount, never()).setVisible(true);
186         verify(mController.mFormatAsPortable, never()).setVisible(true);
187         verify(mController.mFormatAsInternal, never()).setVisible(true);
188         verify(mController.mFree, never()).setVisible(true);
189         verify(mController.mForget, never()).setVisible(true);
190     }
191 
192     @Test
onPrepareOptionsMenu_noExternalStorage_migrateNotVisible()193     public void onPrepareOptionsMenu_noExternalStorage_migrateNotVisible() {
194         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mInternalVolumeInfo);
195 
196         mController.onPrepareOptionsMenu(mMenu);
197 
198         verify(mController.mMigrate, atLeastOnce()).setVisible(false);
199         verify(mController.mMigrate, never()).setVisible(true);
200     }
201 
202     @Test
onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible()203     public void onPrepareOptionsMenu_externalPrimaryStorageAvailable_migrateIsVisible() {
204         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
205         when(mExternalVolumeInfo.isMountedWritable()).thenReturn(true);
206         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
207 
208         mController.onPrepareOptionsMenu(mMenu);
209 
210         verify(mController.mMigrate, atLeastOnce()).setVisible(true);
211     }
212 
213     @Test
onPrepareOptionsMenu_externalUnmounted_migrateIsVisible()214     public void onPrepareOptionsMenu_externalUnmounted_migrateIsVisible() {
215         when(mExternalVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
216         when(mExternalVolumeInfo.isMountedWritable()).thenReturn(false);
217         when(mPackageManager.getPrimaryStorageCurrentVolume()).thenReturn(mExternalVolumeInfo);
218 
219         mController.onPrepareOptionsMenu(mMenu);
220 
221         verify(mController.mMigrate, atLeastOnce()).setVisible(false);
222         verify(mController.mMigrate, never()).setVisible(true);
223     }
224 }
225