19193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania/* 29193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Copyright (C) 2009 The Android Open Source Project 39193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 49193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Licensed under the Apache License, Version 2.0 (the "License"); 59193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * you may not use this file except in compliance with the License. 69193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * You may obtain a copy of the License at 79193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 89193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * http://www.apache.org/licenses/LICENSE-2.0 99193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 109193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Unless required by applicable law or agreed to in writing, software 119193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * distributed under the License is distributed on an "AS IS" BASIS, 129193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * See the License for the specific language governing permissions and 149193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * limitations under the License. 159193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 169193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 179193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniapackage android.media; 189193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 195d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Cataniaimport android.os.Parcel; 209193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport android.util.Log; 211619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinskiimport android.util.MathUtils; 229193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 23cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.Calendar; 249193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport java.util.Collections; 259193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport java.util.Date; 26a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Cataniaimport java.util.HashMap; 27cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.Set; 28cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.TimeZone; 299193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 305d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 319193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania/** 329193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Class to hold the media's metadata. Metadata are used 339193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania for human consumption and can be embedded in the media (e.g 349193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania shoutcast) or available from an external source. The source can be 351e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang local (e.g thumbnail stored in the DB) or remote. 369193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 379193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Metadata is like a Bundle. It is sparse and each key can occur at 389193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania most once. The key is an integer and the value is the actual metadata. 399193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 409193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania The caller is expected to know the type of the metadata and call 419193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania the right get* method to fetch its value. 4248c5fb14933cba4dcf6ba401b895e59bac4a8420Dianne Hackborn 4348c5fb14933cba4dcf6ba401b895e59bac4a8420Dianne Hackborn @hide 44edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik @deprecated Use {@link MediaMetadata}. 459193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 46edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik@Deprecated public class Metadata 479193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania{ 489193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // The metadata are keyed using integers rather than more heavy 499193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // weight strings. We considered using Bundle to ship the metadata 509193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // between the native layer and the java layer but dropped that 519193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // option since keeping in sync a native implementation of Bundle 529193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // and the java one would be too burdensome. Besides Bundle uses 539193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // String for its keys. 549193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // The key range [0 8192) is reserved for the system. 559193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // 569193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // We manually serialize the data in Parcels. For large memory 579193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // blob (bitmaps, raw pictures) we use MemoryFile which allow the 58a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // client to make the data purge-able once it is done with it. 599193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // 609193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 611e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 621e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 631e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 649193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final int ANY = 0; // Never used for metadata returned, only for filtering. 65b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // Keep in sync with kAny in MediaPlayerService.cpp 669193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // Playback capabilities. 681e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 691e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be paused 701e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 711e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int PAUSE_AVAILABLE = 1; // Boolean 721e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be backward seeked 741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_BACKWARD_AVAILABLE = 2; // Boolean 761e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 771e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be forward seeked 781e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 791e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_FORWARD_AVAILABLE = 3; // Boolean 801e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be seeked 821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_AVAILABLE = 4; // Boolean 841e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang 859193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // TODO: Should we use numbers compatible with the metadata retriever? 861e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 871e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 881e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 891e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int TITLE = 5; // String 901e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 911e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 921e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 931e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COMMENT = 6; // String 941e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 951e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 961e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 971e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COPYRIGHT = 7; // String 981e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 991e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1001e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1011e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ALBUM = 8; // String 1021e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1031e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1041e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1051e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ARTIST = 9; // String 1061e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1071e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1081e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUTHOR = 10; // String 1101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1111e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1121e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1131e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COMPOSER = 11; // String 1141e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1161e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1171e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int GENRE = 12; // String 1181e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1191e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1201e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1211e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DATE = 13; // Date 1221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1241e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1251e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DURATION = 14; // Integer(millisec) 1261e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1271e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1281e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1291e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int CD_TRACK_NUM = 15; // Integer 1-based 1301e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1321e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1331e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int CD_TRACK_MAX = 16; // Integer 1341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1351e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1361e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1371e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int RATING = 17; // String 1381e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ALBUM_ART = 18; // byte[] 1421e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1431e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1441e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1451e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_FRAME = 19; // Bitmap 1469193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 1471e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1481e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1491e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1501e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int BIT_RATE = 20; // Integer, Aggregate rate of 1511e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // all the streams in bps. 1529193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 1531e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1541e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1551e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1561e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_BIT_RATE = 21; // Integer, bps 1571e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1581e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1591e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1601e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_BIT_RATE = 22; // Integer, bps 1611e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1621e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1631e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1641e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_SAMPLE_RATE = 23; // Integer, Hz 1651e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1661e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1681e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_FRAME_RATE = 24; // Integer, Hz 169716383a686b086f68533a51785ba77186359ce6bNicolas Catania 1701e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // See RFC2046 and RFC4281. 1711e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1721e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int MIME_TYPE = 25; // String 1751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1761e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1771e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1781e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_CODEC = 26; // String 1791e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1801e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_CODEC = 27; // String 1831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang 1841e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1851e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1861e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1871e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_HEIGHT = 28; // Integer 1881e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1891e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1901e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1911e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_WIDTH = 29; // Integer 1921e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1931e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1941e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1951e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int NUM_TRACKS = 30; // Integer 1961e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1971e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1981e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1991e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DRM_CRIPPLED = 31; // Boolean 200716383a686b086f68533a51785ba77186359ce6bNicolas Catania 2011e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang private static final int LAST_SYSTEM = 31; 202bc7269278042e448299c2e80e4dbb16fed05791dniko private static final int FIRST_CUSTOM = 8192; 2039193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 2049193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // Shorthands to set the MediaPlayer's metadata filter. 2051e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2061e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2071e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2089193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET; 2091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2111e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2129193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY); 2139193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 2141e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2161e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 217cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int STRING_VAL = 1; 2181e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2191e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2201e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 221cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int INTEGER_VAL = 2; 2221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2241e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 225cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int BOOLEAN_VAL = 3; 2261e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2271e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2281e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 229cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int LONG_VAL = 4; 2301e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2321e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 233cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int DOUBLE_VAL = 5; 2341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2351e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2361e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2371e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DATE_VAL = 6; 2381e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int BYTE_ARRAY_VAL = 7; 242cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // FIXME: misses a type for shared heap is missing (MemoryFile). 243cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // FIXME: misses a type for bitmaps. 2441e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang private static final int LAST_TYPE = 7; 245a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 246a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private static final String TAG = "media.Metadata"; 2476fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kInt32Size = 4; 2486fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kMetaHeaderSize = 2 * kInt32Size; // size + marker 2496fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kRecordHeaderSize = 3 * kInt32Size; // size + id + type 2506fa41bbb56e0756d3eac15d6314007e4a450c9d3niko 251a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private static final int kMetaMarker = 0x4d455441; // 'M' 'E' 'T' 'A' 252a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 253a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // After a successful parsing, set the parcel with the serialized metadata. 254a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private Parcel mParcel; 255a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 256a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Map to associate a Metadata key (e.g TITLE) with the offset of 257a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // the record's payload in the parcel. 258a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Used to look up if a key was present too. 259a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Key: Metadata ID 260a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Value: Offset of the metadata type field in the record. 261cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania private final HashMap<Integer, Integer> mKeyToPosMap = 262cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania new HashMap<Integer, Integer>(); 2635d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 2649193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 2651e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2669193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 267a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public Metadata() { } 2689193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 269a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania /** 270a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Go over all the records, collecting metadata keys and records' 271a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * type field offset in the Parcel. These are stored in 272a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * mKeyToPosMap for latter retrieval. 273a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Format of a metadata record: 274a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania <pre> 275a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 1 2 3 276a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 277a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 278a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | record size | 279a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 280a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata key | // TITLE 281a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 282a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata type | // STRING_VAL 283a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 284a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 285a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | .... metadata payload .... | 286a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 287a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 288a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania </pre> 289a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param parcel With the serialized records. 290a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param bytesLeft How many bytes in the parcel should be processed. 291a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return false if an error occurred during parsing. 292a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania */ 293a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private boolean scanAllRecords(Parcel parcel, int bytesLeft) { 294a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania int recCount = 0; 295a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania boolean error = false; 296a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 297a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.clear(); 298a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania while (bytesLeft > kRecordHeaderSize) { 299a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int start = parcel.dataPosition(); 300a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the size. 301a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int size = parcel.readInt(); 302a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 303a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (size <= kRecordHeaderSize) { // at least 1 byte should be present. 304a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Record is too short"); 305a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 306a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 307a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 308a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 309a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the metadata key. 310a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int metadataId = parcel.readInt(); 311a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!checkMetadataId(metadataId)) { 312a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 313a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 314a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 315a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 316a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Store the record offset which points to the type 317a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // field so we can later on read/unmarshall the record 318a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // payload. 319a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (mKeyToPosMap.containsKey(metadataId)) { 320a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Duplicate metadata ID found"); 321a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 322a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 323a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 324a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 325a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.put(metadataId, parcel.dataPosition()); 326a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 327a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the metadata type. 328a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int metadataType = parcel.readInt(); 329a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (metadataType <= 0 || metadataType > LAST_TYPE) { 330a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Invalid metadata type " + metadataType); 331a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 332a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 333a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 334a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 335a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Skip to the next one. 3361619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski try { 3371619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski parcel.setDataPosition(MathUtils.addOrThrow(start, size)); 3381619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski } catch (IllegalArgumentException e) { 3391619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski Log.e(TAG, "Invalid size: " + e.getMessage()); 3401619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski error = true; 3411619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski break; 3421619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski } 3431619ed4706a0bf906d967ab7987cd4c475ac3462Adam Lesinski 344a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania bytesLeft -= size; 345a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania ++recCount; 346a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 347a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 348a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (0 != bytesLeft || error) { 349a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Ran out of data or error on record " + recCount); 350a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.clear(); 351a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 352a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } else { 353a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 354a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 3555d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania } 3565d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 3579193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 358a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Check a parcel containing metadata is well formed. The header 359a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * is checked as well as the individual records format. However, the 360a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * data inside the record is not checked because we do lazy access 361a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * (we check/unmarshall only data the user asks for.) 362a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * 363a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Format of a metadata parcel: 364a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania <pre> 365a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 1 2 3 366a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 367a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata total size | 369a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 370a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | 'M' | 'E' | 'T' | 'A' | 371a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 372a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 373a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | .... metadata records .... | 374a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 375a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 376a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania </pre> 377a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * 378a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param parcel With the serialized data. Metadata keeps a 379a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * reference on it to access it later on. The caller 380a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * should not modify the parcel after this call (and 381a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * not call recycle on it.) 382a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return false if an error occurred. 3831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 3849193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 385a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public boolean parse(Parcel parcel) { 386a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (parcel.dataAvail() < kMetaHeaderSize) { 387a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Not enough data " + parcel.dataAvail()); 388a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 389a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 390a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 391a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int pin = parcel.dataPosition(); // to roll back in case of errors. 392a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int size = parcel.readInt(); 393a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 3946fa41bbb56e0756d3eac15d6314007e4a450c9d3niko // The extra kInt32Size below is to account for the int32 'size' just read. 3956fa41bbb56e0756d3eac15d6314007e4a450c9d3niko if (parcel.dataAvail() + kInt32Size < size || size < kMetaHeaderSize) { 396c39173be3237be9f39d2b57bb38249126e183c53niko Log.e(TAG, "Bad size " + size + " avail " + parcel.dataAvail() + " position " + pin); 397a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 398a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 399a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 400a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 401a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Checks if the 'M' 'E' 'T' 'A' marker is present. 402a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int kShouldBeMetaMarker = parcel.readInt(); 403a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (kShouldBeMetaMarker != kMetaMarker ) { 404a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Marker missing " + Integer.toHexString(kShouldBeMetaMarker)); 405a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 406a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 407a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 408a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 409a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Scan the records to collect metadata ids and offsets. 410a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!scanAllRecords(parcel, size - kMetaHeaderSize)) { 411a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 412a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 413a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 414a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mParcel = parcel; 415a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 4169193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4179193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4189193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 419a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return The set of metadata ID found. 4209193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 421a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public Set<Integer> keySet() { 422a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return mKeyToPosMap.keySet(); 4239193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4249193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4259193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 4269193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @return true if a value is present for the given key. 4279193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 428a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public boolean has(final int metadataId) { 429a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!checkMetadataId(metadataId)) { 430a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania throw new IllegalArgumentException("Invalid key: " + metadataId); 4319193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 432a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return mKeyToPosMap.containsKey(metadataId); 4339193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4349193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 435cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // Accessors. 436cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // Caller must make sure the key is present using the {@code has} 437cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // method otherwise a RuntimeException will occur. 438cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 4391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4429193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public String getString(final int key) { 443cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, STRING_VAL); 444cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readString(); 4459193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4469193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4471e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4481e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4491e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4509193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public int getInt(final int key) { 451cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, INTEGER_VAL); 452cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readInt(); 453cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 454cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 4551e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4561e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Get the boolean value indicated by key 4571e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 458cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public boolean getBoolean(final int key) { 459cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, BOOLEAN_VAL); 460cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readInt() == 1; 4619193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4629193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4631e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4641e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4651e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4669193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public long getLong(final int key) { 4671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang checkType(key, LONG_VAL); /** 4681e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4691e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 470cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readLong(); 4719193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4729193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4769193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public double getDouble(final int key) { 477cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, DOUBLE_VAL); 478cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readDouble(); 4799193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4809193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4849193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public byte[] getByteArray(final int key) { 485cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, BYTE_ARRAY_VAL); 486cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.createByteArray(); 4879193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4889193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4891e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4901e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4911e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4929193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public Date getDate(final int key) { 493cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, DATE_VAL); 494cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final long timeSinceEpoch = mParcel.readLong(); 495cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final String timeZone = mParcel.readString(); 496cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 497cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania if (timeZone.length() == 0) { 498cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return new Date(timeSinceEpoch); 499cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } else { 500cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania TimeZone tz = TimeZone.getTimeZone(timeZone); 501cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania Calendar cal = Calendar.getInstance(tz); 502cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 503cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania cal.setTimeInMillis(timeSinceEpoch); 504cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return cal.getTime(); 505cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 5069193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 5079193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5081e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the last available system metadata id. Ids are 5101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * 1-indexed. 5111e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5121e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 513a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int lastSytemId() { return LAST_SYSTEM; } 514a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5161e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the first available cutom metadata id. 5171e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5181e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 519a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int firstCustomId() { return FIRST_CUSTOM; } 520a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5211e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the last value of known type. Types are 1-indexed. 5231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5241e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 525a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int lastType() { return LAST_TYPE; } 526a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5271e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5281e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Check val is either a system id or a custom one. 5291e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @param val Metadata key to test. 5301e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return true if it is in a valid range. 5311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang **/ 532a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private boolean checkMetadataId(final int val) { 533a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (val <= ANY || (LAST_SYSTEM < val && val < FIRST_CUSTOM)) { 534a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Invalid metadata ID " + val); 535a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 536a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 537a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 538a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 539cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 5401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Check the type of the data match what is expected. 5421e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 543cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania private void checkType(final int key, final int expectedType) { 544cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final int pos = mKeyToPosMap.get(key); 545cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 546cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania mParcel.setDataPosition(pos); 547cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 548cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final int type = mParcel.readInt(); 549cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania if (type != expectedType) { 550cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania throw new IllegalStateException("Wrong type " + expectedType + " but got " + type); 551cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 552cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 5539193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania} 554