• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static org.robolectric.shadows.util.DataSource.toDataSource;
4 
5 import android.content.Context;
6 import android.graphics.Bitmap;
7 import android.media.MediaMetadataRetriever;
8 import android.net.Uri;
9 import java.io.FileDescriptor;
10 import java.util.HashMap;
11 import java.util.Map;
12 import org.robolectric.annotation.Implementation;
13 import org.robolectric.annotation.Implements;
14 import org.robolectric.annotation.Resetter;
15 import org.robolectric.shadows.util.DataSource;
16 
17 @Implements(MediaMetadataRetriever.class)
18 public class ShadowMediaMetadataRetriever {
19   private DataSource dataSource;
20   private static final Map<DataSource, Map<Integer, String>> metadata = new HashMap<>();
21   private static final Map<DataSource, Map<Long, Bitmap>> frames = new HashMap<>();
22   private static final Map<DataSource, RuntimeException> exceptions = new HashMap<>();
23 
setDataSource(DataSource dataSource)24   public void setDataSource(DataSource dataSource) {
25     RuntimeException e = exceptions.get(dataSource);
26     if (e != null) {
27       e.fillInStackTrace();
28       throw e;
29     }
30     this.dataSource = dataSource;
31   }
32 
33   @Implementation
setDataSource(String path)34   protected void setDataSource(String path) {
35     setDataSource(toDataSource(path));
36   }
37 
38   @Implementation
setDataSource(Context context, Uri uri)39   protected void setDataSource(Context context, Uri uri) {
40     setDataSource(toDataSource(context, uri));
41   }
42 
43   @Implementation
setDataSource(String uri, Map<String, String> headers)44   protected void setDataSource(String uri, Map<String, String> headers) {
45     setDataSource(toDataSource(uri, headers));
46   }
47 
48   @Implementation
setDataSource(FileDescriptor fd, long offset, long length)49   protected void setDataSource(FileDescriptor fd, long offset, long length) {
50     setDataSource(toDataSource(fd, offset, length));
51   }
52 
53   @Implementation
extractMetadata(int keyCode)54   protected String extractMetadata(int keyCode) {
55     if (metadata.containsKey(dataSource)) {
56       return metadata.get(dataSource).get(keyCode);
57     }
58     return null;
59   }
60 
61   @Implementation
getFrameAtTime(long timeUs, int option)62   protected Bitmap getFrameAtTime(long timeUs, int option) {
63     return (frames.containsKey(dataSource) ?
64             frames.get(dataSource).get(timeUs) : null);
65   }
66 
67   /**
68    * Configures an exception to be thrown when {@link #setDataSource}
69    * is called for the given data source.
70    *
71    * @param ds the data source that will trigger an exception
72    * @param e the exception to trigger, or <tt>null</tt> to
73    * avoid throwing an exception.
74    */
addException(DataSource ds, RuntimeException e)75   public static void addException(DataSource ds, RuntimeException e) {
76     exceptions.put(ds, e);
77   }
78 
addMetadata(DataSource ds, int keyCode, String value)79   public static void addMetadata(DataSource ds, int keyCode, String value) {
80     if (!metadata.containsKey(ds)) {
81       metadata.put(ds, new HashMap<Integer, String>());
82     }
83     metadata.get(ds).put(keyCode, value);
84   }
85 
86   /**
87    * Adds the given keyCode/value pair for the given data source.
88    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(String)} and
89    * then calls {@link #addMetadata(DataSource, int, String)}. This
90    * method is retained mostly for backwards compatibility;
91    * you can call {@link #addMetadata(DataSource, int, String)} directly.
92    *
93    * @param path the path to the data source whose metadata is being set.
94    * @param keyCode the keyCode for the metadata being set, as used by {@link MediaMetadataRetriever#extractMetadata(int)}.
95    * @param value the value for the specified metadata.
96    */
addMetadata(String path, int keyCode, String value)97   public static void addMetadata(String path, int keyCode, String value) {
98     addMetadata(toDataSource(path), keyCode, value);
99   }
100 
addFrame(DataSource ds, long time, Bitmap bitmap)101   public static void addFrame(DataSource ds, long time, Bitmap bitmap) {
102     if (!frames.containsKey(ds)) {
103       frames.put(ds, new HashMap<Long, Bitmap>());
104     }
105     frames.get(ds).put(time, bitmap);
106   }
107 
108   /**
109    * Adds the given bitmap at the given time for the given data source.
110    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(String)} and
111    * then calls {@link #addFrame(DataSource, long, Bitmap)}. This
112    * method is retained mostly for backwards compatibility;
113    * you can call {@link #addFrame(DataSource, long, Bitmap)} directly.
114    *
115    * @param path the path to the data source.
116    * @param time the playback time at which the specified bitmap
117    * should be retrieved.
118    * @param bitmap the bitmap to retrieve.
119    */
addFrame(String path, long time, Bitmap bitmap)120   public static void addFrame(String path, long time, Bitmap bitmap) {
121     addFrame(toDataSource(path), time, bitmap);
122   }
123 
124   /**
125    * Adds the given bitmap at the given time for the given data source.
126    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(Context, Uri)} and
127    * then calls {@link #addFrame(DataSource, long, Bitmap)}. This
128    * method is retained mostly for backwards compatibility;
129    * you can call {@link #addFrame(DataSource, long, Bitmap)} directly.
130    *
131    * @param context the Context object to match on the data source.
132    * @param uri the Uri of the data source.
133    * @param time the playback time at which the specified bitmap
134    * should be retrieved.
135    * @param bitmap the bitmap to retrieve.
136    */
addFrame(Context context, Uri uri, long time, Bitmap bitmap)137   public static void addFrame(Context context, Uri uri, long time, Bitmap bitmap) {
138     addFrame(toDataSource(context, uri), time, bitmap);
139   }
140 
141   /**
142    * Adds the given bitmap at the given time for the given data source.
143    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(String, Map)} and
144    * then calls {@link #addFrame(DataSource, long, Bitmap)}. This
145    * method is retained mostly for backwards compatibility;
146    * you can call {@link #addFrame(DataSource, long, Bitmap)} directly.
147    *
148    * @param uri the Uri of the data source.
149    * @param headers the headers to use when requesting the specified uri.
150    * @param time the playback time at which the specified bitmap
151    * should be retrieved.
152    * @param bitmap the bitmap to retrieve.
153    */
addFrame(String uri, Map<String, String> headers, long time, Bitmap bitmap)154   public static void addFrame(String uri, Map<String, String> headers, long time, Bitmap bitmap) {
155     addFrame(toDataSource(uri, headers), time, bitmap);
156   }
157 
158   /**
159    * Adds the given bitmap at the given time for the given data source.
160    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(FileDescriptor)} and
161    * then calls {@link #addFrame(DataSource, long, Bitmap)}. This
162    * method is retained mostly for backwards compatibility;
163    * you can call {@link #addFrame(DataSource, long, Bitmap)} directly.
164    *
165    * @param fd file descriptor of the data source.
166    * @param time the playback time at which the specified bitmap
167    * should be retrieved.
168    * @param bitmap the bitmap to retrieve.
169    */
addFrame(FileDescriptor fd, long time, Bitmap bitmap)170   public static void addFrame(FileDescriptor fd, long time, Bitmap bitmap) {
171     addFrame(toDataSource(fd), time, bitmap);
172   }
173 
174   /**
175    * Adds the given bitmap at the given time for the given data source.
176    * Uses <tt>path</tt> to call {@link org.robolectric.shadows.util.DataSource#toDataSource(FileDescriptor, long, long)} and
177    * then calls {@link #addFrame(DataSource, long, Bitmap)}. This
178    * method is retained mostly for backwards compatibility;
179    * you can call {@link #addFrame(DataSource, long, Bitmap)} directly.
180    *
181    * @param fd file descriptor of the data source.
182    * @param offset the byte offset within the specified file from which to start reading the data.
183    * @param length the number of bytes to read from the file.
184    * @param time the playback time at which the specified bitmap
185    * should be retrieved.
186    * @param bitmap the bitmap to retrieve.
187    */
addFrame(FileDescriptor fd, long offset, long length, long time, Bitmap bitmap)188   public static void addFrame(FileDescriptor fd, long offset, long length,
189                               long time, Bitmap bitmap) {
190     addFrame(toDataSource(fd, offset, length), time, bitmap);
191   }
192 
193   @Resetter
reset()194   public static void reset() {
195     metadata.clear();
196     frames.clear();
197     exceptions.clear();
198   }
199 }
200