blob: aff2e1b4cf31d58ade3c4a9f18147588445ab47f [file] [log] [blame]
Mike Lockwood7d7fb632010-12-01 18:46:23 -05001/*
2 * Copyright (C) 2010 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 */
16
Mike Lockwood0cd01362010-12-30 11:54:33 -050017package android.mtp;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050018
Jeff Sharkey60cfad82016-01-05 17:30:57 -070019import android.content.ContentProviderClient;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050020import android.database.Cursor;
21import android.net.Uri;
22import android.os.RemoteException;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050023import android.provider.MediaStore.Audio;
24import android.provider.MediaStore.Files;
25import android.provider.MediaStore.Images;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050026import android.util.Log;
27
28import java.util.ArrayList;
29
Jerry Zhangf9c5c252017-08-16 18:07:51 -070030/**
31 * MtpPropertyGroup represents a list of MTP properties.
32 * {@hide}
33 */
Mike Lockwood7d7fb632010-12-01 18:46:23 -050034class MtpPropertyGroup {
Jerry Zhangf9c5c252017-08-16 18:07:51 -070035 private static final String TAG = MtpPropertyGroup.class.getSimpleName();
Mike Lockwood7d7fb632010-12-01 18:46:23 -050036
37 private class Property {
Jerry Zhangf9c5c252017-08-16 18:07:51 -070038 int code;
39 int type;
40 int column;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050041
42 Property(int code, int type, int column) {
43 this.code = code;
44 this.type = type;
45 this.column = column;
46 }
47 }
48
Mike Lockwood7d7fb632010-12-01 18:46:23 -050049 // list of all properties in this group
Jerry Zhangf9c5c252017-08-16 18:07:51 -070050 private final Property[] mProperties;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050051
52 // list of columns for database query
Jerry Zhangf9c5c252017-08-16 18:07:51 -070053 private String[] mColumns;
Mike Lockwood7d7fb632010-12-01 18:46:23 -050054
Jerry Zhangf9c5c252017-08-16 18:07:51 -070055 private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
56
Mike Lockwood7d7fb632010-12-01 18:46:23 -050057 // constructs a property group for a list of properties
Jeff Sharkey42bf6d82019-04-17 11:16:12 -060058 public MtpPropertyGroup(int[] properties) {
Mike Lockwood7d7fb632010-12-01 18:46:23 -050059 int count = properties.length;
Jerry Zhangf9c5c252017-08-16 18:07:51 -070060 ArrayList<String> columns = new ArrayList<>(count);
Mike Lockwood7d7fb632010-12-01 18:46:23 -050061 columns.add(Files.FileColumns._ID);
62
63 mProperties = new Property[count];
64 for (int i = 0; i < count; i++) {
65 mProperties[i] = createProperty(properties[i], columns);
66 }
67 count = columns.size();
68 mColumns = new String[count];
69 for (int i = 0; i < count; i++) {
70 mColumns[i] = columns.get(i);
71 }
72 }
73
74 private Property createProperty(int code, ArrayList<String> columns) {
75 String column = null;
76 int type;
77
Jerry Zhangf9c5c252017-08-16 18:07:51 -070078 switch (code) {
Mike Lockwood7d7fb632010-12-01 18:46:23 -050079 case MtpConstants.PROPERTY_STORAGE_ID:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050080 type = MtpConstants.TYPE_UINT32;
81 break;
Jerry Zhangf9c5c252017-08-16 18:07:51 -070082 case MtpConstants.PROPERTY_OBJECT_FORMAT:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050083 type = MtpConstants.TYPE_UINT16;
84 break;
85 case MtpConstants.PROPERTY_PROTECTION_STATUS:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050086 type = MtpConstants.TYPE_UINT16;
87 break;
88 case MtpConstants.PROPERTY_OBJECT_SIZE:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050089 type = MtpConstants.TYPE_UINT64;
90 break;
91 case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050092 type = MtpConstants.TYPE_STR;
93 break;
94 case MtpConstants.PROPERTY_NAME:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050095 type = MtpConstants.TYPE_STR;
96 break;
97 case MtpConstants.PROPERTY_DATE_MODIFIED:
Mike Lockwood7d7fb632010-12-01 18:46:23 -050098 type = MtpConstants.TYPE_STR;
99 break;
100 case MtpConstants.PROPERTY_DATE_ADDED:
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500101 type = MtpConstants.TYPE_STR;
102 break;
103 case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
104 column = Audio.AudioColumns.YEAR;
105 type = MtpConstants.TYPE_STR;
106 break;
107 case MtpConstants.PROPERTY_PARENT_OBJECT:
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500108 type = MtpConstants.TYPE_UINT32;
109 break;
110 case MtpConstants.PROPERTY_PERSISTENT_UID:
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500111 type = MtpConstants.TYPE_UINT128;
112 break;
113 case MtpConstants.PROPERTY_DURATION:
114 column = Audio.AudioColumns.DURATION;
115 type = MtpConstants.TYPE_UINT32;
116 break;
117 case MtpConstants.PROPERTY_TRACK:
118 column = Audio.AudioColumns.TRACK;
119 type = MtpConstants.TYPE_UINT16;
120 break;
121 case MtpConstants.PROPERTY_DISPLAY_NAME:
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500122 type = MtpConstants.TYPE_STR;
123 break;
124 case MtpConstants.PROPERTY_ARTIST:
James Weif545a3a2020-05-01 15:07:23 +0800125 column = Audio.AudioColumns.ARTIST;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500126 type = MtpConstants.TYPE_STR;
127 break;
128 case MtpConstants.PROPERTY_ALBUM_NAME:
James Weif545a3a2020-05-01 15:07:23 +0800129 column = Audio.AudioColumns.ALBUM;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500130 type = MtpConstants.TYPE_STR;
131 break;
132 case MtpConstants.PROPERTY_ALBUM_ARTIST:
133 column = Audio.AudioColumns.ALBUM_ARTIST;
134 type = MtpConstants.TYPE_STR;
135 break;
James Weif545a3a2020-05-01 15:07:23 +0800136 case MtpConstants.PROPERTY_GENRE:
137 column = Audio.AudioColumns.GENRE;
138 type = MtpConstants.TYPE_STR;
139 break;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500140 case MtpConstants.PROPERTY_COMPOSER:
141 column = Audio.AudioColumns.COMPOSER;
142 type = MtpConstants.TYPE_STR;
143 break;
144 case MtpConstants.PROPERTY_DESCRIPTION:
145 column = Images.ImageColumns.DESCRIPTION;
146 type = MtpConstants.TYPE_STR;
147 break;
Mike Lockwood71827742015-01-23 10:50:08 -0800148 case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
149 case MtpConstants.PROPERTY_AUDIO_BITRATE:
150 case MtpConstants.PROPERTY_SAMPLE_RATE:
151 // these are special cased
152 type = MtpConstants.TYPE_UINT32;
153 break;
154 case MtpConstants.PROPERTY_BITRATE_TYPE:
155 case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
156 // these are special cased
157 type = MtpConstants.TYPE_UINT16;
158 break;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500159 default:
160 type = MtpConstants.TYPE_UNDEFINED;
161 Log.e(TAG, "unsupported property " + code);
162 break;
163 }
164
165 if (column != null) {
166 columns.add(column);
167 return new Property(code, type, columns.size() - 1);
168 } else {
169 return new Property(code, type, -1);
170 }
171 }
172
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700173 /**
174 * Gets the values of the properties represented by this property group for the given
175 * object and adds them to the given property list.
176 * @return Response_OK if the operation succeeded.
177 */
Jeff Sharkey42bf6d82019-04-17 11:16:12 -0600178 public int getPropertyList(ContentProviderClient provider, String volumeName,
179 MtpStorageManager.MtpObject object, MtpPropertyList list) {
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500180 Cursor c = null;
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700181 int id = object.getId();
182 String path = object.getPath().toString();
183 for (Property property : mProperties) {
184 if (property.column != -1 && c == null) {
185 try {
186 // Look up the entry in MediaProvider only if one of those properties is needed.
Jeff Sharkeyff200952019-03-24 12:50:51 -0600187 final Uri uri = MtpDatabase.getObjectPropertiesUri(object.getFormat(),
Jeff Sharkey42bf6d82019-04-17 11:16:12 -0600188 volumeName);
189 c = provider.query(uri, mColumns,
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700190 PATH_WHERE, new String[] {path}, null, null);
191 if (c != null && !c.moveToNext()) {
192 c.close();
193 c = null;
194 }
Jeff Sharkeyff200952019-03-24 12:50:51 -0600195 } catch (IllegalArgumentException e) {
196 return MtpConstants.RESPONSE_INVALID_OBJECT_PROP_CODE;
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700197 } catch (RemoteException e) {
198 Log.e(TAG, "Mediaprovider lookup failed");
Mike Lockwood4356d812011-02-07 13:40:21 -0500199 }
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500200 }
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700201 switch (property.code) {
202 case MtpConstants.PROPERTY_PROTECTION_STATUS:
203 // protection status is always 0
204 list.append(id, property.code, property.type, 0);
205 break;
206 case MtpConstants.PROPERTY_NAME:
207 case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
208 case MtpConstants.PROPERTY_DISPLAY_NAME:
209 list.append(id, property.code, object.getName());
210 break;
211 case MtpConstants.PROPERTY_DATE_MODIFIED:
212 case MtpConstants.PROPERTY_DATE_ADDED:
213 // convert from seconds to DateTime
214 list.append(id, property.code,
215 format_date_time(object.getModifiedTime()));
216 break;
217 case MtpConstants.PROPERTY_STORAGE_ID:
218 list.append(id, property.code, property.type, object.getStorageId());
219 break;
220 case MtpConstants.PROPERTY_OBJECT_FORMAT:
221 list.append(id, property.code, property.type, object.getFormat());
222 break;
223 case MtpConstants.PROPERTY_OBJECT_SIZE:
224 list.append(id, property.code, property.type, object.getSize());
225 break;
226 case MtpConstants.PROPERTY_PARENT_OBJECT:
227 list.append(id, property.code, property.type,
228 object.getParent().isRoot() ? 0 : object.getParent().getId());
229 break;
230 case MtpConstants.PROPERTY_PERSISTENT_UID:
231 // The persistent uid must be unique and never reused among all objects,
232 // and remain the same between sessions.
233 long puid = (object.getPath().toString().hashCode() << 32)
234 + object.getModifiedTime();
235 list.append(id, property.code, property.type, puid);
236 break;
237 case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
238 // release date is stored internally as just the year
239 int year = 0;
240 if (c != null)
241 year = c.getInt(property.column);
242 String dateTime = Integer.toString(year) + "0101T000000";
243 list.append(id, property.code, dateTime);
244 break;
245 case MtpConstants.PROPERTY_TRACK:
246 int track = 0;
247 if (c != null)
248 track = c.getInt(property.column);
249 list.append(id, property.code, MtpConstants.TYPE_UINT16,
250 track % 1000);
251 break;
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700252 case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
253 case MtpConstants.PROPERTY_AUDIO_BITRATE:
254 case MtpConstants.PROPERTY_SAMPLE_RATE:
255 // we don't have these in our database, so return 0
256 list.append(id, property.code, MtpConstants.TYPE_UINT32, 0);
257 break;
258 case MtpConstants.PROPERTY_BITRATE_TYPE:
259 case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
260 // we don't have these in our database, so return 0
261 list.append(id, property.code, MtpConstants.TYPE_UINT16, 0);
262 break;
263 default:
264 switch(property.type) {
265 case MtpConstants.TYPE_UNDEFINED:
266 list.append(id, property.code, property.type, 0);
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500267 break;
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700268 case MtpConstants.TYPE_STR:
269 String value = "";
270 if (c != null)
271 value = c.getString(property.column);
272 list.append(id, property.code, value);
Mike Lockwood71827742015-01-23 10:50:08 -0800273 break;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500274 default:
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700275 long longValue = 0L;
276 if (c != null)
277 longValue = c.getLong(property.column);
278 list.append(id, property.code, property.type, longValue);
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500279 }
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500280 }
281 }
Jerry Zhangf9c5c252017-08-16 18:07:51 -0700282 if (c != null)
283 c.close();
284 return MtpConstants.RESPONSE_OK;
Mike Lockwood7d7fb632010-12-01 18:46:23 -0500285 }
286
287 private native String format_date_time(long seconds);
288}