• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.N;
4 import static android.os.Build.VERSION_CODES.Q;
5 
6 import android.app.Notification;
7 import android.app.NotificationManager;
8 import android.app.Service;
9 import android.content.Context;
10 import android.content.pm.ServiceInfo.ForegroundServiceType;
11 import org.robolectric.RuntimeEnvironment;
12 import org.robolectric.annotation.Implementation;
13 import org.robolectric.annotation.Implements;
14 import org.robolectric.annotation.RealObject;
15 
16 @SuppressWarnings({"UnusedDeclaration"})
17 @Implements(Service.class)
18 public class ShadowService extends ShadowContextWrapper {
19   @RealObject Service realService;
20 
21   private int lastForegroundNotificationId;
22   private Notification lastForegroundNotification;
23   private boolean lastForegroundNotificationAttached = false;
24   private boolean selfStopped = false;
25   private boolean foregroundStopped;
26   private boolean notificationShouldRemoved;
27   private int stopSelfId;
28   private int stopSelfResultId;
29   private int foregroundServiceType;
30 
31   @Implementation
onDestroy()32   protected void onDestroy() {
33     if (lastForegroundNotificationAttached) {
34       lastForegroundNotificationAttached = false;
35       removeForegroundNotification();
36     }
37   }
38 
39   @Implementation
stopSelf()40   protected void stopSelf() {
41     selfStopped = true;
42   }
43 
44   @Implementation
stopSelf(int id)45   protected void stopSelf(int id) {
46     selfStopped = true;
47     stopSelfId = id;
48   }
49 
50   @Implementation
stopSelfResult(int id)51   protected boolean stopSelfResult(int id) {
52     selfStopped = true;
53     stopSelfResultId = id;
54     return true;
55   }
56 
57   @Implementation
startForeground(int id, Notification notification)58   protected void startForeground(int id, Notification notification) {
59     foregroundStopped = false;
60     lastForegroundNotificationId = id;
61     lastForegroundNotification = notification;
62     lastForegroundNotificationAttached = true;
63     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
64     NotificationManager nm =
65         (NotificationManager)
66             RuntimeEnvironment.getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
67     nm.notify(id, notification);
68     this.foregroundServiceType = 0;
69   }
70 
71   @Implementation(minSdk = Q)
startForeground( int id, Notification notification, @ForegroundServiceType int foregroundServiceType)72   protected void startForeground(
73       int id, Notification notification, @ForegroundServiceType int foregroundServiceType) {
74     startForeground(id, notification);
75     this.foregroundServiceType = foregroundServiceType;
76   }
77 
78   @Implementation
stopForeground(boolean removeNotification)79   protected void stopForeground(boolean removeNotification) {
80     foregroundStopped = true;
81     notificationShouldRemoved = removeNotification;
82     if (removeNotification) {
83       removeForegroundNotification();
84     }
85   }
86 
87   @Implementation(minSdk = Q)
88   @ForegroundServiceType
getForegroundServiceType()89   protected int getForegroundServiceType() {
90     return foregroundServiceType;
91   }
92 
93   @Implementation(minSdk = N)
stopForeground(int flags)94   protected void stopForeground(int flags) {
95     if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
96       lastForegroundNotificationAttached = false;
97     }
98     stopForeground((flags & Service.STOP_FOREGROUND_REMOVE) != 0);
99   }
100 
removeForegroundNotification()101   private void removeForegroundNotification() {
102     NotificationManager nm =
103         (NotificationManager)
104             RuntimeEnvironment.getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
105     nm.cancel(lastForegroundNotificationId);
106     lastForegroundNotification = null;
107     lastForegroundNotificationAttached = false;
108   }
109 
getLastForegroundNotificationId()110   public int getLastForegroundNotificationId() {
111     return lastForegroundNotificationId;
112   }
113 
getLastForegroundNotification()114   public Notification getLastForegroundNotification() {
115     return lastForegroundNotification;
116   }
117 
118   /**
119    * Returns whether the last foreground notification is still "attached" to the service, meaning it
120    * will be removed when the service is destroyed.
121    */
isLastForegroundNotificationAttached()122   public boolean isLastForegroundNotificationAttached() {
123     return lastForegroundNotificationAttached;
124   }
125 
126   /**
127    * @return Is this service stopped by self.
128    */
isStoppedBySelf()129   public boolean isStoppedBySelf() {
130     return selfStopped;
131   }
132 
isForegroundStopped()133   public boolean isForegroundStopped() {
134     return foregroundStopped;
135   }
136 
getNotificationShouldRemoved()137   public boolean getNotificationShouldRemoved() {
138     return notificationShouldRemoved;
139   }
140 
141   /**
142    * Returns id passed to {@link #stopSelf(int)} method. Make sure to check result of {@link
143    * #isStoppedBySelf()} first.
144    */
getStopSelfId()145   public int getStopSelfId() {
146     return stopSelfId;
147   }
148 
149   /**
150    * Returns id passed to {@link #stopSelfResult(int)} method. Make sure to check result of {@link
151    * #isStoppedBySelf()} first.
152    */
getStopSelfResultId()153   public int getStopSelfResultId() {
154     return stopSelfResultId;
155   }
156 }
157