• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import android.os.Build.VERSION_CODES;
4 import android.util.EventLog;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.List;
8 import org.robolectric.annotation.Implementation;
9 import org.robolectric.annotation.Implements;
10 import org.robolectric.annotation.Resetter;
11 import org.robolectric.shadow.api.Shadow;
12 
13 @Implements(EventLog.class)
14 public class ShadowEventLog {
15 
16   /**
17    * Constant written to the log if the parameter is null.
18    *
19    * <p>This matches how the real android code handles nulls.
20    */
21   static final String NULL_PLACE_HOLDER = "NULL";
22 
23   @Implements(EventLog.Event.class)
24   public static class ShadowEvent {
25 
26     private Object data;
27     private int tag;
28     private int processId;
29     private long timeNanos;
30 
31     @Implementation
getData()32     protected Object getData() {
33       return data;
34     }
35 
36     @Implementation
getTag()37     protected int getTag() {
38       return tag;
39     }
40 
41     @Implementation
getProcessId()42     protected int getProcessId() {
43       return processId;
44     }
45 
46     @Implementation
getTimeNanos()47     protected long getTimeNanos() {
48       return timeNanos;
49     }
50   }
51 
52   private static final List<EventLog.Event> events = new ArrayList<>();
53 
54   /** Class to build {@link EventLog.Event} */
55   public static class EventBuilder {
56 
57     private final Object data;
58     private final int tag;
59     private int processId = ShadowProcess.myPid();
60     private long timeNanos = System.nanoTime();
61 
EventBuilder(int tag, Object data)62     public EventBuilder(int tag, Object data) {
63       this.tag = tag;
64       this.data = data;
65     }
66 
setProcessId(int processId)67     public EventBuilder setProcessId(int processId) {
68       this.processId = processId;
69       return this;
70     }
71 
setTimeNanos(long timeNanos)72     public EventBuilder setTimeNanos(long timeNanos) {
73       this.timeNanos = timeNanos;
74       return this;
75     }
76 
build()77     public EventLog.Event build() {
78       EventLog.Event event = Shadow.newInstanceOf(EventLog.Event.class);
79       ShadowEvent shadowEvent = Shadow.extract(event);
80       shadowEvent.data = data;
81       shadowEvent.tag = tag;
82       shadowEvent.processId = processId;
83       shadowEvent.timeNanos = timeNanos;
84       return event;
85     }
86   }
87 
88   /** Add event to {@link EventLog}. */
addEvent(EventLog.Event event)89   public static void addEvent(EventLog.Event event) {
90     events.add(event);
91   }
92 
93   @Resetter
clearAll()94   public static void clearAll() {
95     events.clear();
96   }
97 
98   /** Writes an event log message, returning an approximation of the bytes written. */
99   @Implementation
writeEvent(int tag, String str)100   protected static int writeEvent(int tag, String str) {
101     if (str == null) {
102       str = NULL_PLACE_HOLDER;
103     }
104     addEvent(new EventBuilder(tag, str).build());
105     return Integer.BYTES + str.length();
106   }
107 
108   /** Writes an event log message, returning an approximation of the bytes written. */
109   @Implementation
writeEvent(int tag, Object... list)110   protected static int writeEvent(int tag, Object... list) {
111     if (list == null) {
112       // This matches how the real android code handles nulls
113       return writeEvent(tag, (String) null);
114     }
115     addEvent(new EventBuilder(tag, list).build());
116     return Integer.BYTES + list.length * Integer.BYTES;
117   }
118 
119   /** Writes an event log message, returning an approximation of the bytes written. */
120   @Implementation
writeEvent(int tag, int value)121   protected static int writeEvent(int tag, int value) {
122     addEvent(new EventBuilder(tag, value).build());
123     return Integer.BYTES + Integer.BYTES;
124   }
125 
126   /** Writes an event log message, returning an approximation of the bytes written. */
127   @Implementation(minSdk = VERSION_CODES.M)
writeEvent(int tag, float value)128   protected static int writeEvent(int tag, float value) {
129     addEvent(new EventBuilder(tag, value).build());
130     return Integer.BYTES + Float.BYTES;
131   }
132 
133   /** Writes an event log message, returning an approximation of the bytes written. */
134   @Implementation
writeEvent(int tag, long value)135   protected static int writeEvent(int tag, long value) {
136     addEvent(new EventBuilder(tag, value).build());
137     return Integer.BYTES + Long.BYTES;
138   }
139 
140   @Implementation
readEvents(int[] tags, Collection<EventLog.Event> output)141   protected static void readEvents(int[] tags, Collection<EventLog.Event> output) {
142     for (EventLog.Event event : events) {
143       for (int tag : tags) {
144         if (tag == event.getTag()) {
145           output.add(event);
146           break;
147         }
148       }
149     }
150   }
151 }
152