• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import android.annotation.NonNull;
4 import android.annotation.Nullable;
5 import android.os.Build.VERSION_CODES;
6 import android.safetycenter.SafetyCenterManager;
7 import android.safetycenter.SafetyEvent;
8 import android.safetycenter.SafetySourceData;
9 import android.safetycenter.SafetySourceErrorDetails;
10 import com.google.errorprone.annotations.concurrent.GuardedBy;
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.Map;
14 import java.util.Set;
15 import org.robolectric.annotation.Implementation;
16 import org.robolectric.annotation.Implements;
17 
18 /** Shadow for {@link SafetyCenterManager}. */
19 @Implements(
20     value = SafetyCenterManager.class,
21     minSdk = VERSION_CODES.TIRAMISU,
22     isInAndroidSdk = false)
23 public class ShadowSafetyCenterManager {
24 
25   private final Object lock = new Object();
26 
27   @GuardedBy("lock")
28   private final Map<String, SafetySourceData> dataById = new HashMap<>();
29 
30   @GuardedBy("lock")
31   private final Map<String, SafetyEvent> eventsById = new HashMap<>();
32 
33   @GuardedBy("lock")
34   private final Map<String, SafetySourceErrorDetails> errorsById = new HashMap<>();
35 
36   @GuardedBy("lock")
37   private final Set<String> throwForId = new HashSet<>();
38 
39   @GuardedBy("lock")
40   private boolean enabled = false;
41 
42   @Implementation
isSafetyCenterEnabled()43   protected boolean isSafetyCenterEnabled() {
44     synchronized (lock) {
45       return enabled;
46     }
47   }
48 
49   @Implementation
setSafetySourceData( @onNull String safetySourceId, @Nullable SafetySourceData safetySourceData, @NonNull SafetyEvent safetyEvent)50   protected void setSafetySourceData(
51       @NonNull String safetySourceId,
52       @Nullable SafetySourceData safetySourceData,
53       @NonNull SafetyEvent safetyEvent) {
54     synchronized (lock) {
55       if (!isSafetyCenterEnabled()) {
56         return;
57       }
58       maybeThrowForId(safetySourceId);
59       dataById.put(safetySourceId, safetySourceData);
60       eventsById.put(safetySourceId, safetyEvent);
61     }
62   }
63 
64   @Implementation
getSafetySourceData(@onNull String safetySourceId)65   protected SafetySourceData getSafetySourceData(@NonNull String safetySourceId) {
66     synchronized (lock) {
67       if (!isSafetyCenterEnabled()) {
68         return null;
69       }
70       maybeThrowForId(safetySourceId);
71       return dataById.get(safetySourceId);
72     }
73   }
74 
75   @Implementation
reportSafetySourceError( @onNull String safetySourceId, @NonNull SafetySourceErrorDetails safetySourceErrorDetails)76   protected void reportSafetySourceError(
77       @NonNull String safetySourceId, @NonNull SafetySourceErrorDetails safetySourceErrorDetails) {
78     synchronized (lock) {
79       if (!isSafetyCenterEnabled()) {
80         return;
81       }
82       maybeThrowForId(safetySourceId);
83       errorsById.put(safetySourceId, safetySourceErrorDetails);
84     }
85   }
86 
87   @GuardedBy("lock")
maybeThrowForId(String safetySourceId)88   private void maybeThrowForId(String safetySourceId) {
89     if (throwForId.contains(safetySourceId)) {
90       throw new IllegalArgumentException(String.format("%s is invalid", safetySourceId));
91     }
92   }
93 
94   /**
95    * Sets the return value for {@link #isSafetyCenterEnabled} which also enables the {@link
96    * #setSafetySourceData} and {@link #getSafetySourceData} methods.
97    */
setSafetyCenterEnabled(boolean enabled)98   public void setSafetyCenterEnabled(boolean enabled) {
99     synchronized (lock) {
100       this.enabled = enabled;
101     }
102   }
103 
104   /**
105    * Makes the APIs throw an {@link IllegalArgumentException} for the given {@code safetySourceId}.
106    */
throwOnSafetySourceId(@onNull String safetySourceId)107   public void throwOnSafetySourceId(@NonNull String safetySourceId) {
108     synchronized (lock) {
109       throwForId.add(safetySourceId);
110     }
111   }
112 
113   /**
114    * Returns the {@link SafetyEvent} that was given to {@link SafetyCenterManager} the last time
115    * {@link #setSafetySourceData} was called with this {@code safetySourceId}.
116    */
getLastSafetyEvent(@onNull String safetySourceId)117   public SafetyEvent getLastSafetyEvent(@NonNull String safetySourceId) {
118     synchronized (lock) {
119       return eventsById.get(safetySourceId);
120     }
121   }
122 
123   /**
124    * Returns the {@link SafetySourceErrorDetails} that was given to {@link SafetyCenterManager} the
125    * last time {@link #reportSafetySourceError} was called with this {@code safetySourceId}.
126    */
getLastSafetySourceError(@onNull String safetySourceId)127   public SafetySourceErrorDetails getLastSafetySourceError(@NonNull String safetySourceId) {
128     synchronized (lock) {
129       return errorsById.get(safetySourceId);
130     }
131   }
132 }
133