blob: baa7a502688eb73306afed9a98c2a7781cef4f76 [file] [log] [blame]
Eric Laurent2035ac82015-03-05 15:18:44 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.hardware.radio;
17
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -070018import android.annotation.NonNull;
Eric Laurent2035ac82015-03-05 15:18:44 -080019import android.annotation.SystemApi;
Eric Laurent2035ac82015-03-05 15:18:44 -080020import android.graphics.Bitmap;
21import android.graphics.BitmapFactory;
Eric Laurent2035ac82015-03-05 15:18:44 -080022import android.os.Bundle;
23import android.os.Parcel;
24import android.os.Parcelable;
Eric Laurent2035ac82015-03-05 15:18:44 -080025import android.util.ArrayMap;
26import android.util.Log;
27import android.util.SparseArray;
28
Eric Laurent2035ac82015-03-05 15:18:44 -080029import java.util.Set;
30
31/**
32 * Contains meta data about a radio program such as station name, song title, artist etc...
33 * @hide
34 */
35@SystemApi
36public final class RadioMetadata implements Parcelable {
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070037 private static final String TAG = "BroadcastRadio.metadata";
Eric Laurent2035ac82015-03-05 15:18:44 -080038
39 /**
40 * The RDS Program Information.
41 */
42 public static final String METADATA_KEY_RDS_PI = "android.hardware.radio.metadata.RDS_PI";
43
44 /**
45 * The RDS Program Service.
46 */
47 public static final String METADATA_KEY_RDS_PS = "android.hardware.radio.metadata.RDS_PS";
48
49 /**
50 * The RDS PTY.
51 */
52 public static final String METADATA_KEY_RDS_PTY = "android.hardware.radio.metadata.RDS_PTY";
53
54 /**
55 * The RBDS PTY.
56 */
57 public static final String METADATA_KEY_RBDS_PTY = "android.hardware.radio.metadata.RBDS_PTY";
58
59 /**
60 * The RBDS Radio Text.
61 */
62 public static final String METADATA_KEY_RDS_RT = "android.hardware.radio.metadata.RDS_RT";
63
64 /**
65 * The song title.
66 */
67 public static final String METADATA_KEY_TITLE = "android.hardware.radio.metadata.TITLE";
68
69 /**
70 * The artist name.
71 */
72 public static final String METADATA_KEY_ARTIST = "android.hardware.radio.metadata.ARTIST";
73
74 /**
75 * The album name.
76 */
77 public static final String METADATA_KEY_ALBUM = "android.hardware.radio.metadata.ALBUM";
78
79 /**
80 * The music genre.
81 */
82 public static final String METADATA_KEY_GENRE = "android.hardware.radio.metadata.GENRE";
83
84 /**
85 * The radio station icon {@link Bitmap}.
86 */
87 public static final String METADATA_KEY_ICON = "android.hardware.radio.metadata.ICON";
88
89 /**
90 * The artwork for the song/album {@link Bitmap}.
91 */
92 public static final String METADATA_KEY_ART = "android.hardware.radio.metadata.ART";
93
Sanket Agarwal7058e4c2015-10-08 14:14:20 -070094 /**
95 * The clock.
96 */
97 public static final String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK";
98
Tomasz Wasilczykfc677392018-02-23 09:53:35 -080099 /**
100 * Technology-independent program name (station name).
101 */
102 public static final String METADATA_KEY_PROGRAM_NAME =
103 "android.hardware.radio.metadata.PROGRAM_NAME";
104
105 /**
106 * DAB ensemble name.
107 */
108 public static final String METADATA_KEY_DAB_ENSEMBLE_NAME =
109 "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME";
110
111 /**
112 * DAB ensemble name - short version (up to 8 characters).
113 */
114 public static final String METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT =
115 "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME_SHORT";
116
117 /**
118 * DAB service name.
119 */
120 public static final String METADATA_KEY_DAB_SERVICE_NAME =
121 "android.hardware.radio.metadata.DAB_SERVICE_NAME";
122
123 /**
124 * DAB service name - short version (up to 8 characters).
125 */
126 public static final String METADATA_KEY_DAB_SERVICE_NAME_SHORT =
127 "android.hardware.radio.metadata.DAB_SERVICE_NAME_SHORT";
128
129 /**
130 * DAB component name.
131 */
132 public static final String METADATA_KEY_DAB_COMPONENT_NAME =
133 "android.hardware.radio.metadata.DAB_COMPONENT_NAME";
134
135 /**
136 * DAB component name.
137 */
138 public static final String METADATA_KEY_DAB_COMPONENT_NAME_SHORT =
139 "android.hardware.radio.metadata.DAB_COMPONENT_NAME_SHORT";
140
Eric Laurent2035ac82015-03-05 15:18:44 -0800141
142 private static final int METADATA_TYPE_INVALID = -1;
143 private static final int METADATA_TYPE_INT = 0;
144 private static final int METADATA_TYPE_TEXT = 1;
145 private static final int METADATA_TYPE_BITMAP = 2;
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700146 private static final int METADATA_TYPE_CLOCK = 3;
Eric Laurent2035ac82015-03-05 15:18:44 -0800147
148 private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
149
150 static {
151 METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
Tomasz Wasilczykd6e269a2017-06-29 17:52:54 -0700152 METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PI, METADATA_TYPE_INT);
Eric Laurent2035ac82015-03-05 15:18:44 -0800153 METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PS, METADATA_TYPE_TEXT);
154 METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_PTY, METADATA_TYPE_INT);
155 METADATA_KEYS_TYPE.put(METADATA_KEY_RBDS_PTY, METADATA_TYPE_INT);
156 METADATA_KEYS_TYPE.put(METADATA_KEY_RDS_RT, METADATA_TYPE_TEXT);
157 METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT);
158 METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT);
159 METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT);
160 METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
161 METADATA_KEYS_TYPE.put(METADATA_KEY_ICON, METADATA_TYPE_BITMAP);
162 METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700163 METADATA_KEYS_TYPE.put(METADATA_KEY_CLOCK, METADATA_TYPE_CLOCK);
Tomasz Wasilczykfc677392018-02-23 09:53:35 -0800164 METADATA_KEYS_TYPE.put(METADATA_KEY_PROGRAM_NAME, METADATA_TYPE_TEXT);
165 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME, METADATA_TYPE_TEXT);
166 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT, METADATA_TYPE_TEXT);
167 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME, METADATA_TYPE_TEXT);
168 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME_SHORT, METADATA_TYPE_TEXT);
169 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME, METADATA_TYPE_TEXT);
170 METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME_SHORT, METADATA_TYPE_TEXT);
Eric Laurent2035ac82015-03-05 15:18:44 -0800171 }
172
173 // keep in sync with: system/media/radio/include/system/radio_metadata.h
174 private static final int NATIVE_KEY_INVALID = -1;
175 private static final int NATIVE_KEY_RDS_PI = 0;
176 private static final int NATIVE_KEY_RDS_PS = 1;
177 private static final int NATIVE_KEY_RDS_PTY = 2;
178 private static final int NATIVE_KEY_RBDS_PTY = 3;
179 private static final int NATIVE_KEY_RDS_RT = 4;
180 private static final int NATIVE_KEY_TITLE = 5;
181 private static final int NATIVE_KEY_ARTIST = 6;
182 private static final int NATIVE_KEY_ALBUM = 7;
183 private static final int NATIVE_KEY_GENRE = 8;
184 private static final int NATIVE_KEY_ICON = 9;
185 private static final int NATIVE_KEY_ART = 10;
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700186 private static final int NATIVE_KEY_CLOCK = 11;
Eric Laurent2035ac82015-03-05 15:18:44 -0800187
188 private static final SparseArray<String> NATIVE_KEY_MAPPING;
189
190 static {
191 NATIVE_KEY_MAPPING = new SparseArray<String>();
192 NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PI, METADATA_KEY_RDS_PI);
193 NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PS, METADATA_KEY_RDS_PS);
194 NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_PTY, METADATA_KEY_RDS_PTY);
195 NATIVE_KEY_MAPPING.put(NATIVE_KEY_RBDS_PTY, METADATA_KEY_RBDS_PTY);
196 NATIVE_KEY_MAPPING.put(NATIVE_KEY_RDS_RT, METADATA_KEY_RDS_RT);
197 NATIVE_KEY_MAPPING.put(NATIVE_KEY_TITLE, METADATA_KEY_TITLE);
198 NATIVE_KEY_MAPPING.put(NATIVE_KEY_ARTIST, METADATA_KEY_ARTIST);
199 NATIVE_KEY_MAPPING.put(NATIVE_KEY_ALBUM, METADATA_KEY_ALBUM);
200 NATIVE_KEY_MAPPING.put(NATIVE_KEY_GENRE, METADATA_KEY_GENRE);
201 NATIVE_KEY_MAPPING.put(NATIVE_KEY_ICON, METADATA_KEY_ICON);
202 NATIVE_KEY_MAPPING.put(NATIVE_KEY_ART, METADATA_KEY_ART);
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700203 NATIVE_KEY_MAPPING.put(NATIVE_KEY_CLOCK, METADATA_KEY_CLOCK);
204 }
205
206 /**
207 * Provides a Clock that can be used to describe time as provided by the Radio.
208 *
209 * The clock is defined by the seconds since epoch at the UTC + 0 timezone
210 * and timezone offset from UTC + 0 represented in number of minutes.
211 *
212 * @hide
213 */
214 @SystemApi
215 public static final class Clock implements Parcelable {
216 private final long mUtcEpochSeconds;
217 private final int mTimezoneOffsetMinutes;
218
219 public int describeContents() {
220 return 0;
221 }
222
223 public void writeToParcel(Parcel out, int flags) {
224 out.writeLong(mUtcEpochSeconds);
225 out.writeInt(mTimezoneOffsetMinutes);
226 }
227
228 public static final Parcelable.Creator<Clock> CREATOR
229 = new Parcelable.Creator<Clock>() {
230 public Clock createFromParcel(Parcel in) {
231 return new Clock(in);
232 }
233
234 public Clock[] newArray(int size) {
235 return new Clock[size];
236 }
237 };
238
239 public Clock(long utcEpochSeconds, int timezoneOffsetMinutes) {
240 mUtcEpochSeconds = utcEpochSeconds;
241 mTimezoneOffsetMinutes = timezoneOffsetMinutes;
242 }
243
244 private Clock(Parcel in) {
245 mUtcEpochSeconds = in.readLong();
246 mTimezoneOffsetMinutes = in.readInt();
247 }
248
249 public long getUtcEpochSeconds() {
250 return mUtcEpochSeconds;
251 }
252
253 public int getTimezoneOffsetMinutes() {
254 return mTimezoneOffsetMinutes;
255 }
Eric Laurent2035ac82015-03-05 15:18:44 -0800256 }
257
258 private final Bundle mBundle;
259
260 RadioMetadata() {
261 mBundle = new Bundle();
262 }
263
264 private RadioMetadata(Bundle bundle) {
265 mBundle = new Bundle(bundle);
266 }
267
268 private RadioMetadata(Parcel in) {
269 mBundle = in.readBundle();
270 }
271
Tomasz Wasilczykdd2e6c52018-04-30 10:31:50 -0700272 @Override
273 public String toString() {
274 StringBuilder sb = new StringBuilder("RadioMetadata[");
275
276 final String removePrefix = "android.hardware.radio.metadata";
277
278 boolean first = true;
279 for (String key : mBundle.keySet()) {
280 if (first) first = false;
281 else sb.append(", ");
282
283 String keyDisp = key;
284 if (key.startsWith(removePrefix)) keyDisp = key.substring(removePrefix.length());
285
286 sb.append(keyDisp);
287 sb.append('=');
288 sb.append(mBundle.get(key));
289 }
290
291 sb.append("]");
292 return sb.toString();
293 }
294
Eric Laurent2035ac82015-03-05 15:18:44 -0800295 /**
296 * Returns {@code true} if the given key is contained in the meta data
297 *
298 * @param key a String key
299 * @return {@code true} if the key exists in this meta data, {@code false} otherwise
300 */
301 public boolean containsKey(String key) {
302 return mBundle.containsKey(key);
303 }
304
305 /**
306 * Returns the text value associated with the given key as a String, or null
307 * if the key is not found in the meta data.
308 *
309 * @param key The key the value is stored under
310 * @return a String value, or null
311 */
312 public String getString(String key) {
313 return mBundle.getString(key);
314 }
315
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700316 private static void putInt(Bundle bundle, String key, int value) {
317 int type = METADATA_KEYS_TYPE.getOrDefault(key, METADATA_TYPE_INVALID);
318 if (type != METADATA_TYPE_INT && type != METADATA_TYPE_BITMAP) {
319 throw new IllegalArgumentException("The " + key + " key cannot be used to put an int");
320 }
321 bundle.putInt(key, value);
322 }
323
Eric Laurent2035ac82015-03-05 15:18:44 -0800324 /**
325 * Returns the value associated with the given key,
326 * or 0 if the key is not found in the meta data.
327 *
328 * @param key The key the value is stored under
329 * @return an int value
330 */
331 public int getInt(String key) {
332 return mBundle.getInt(key, 0);
333 }
334
335 /**
336 * Returns a {@link Bitmap} for the given key or null if the key is not found in the meta data.
337 *
338 * @param key The key the value is stored under
339 * @return a {@link Bitmap} or null
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700340 * @deprecated Use getBitmapId(String) instead
Eric Laurent2035ac82015-03-05 15:18:44 -0800341 */
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700342 @Deprecated
Eric Laurent2035ac82015-03-05 15:18:44 -0800343 public Bitmap getBitmap(String key) {
344 Bitmap bmp = null;
345 try {
346 bmp = mBundle.getParcelable(key);
347 } catch (Exception e) {
348 // ignore, value was not a bitmap
349 Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
350 }
351 return bmp;
352 }
353
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700354 /**
355 * Retrieves an identifier for a bitmap.
356 *
357 * The format of an identifier is opaque to the application,
358 * with a special case of value 0 being invalid.
359 * An identifier for a given image-tuner pair is unique, so an application
360 * may cache images and determine if there is a necessity to fetch them
361 * again - if identifier changes, it means the image has changed.
362 *
363 * Only bitmap keys may be used with this method:
364 * <ul>
365 * <li>{@link #METADATA_KEY_ICON}</li>
366 * <li>{@link #METADATA_KEY_ART}</li>
367 * </ul>
368 *
369 * @param key The key the value is stored under.
370 * @return a bitmap identifier or 0 if it's missing.
371 * @hide This API is not thoroughly elaborated yet
372 */
373 public int getBitmapId(@NonNull String key) {
374 if (!METADATA_KEY_ICON.equals(key) && !METADATA_KEY_ART.equals(key)) return 0;
375 return getInt(key);
376 }
377
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700378 public Clock getClock(String key) {
379 Clock clock = null;
380 try {
381 clock = mBundle.getParcelable(key);
382 } catch (Exception e) {
383 // ignore, value was not a clock.
384 Log.w(TAG, "Failed to retrieve a key as Clock.", e);
385 }
386 return clock;
387 }
388
Eric Laurent2035ac82015-03-05 15:18:44 -0800389 @Override
390 public int describeContents() {
391 return 0;
392 }
393
394 @Override
395 public void writeToParcel(Parcel dest, int flags) {
396 dest.writeBundle(mBundle);
397 }
398
399 /**
400 * Returns the number of fields in this meta data.
401 *
402 * @return the number of fields in the meta data.
403 */
404 public int size() {
405 return mBundle.size();
406 }
407
408 /**
409 * Returns a Set containing the Strings used as keys in this meta data.
410 *
411 * @return a Set of String keys
412 */
413 public Set<String> keySet() {
414 return mBundle.keySet();
415 }
416
417 /**
418 * Helper for getting the String key used by {@link RadioMetadata} from the
419 * corrsponding native integer key.
420 *
421 * @param editorKey The key used by the editor
422 * @return the key used by this class or null if no mapping exists
423 * @hide
424 */
425 public static String getKeyFromNativeKey(int nativeKey) {
426 return NATIVE_KEY_MAPPING.get(nativeKey, null);
427 }
428
429 public static final Parcelable.Creator<RadioMetadata> CREATOR =
430 new Parcelable.Creator<RadioMetadata>() {
431 @Override
432 public RadioMetadata createFromParcel(Parcel in) {
433 return new RadioMetadata(in);
434 }
435
436 @Override
437 public RadioMetadata[] newArray(int size) {
438 return new RadioMetadata[size];
439 }
440 };
441
442 /**
443 * Use to build RadioMetadata objects.
444 */
445 public static final class Builder {
446 private final Bundle mBundle;
447
448 /**
449 * Create an empty Builder. Any field that should be included in the
450 * {@link RadioMetadata} must be added.
451 */
452 public Builder() {
453 mBundle = new Bundle();
454 }
455
456 /**
457 * Create a Builder using a {@link RadioMetadata} instance to set the
458 * initial values. All fields in the source meta data will be included in
459 * the new meta data. Fields can be overwritten by adding the same key.
460 *
461 * @param source
462 */
463 public Builder(RadioMetadata source) {
464 mBundle = new Bundle(source.mBundle);
465 }
466
467 /**
468 * Create a Builder using a {@link RadioMetadata} instance to set
469 * initial values, but replace bitmaps with a scaled down copy if they
470 * are larger than maxBitmapSize.
471 *
472 * @param source The original meta data to copy.
473 * @param maxBitmapSize The maximum height/width for bitmaps contained
474 * in the meta data.
475 * @hide
476 */
477 public Builder(RadioMetadata source, int maxBitmapSize) {
478 this(source);
479 for (String key : mBundle.keySet()) {
480 Object value = mBundle.get(key);
481 if (value != null && value instanceof Bitmap) {
482 Bitmap bmp = (Bitmap) value;
483 if (bmp.getHeight() > maxBitmapSize || bmp.getWidth() > maxBitmapSize) {
484 putBitmap(key, scaleBitmap(bmp, maxBitmapSize));
485 }
486 }
487 }
488 }
489
490 /**
491 * Put a String value into the meta data. Custom keys may be used, but if
492 * the METADATA_KEYs defined in this class are used they may only be one
493 * of the following:
494 * <ul>
Eric Laurent2035ac82015-03-05 15:18:44 -0800495 * <li>{@link #METADATA_KEY_RDS_PS}</li>
496 * <li>{@link #METADATA_KEY_RDS_RT}</li>
497 * <li>{@link #METADATA_KEY_TITLE}</li>
498 * <li>{@link #METADATA_KEY_ARTIST}</li>
499 * <li>{@link #METADATA_KEY_ALBUM}</li>
500 * <li>{@link #METADATA_KEY_GENRE}</li>
501 * </ul>
502 *
503 * @param key The key for referencing this value
504 * @param value The String value to store
505 * @return the same Builder instance
506 */
507 public Builder putString(String key, String value) {
508 if (!METADATA_KEYS_TYPE.containsKey(key) ||
509 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
510 throw new IllegalArgumentException("The " + key
511 + " key cannot be used to put a String");
512 }
513 mBundle.putString(key, value);
514 return this;
515 }
516
517 /**
518 * Put an int value into the meta data. Custom keys may be used, but if
519 * the METADATA_KEYs defined in this class are used they may only be one
520 * of the following:
521 * <ul>
Tomasz Wasilczykd6e269a2017-06-29 17:52:54 -0700522 * <li>{@link #METADATA_KEY_RDS_PI}</li>
Eric Laurent2035ac82015-03-05 15:18:44 -0800523 * <li>{@link #METADATA_KEY_RDS_PTY}</li>
524 * <li>{@link #METADATA_KEY_RBDS_PTY}</li>
525 * </ul>
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700526 * or any bitmap represented by its identifier.
Eric Laurent2035ac82015-03-05 15:18:44 -0800527 *
528 * @param key The key for referencing this value
529 * @param value The int value to store
530 * @return the same Builder instance
531 */
532 public Builder putInt(String key, int value) {
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700533 RadioMetadata.putInt(mBundle, key, value);
Eric Laurent2035ac82015-03-05 15:18:44 -0800534 return this;
535 }
536
537 /**
538 * Put a {@link Bitmap} into the meta data. Custom keys may be used, but
539 * if the METADATA_KEYs defined in this class are used they may only be
540 * one of the following:
541 * <ul>
542 * <li>{@link #METADATA_KEY_ICON}</li>
543 * <li>{@link #METADATA_KEY_ART}</li>
544 * </ul>
545 * <p>
546 *
547 * @param key The key for referencing this value
548 * @param value The Bitmap to store
549 * @return the same Builder instance
550 */
551 public Builder putBitmap(String key, Bitmap value) {
552 if (!METADATA_KEYS_TYPE.containsKey(key) ||
553 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
554 throw new IllegalArgumentException("The " + key
555 + " key cannot be used to put a Bitmap");
556 }
557 mBundle.putParcelable(key, value);
558 return this;
559 }
560
561 /**
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700562 * Put a {@link RadioMetadata.Clock} into the meta data. Custom keys may be used, but if the
563 * METADATA_KEYs defined in this class are used they may only be one of the following:
564 * <ul>
565 * <li>{@link #MEADATA_KEY_CLOCK}</li>
566 * </ul>
567 *
568 * @param utcSecondsSinceEpoch Number of seconds since epoch for UTC + 0 timezone.
569 * @param timezoneOffsetInMinutes Offset of timezone from UTC + 0 in minutes.
570 * @return the same Builder instance.
571 */
572 public Builder putClock(String key, long utcSecondsSinceEpoch, int timezoneOffsetMinutes) {
573 if (!METADATA_KEYS_TYPE.containsKey(key) ||
574 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
575 throw new IllegalArgumentException("The " + key
576 + " key cannot be used to put a RadioMetadata.Clock.");
577 }
578 mBundle.putParcelable(key, new Clock(utcSecondsSinceEpoch, timezoneOffsetMinutes));
579 return this;
580 }
581
582 /**
Eric Laurent2035ac82015-03-05 15:18:44 -0800583 * Creates a {@link RadioMetadata} instance with the specified fields.
584 *
585 * @return a new {@link RadioMetadata} object
586 */
587 public RadioMetadata build() {
588 return new RadioMetadata(mBundle);
589 }
590
591 private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
592 float maxSizeF = maxSize;
593 float widthScale = maxSizeF / bmp.getWidth();
594 float heightScale = maxSizeF / bmp.getHeight();
595 float scale = Math.min(widthScale, heightScale);
596 int height = (int) (bmp.getHeight() * scale);
597 int width = (int) (bmp.getWidth() * scale);
598 return Bitmap.createScaledBitmap(bmp, width, height, true);
599 }
600 }
601
602 int putIntFromNative(int nativeKey, int value) {
603 String key = getKeyFromNativeKey(nativeKey);
Tomasz Wasilczyk4482b142017-07-17 13:57:12 -0700604 try {
605 putInt(mBundle, key, value);
606 return 0;
607 } catch (IllegalArgumentException ex) {
Eric Laurent2035ac82015-03-05 15:18:44 -0800608 return -1;
609 }
Eric Laurent2035ac82015-03-05 15:18:44 -0800610 }
611
612 int putStringFromNative(int nativeKey, String value) {
613 String key = getKeyFromNativeKey(nativeKey);
614 if (!METADATA_KEYS_TYPE.containsKey(key) ||
615 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
616 return -1;
617 }
618 mBundle.putString(key, value);
619 return 0;
620 }
621
622 int putBitmapFromNative(int nativeKey, byte[] value) {
623 String key = getKeyFromNativeKey(nativeKey);
624 if (!METADATA_KEYS_TYPE.containsKey(key) ||
625 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
626 return -1;
627 }
628 Bitmap bmp = null;
629 try {
630 bmp = BitmapFactory.decodeByteArray(value, 0, value.length);
Ray Essick76010492016-11-03 14:45:56 -0700631 if (bmp != null) {
632 mBundle.putParcelable(key, bmp);
633 return 0;
Eric Laurent2035ac82015-03-05 15:18:44 -0800634 }
Ray Essick76010492016-11-03 14:45:56 -0700635 } catch (Exception e) {
Eric Laurent2035ac82015-03-05 15:18:44 -0800636 }
Ray Essick76010492016-11-03 14:45:56 -0700637 return -1;
Eric Laurent2035ac82015-03-05 15:18:44 -0800638 }
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700639
640 int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
Sanket Agarwal7058e4c2015-10-08 14:14:20 -0700641 String key = getKeyFromNativeKey(nativeKey);
642 if (!METADATA_KEYS_TYPE.containsKey(key) ||
643 METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
644 return -1;
645 }
646 mBundle.putParcelable(key, new RadioMetadata.Clock(
647 utcEpochSeconds, timezoneOffsetInMinutes));
648 return 0;
649 }
Eric Laurent2035ac82015-03-05 15:18:44 -0800650}