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; 219193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 22cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.Calendar; 239193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport java.util.Collections; 249193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport java.util.Date; 25a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Cataniaimport java.util.HashMap; 26cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.Set; 27cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Cataniaimport java.util.TimeZone; 289193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 295d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 309193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania/** 319193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Class to hold the media's metadata. Metadata are used 329193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania for human consumption and can be embedded in the media (e.g 339193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania shoutcast) or available from an external source. The source can be 341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang local (e.g thumbnail stored in the DB) or remote. 359193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 369193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Metadata is like a Bundle. It is sparse and each key can occur at 379193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania most once. The key is an integer and the value is the actual metadata. 389193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 399193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania The caller is expected to know the type of the metadata and call 409193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania the right get* method to fetch its value. 4148c5fb14933cba4dcf6ba401b895e59bac4a8420Dianne Hackborn 4248c5fb14933cba4dcf6ba401b895e59bac4a8420Dianne Hackborn @hide 43edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik @deprecated Use {@link MediaMetadata}. 449193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 45edb158f55f48a1f7b2cbf30ddec9b8917dc9a619RoboErik@Deprecated public class Metadata 469193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania{ 479193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // The metadata are keyed using integers rather than more heavy 489193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // weight strings. We considered using Bundle to ship the metadata 499193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // between the native layer and the java layer but dropped that 509193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // option since keeping in sync a native implementation of Bundle 519193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // and the java one would be too burdensome. Besides Bundle uses 529193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // String for its keys. 539193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // The key range [0 8192) is reserved for the system. 549193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // 559193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // We manually serialize the data in Parcels. For large memory 569193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // blob (bitmaps, raw pictures) we use MemoryFile which allow the 57a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // client to make the data purge-able once it is done with it. 589193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // 599193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 601e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 611e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 621e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 639193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final int ANY = 0; // Never used for metadata returned, only for filtering. 64b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // Keep in sync with kAny in MediaPlayerService.cpp 659193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 661e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // Playback capabilities. 671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 681e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be paused 691e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 701e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int PAUSE_AVAILABLE = 1; // Boolean 711e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 721e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be backward seeked 731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_BACKWARD_AVAILABLE = 2; // Boolean 751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 761e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be forward seeked 771e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 781e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_FORWARD_AVAILABLE = 3; // Boolean 791e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 801e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Indicate whether the media can be seeked 811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int SEEK_AVAILABLE = 4; // Boolean 831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang 849193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // TODO: Should we use numbers compatible with the metadata retriever? 851e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 861e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 871e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 881e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int TITLE = 5; // String 891e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 901e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 911e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 921e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COMMENT = 6; // String 931e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 941e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 951e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 961e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COPYRIGHT = 7; // String 971e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 981e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 991e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1001e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ALBUM = 8; // String 1011e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1021e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1031e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1041e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ARTIST = 9; // String 1051e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1061e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1071e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1081e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUTHOR = 10; // String 1091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1111e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1121e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int COMPOSER = 11; // String 1131e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1141e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1161e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int GENRE = 12; // String 1171e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1181e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1191e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1201e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DATE = 13; // Date 1211e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1241e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DURATION = 14; // Integer(millisec) 1251e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1261e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1271e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1281e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int CD_TRACK_NUM = 15; // Integer 1-based 1291e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1301e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1321e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int CD_TRACK_MAX = 16; // Integer 1331e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1351e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1361e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int RATING = 17; // String 1371e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1381e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int ALBUM_ART = 18; // byte[] 1411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1421e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1431e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1441e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_FRAME = 19; // Bitmap 1459193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 1461e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1471e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1481e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1491e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int BIT_RATE = 20; // Integer, Aggregate rate of 1501e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // all the streams in bps. 1519193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 1521e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1531e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1541e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1551e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_BIT_RATE = 21; // Integer, bps 1561e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1571e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1581e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1591e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_BIT_RATE = 22; // Integer, bps 1601e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1611e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1621e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1631e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_SAMPLE_RATE = 23; // Integer, Hz 1641e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1651e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1661e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_FRAME_RATE = 24; // Integer, Hz 168716383a686b086f68533a51785ba77186359ce6bNicolas Catania 1691e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang // See RFC2046 and RFC4281. 1701e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1711e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1721e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int MIME_TYPE = 25; // String 1741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1761e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1771e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int AUDIO_CODEC = 26; // String 1781e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1791e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1801e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_CODEC = 27; // String 1821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang 1831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1841e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1851e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1861e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_HEIGHT = 28; // Integer 1871e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1881e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1891e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1901e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int VIDEO_WIDTH = 29; // Integer 1911e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1921e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1931e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1941e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int NUM_TRACKS = 30; // Integer 1951e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 1961e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 1971e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 1981e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DRM_CRIPPLED = 31; // Boolean 199716383a686b086f68533a51785ba77186359ce6bNicolas Catania 2001e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang private static final int LAST_SYSTEM = 31; 201bc7269278042e448299c2e80e4dbb16fed05791dniko private static final int FIRST_CUSTOM = 8192; 2029193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 2039193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // Shorthands to set the MediaPlayer's metadata filter. 2041e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2051e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2061e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2079193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET; 2081e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2119193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY); 2129193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 2131e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2141e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 216cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int STRING_VAL = 1; 2171e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2181e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2191e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 220cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int INTEGER_VAL = 2; 2211e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 224cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int BOOLEAN_VAL = 3; 2251e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2261e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2271e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 228cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int LONG_VAL = 4; 2291e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2301e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 232cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public static final int DOUBLE_VAL = 5; 2331e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2351e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2361e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int DATE_VAL = 6; 2371e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 2381e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 2401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang public static final int BYTE_ARRAY_VAL = 7; 241cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // FIXME: misses a type for shared heap is missing (MemoryFile). 242cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // FIXME: misses a type for bitmaps. 2431e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang private static final int LAST_TYPE = 7; 244a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 245a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private static final String TAG = "media.Metadata"; 2466fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kInt32Size = 4; 2476fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kMetaHeaderSize = 2 * kInt32Size; // size + marker 2486fa41bbb56e0756d3eac15d6314007e4a450c9d3niko private static final int kRecordHeaderSize = 3 * kInt32Size; // size + id + type 2496fa41bbb56e0756d3eac15d6314007e4a450c9d3niko 250a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private static final int kMetaMarker = 0x4d455441; // 'M' 'E' 'T' 'A' 251a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 252a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // After a successful parsing, set the parcel with the serialized metadata. 253a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private Parcel mParcel; 254a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 255a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Map to associate a Metadata key (e.g TITLE) with the offset of 256a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // the record's payload in the parcel. 257a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Used to look up if a key was present too. 258a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Key: Metadata ID 259a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Value: Offset of the metadata type field in the record. 260cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania private final HashMap<Integer, Integer> mKeyToPosMap = 261cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania new HashMap<Integer, Integer>(); 2625d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 2639193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 2641e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 2659193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 266a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public Metadata() { } 2679193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 268a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania /** 269a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Go over all the records, collecting metadata keys and records' 270a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * type field offset in the Parcel. These are stored in 271a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * mKeyToPosMap for latter retrieval. 272a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Format of a metadata record: 273a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania <pre> 274a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 1 2 3 275a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas 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 276a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 277a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | record size | 278a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 279a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata key | // TITLE 280a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 281a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata type | // STRING_VAL 282a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 283a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 284a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | .... metadata payload .... | 285a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 286a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 287a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania </pre> 288a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param parcel With the serialized records. 289a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param bytesLeft How many bytes in the parcel should be processed. 290a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return false if an error occurred during parsing. 291a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania */ 292a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private boolean scanAllRecords(Parcel parcel, int bytesLeft) { 293a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania int recCount = 0; 294a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania boolean error = false; 295a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 296a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.clear(); 297a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania while (bytesLeft > kRecordHeaderSize) { 298a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int start = parcel.dataPosition(); 299a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the size. 300a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int size = parcel.readInt(); 301a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 302a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (size <= kRecordHeaderSize) { // at least 1 byte should be present. 303a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Record is too short"); 304a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 305a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 306a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 307a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 308a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the metadata key. 309a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int metadataId = parcel.readInt(); 310a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!checkMetadataId(metadataId)) { 311a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 312a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 313a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 314a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 315a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Store the record offset which points to the type 316a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // field so we can later on read/unmarshall the record 317a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // payload. 318a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (mKeyToPosMap.containsKey(metadataId)) { 319a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Duplicate metadata ID found"); 320a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 321a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 322a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 323a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 324a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.put(metadataId, parcel.dataPosition()); 325a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 326a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Check the metadata type. 327a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int metadataType = parcel.readInt(); 328a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (metadataType <= 0 || metadataType > LAST_TYPE) { 329a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Invalid metadata type " + metadataType); 330a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania error = true; 331a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania break; 332a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 333a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 334a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Skip to the next one. 335a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(start + size); 336a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania bytesLeft -= size; 337a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania ++recCount; 338a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 339a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 340a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (0 != bytesLeft || error) { 341a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Ran out of data or error on record " + recCount); 342a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mKeyToPosMap.clear(); 343a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 344a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } else { 345a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 346a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 3475d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania } 3485d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 3499193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 350a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Check a parcel containing metadata is well formed. The header 351a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * is checked as well as the individual records format. However, the 352a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * data inside the record is not checked because we do lazy access 353a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * (we check/unmarshall only data the user asks for.) 354a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * 355a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * Format of a metadata parcel: 356a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania <pre> 357a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 1 2 3 358a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas 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 359a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 360a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | metadata total size | 361a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 362a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | 'M' | 'E' | 'T' | 'A' | 363a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 365a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | .... metadata records .... | 366a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania | | 367a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania </pre> 369a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * 370a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @param parcel With the serialized data. Metadata keeps a 371a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * reference on it to access it later on. The caller 372a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * should not modify the parcel after this call (and 373a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * not call recycle on it.) 374a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return false if an error occurred. 3751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 3769193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 377a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public boolean parse(Parcel parcel) { 378a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (parcel.dataAvail() < kMetaHeaderSize) { 379a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Not enough data " + parcel.dataAvail()); 380a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 381a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 382a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 383a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int pin = parcel.dataPosition(); // to roll back in case of errors. 384a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int size = parcel.readInt(); 385a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 3866fa41bbb56e0756d3eac15d6314007e4a450c9d3niko // The extra kInt32Size below is to account for the int32 'size' just read. 3876fa41bbb56e0756d3eac15d6314007e4a450c9d3niko if (parcel.dataAvail() + kInt32Size < size || size < kMetaHeaderSize) { 388c39173be3237be9f39d2b57bb38249126e183c53niko Log.e(TAG, "Bad size " + size + " avail " + parcel.dataAvail() + " position " + pin); 389a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 390a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 391a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 392a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 393a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Checks if the 'M' 'E' 'T' 'A' marker is present. 394a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania final int kShouldBeMetaMarker = parcel.readInt(); 395a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (kShouldBeMetaMarker != kMetaMarker ) { 396a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Marker missing " + Integer.toHexString(kShouldBeMetaMarker)); 397a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 398a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 399a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 400a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 401a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania // Scan the records to collect metadata ids and offsets. 402a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!scanAllRecords(parcel, size - kMetaHeaderSize)) { 403a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania parcel.setDataPosition(pin); 404a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 405a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 406a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania mParcel = parcel; 407a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 4089193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4099193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4109193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 411a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania * @return The set of metadata ID found. 4129193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 413a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public Set<Integer> keySet() { 414a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return mKeyToPosMap.keySet(); 4159193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4169193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4179193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 4189193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @return true if a value is present for the given key. 4199193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 420a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public boolean has(final int metadataId) { 421a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (!checkMetadataId(metadataId)) { 422a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania throw new IllegalArgumentException("Invalid key: " + metadataId); 4239193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 424a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return mKeyToPosMap.containsKey(metadataId); 4259193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4269193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 427cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // Accessors. 428cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // Caller must make sure the key is present using the {@code has} 429cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania // method otherwise a RuntimeException will occur. 430cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 4311e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4321e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4331e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4349193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public String getString(final int key) { 435cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, STRING_VAL); 436cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readString(); 4379193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4389193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4391e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4401e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4411e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4429193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public int getInt(final int key) { 443cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, INTEGER_VAL); 444cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readInt(); 445cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 446cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 4471e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4481e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Get the boolean value indicated by key 4491e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 450cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania public boolean getBoolean(final int key) { 451cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, BOOLEAN_VAL); 452cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readInt() == 1; 4539193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4549193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4551e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4561e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4571e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4589193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public long getLong(final int key) { 4591e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang checkType(key, LONG_VAL); /** 4601e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4611e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 462cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readLong(); 4639193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4649193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4651e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4661e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4671e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4689193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public double getDouble(final int key) { 469cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, DOUBLE_VAL); 470cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.readDouble(); 4719193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4729193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4731e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4741e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4751e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4769193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public byte[] getByteArray(final int key) { 477cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, BYTE_ARRAY_VAL); 478cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return mParcel.createByteArray(); 4799193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4809193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 4811e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 4821e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 4831e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 4849193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public Date getDate(final int key) { 485cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania checkType(key, DATE_VAL); 486cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final long timeSinceEpoch = mParcel.readLong(); 487cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final String timeZone = mParcel.readString(); 488cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 489cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania if (timeZone.length() == 0) { 490cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return new Date(timeSinceEpoch); 491cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } else { 492cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania TimeZone tz = TimeZone.getTimeZone(timeZone); 493cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania Calendar cal = Calendar.getInstance(tz); 494cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 495cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania cal.setTimeInMillis(timeSinceEpoch); 496cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania return cal.getTime(); 497cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 4989193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 4999193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5001e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5011e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the last available system metadata id. Ids are 5021e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * 1-indexed. 5031e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5041e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 505a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int lastSytemId() { return LAST_SYSTEM; } 506a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5071e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5081e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the first available cutom metadata id. 5091e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5101e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 511a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int firstCustomId() { return FIRST_CUSTOM; } 512a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5131e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5141e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return the last value of known type. Types are 1-indexed. 5151e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * {@hide} 5161e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 517a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania public static int lastType() { return LAST_TYPE; } 518a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania 5191e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5201e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Check val is either a system id or a custom one. 5211e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @param val Metadata key to test. 5221e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * @return true if it is in a valid range. 5231e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang **/ 524a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania private boolean checkMetadataId(final int val) { 525a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania if (val <= ANY || (LAST_SYSTEM < val && val < FIRST_CUSTOM)) { 526a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania Log.e(TAG, "Invalid metadata ID " + val); 527a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return false; 528a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 529a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania return true; 530a5ccb22a3ddb342fe3f7e5493095c6e6dceda60bNicolas Catania } 531cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 5321e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang /** 5331e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang * Check the type of the data match what is expected. 5341e1b13e62e38d6efc7cef4b496b3119bd45ee2c2Gloria Wang */ 535cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania private void checkType(final int key, final int expectedType) { 536cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final int pos = mKeyToPosMap.get(key); 537cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 538cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania mParcel.setDataPosition(pos); 539cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania 540cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania final int type = mParcel.readInt(); 541cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania if (type != expectedType) { 542cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania throw new IllegalStateException("Wrong type " + expectedType + " but got " + type); 543cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 544cb2e00eedce99b30faf5f238136a00bc5448c5f2Nicolas Catania } 5459193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania} 546