aboutsummaryrefslogtreecommitdiff
path: root/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
blob: 929c36aef9a4894c5e078494a3f2de4998bf1c72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package org.robolectric.shadows;

import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.TIRAMISU;
import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;

import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import com.google.common.base.Preconditions;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;

/**
 * Fake implementation of {@link android.os.storage.StorageManager}
 */
@Implements(StorageManager.class)
public class ShadowStorageManager {

  private static boolean isFileEncryptionSupported = true;
  private final List<StorageVolume> storageVolumeList = new ArrayList<>();

  @Implementation(minSdk = M)
  protected static StorageVolume[] getVolumeList(int userId, int flags) {
    return new StorageVolume[0];
  }

  /**
   * Gets the volume list from {@link #getVolumeList(int, int)}
   *
   * @return volume list
   */
  @Implementation
  public StorageVolume[] getVolumeList() {
    return getVolumeList(0, 0);
  }

  /**
   * Adds a {@link StorageVolume} to the list returned by {@link #getStorageVolumes()}.
   *
   * @param StorageVolume to add to list
   */
  public void addStorageVolume(StorageVolume storageVolume) {
    Preconditions.checkNotNull(storageVolume);
    storageVolumeList.add(storageVolume);
  }

  /**
   * Returns the storage volumes configured via {@link #addStorageVolume()}.
   *
   * @return StorageVolume list
   */
  @Implementation(minSdk = N)
  protected List<StorageVolume> getStorageVolumes() {
    return storageVolumeList;
  }

  /** Clears the storageVolumeList. */
  public void resetStorageVolumeList() {
    storageVolumeList.clear();
  }

  /**
   * Checks whether File belongs to any {@link StorageVolume} in the list returned by {@link
   * #getStorageVolumes()}.
   *
   * @param File to check
   * @return StorageVolume for the file
   */
  @Implementation(minSdk = N)
  public StorageVolume getStorageVolume(File file) {
    for (StorageVolume volume : storageVolumeList) {
      File volumeFile = volume.getPathFile();
      if (file.getAbsolutePath().startsWith(volumeFile.getAbsolutePath())) {
        return volume;
      }
    }
    return null;
  }

  // Use maxSdk=T for this method, since starting in U, this method in StorageManager is deprecated
  // and is no longer called by the Android framework. It's planned to be removed entirely in V.
  @HiddenApi
  @Implementation(minSdk = N, maxSdk = TIRAMISU)
  protected static boolean isFileEncryptedNativeOrEmulated() {
    return isFileEncryptionSupported;
  }

  /**
   * Setter for {@link #isFileEncryptedNativeOrEmulated()}
   *
   * @param isSupported a boolean value to set file encrypted native or not
   */
  public void setFileEncryptedNativeOrEmulated(boolean isSupported) {
    isFileEncryptionSupported = isSupported;
  }

  // Use maxSdk=U, as this method is planned to be removed from StorageManager in V.
  @HiddenApi
  @Implementation(minSdk = N, maxSdk = UPSIDE_DOWN_CAKE)
  protected static boolean isUserKeyUnlocked(int userId) {
    ShadowUserManager extract =
        Shadow.extract(RuntimeEnvironment.getApplication().getSystemService(UserManager.class));
    return extract.isUserUnlocked();
  }
}