17d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood/*
27d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
37d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood *
47d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
57d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * you may not use this file except in compliance with the License.
67d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * You may obtain a copy of the License at
77d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood *
87d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
97d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood *
107d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * Unless required by applicable law or agreed to in writing, software
117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
127d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * See the License for the specific language governing permissions and
147d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood * limitations under the License.
157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood */
167d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
170cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodpackage android.mtp;
187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.content.IContentProvider;
207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.database.Cursor;
217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.net.Uri;
227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.os.RemoteException;
237d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.provider.MediaStore.Audio;
247d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.provider.MediaStore.Files;
257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.provider.MediaStore.Images;
267d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.provider.MediaStore.MediaColumns;
277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport android.util.Log;
287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport java.util.ArrayList;
307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodclass MtpPropertyGroup {
327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private static final String TAG = "MtpPropertyGroup";
347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private class Property {
367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        // MTP property code
377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int     code;
387d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        // MTP data type
397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int     type;
407d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        // column index for our query
417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int     column;
427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
437d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Property(int code, int type, int column) {
447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            this.code = code;
457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            this.type = type;
467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            this.column = column;
477d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private final MtpDatabase mDatabase;
517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private final IContentProvider mProvider;
5235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn    private final String mPackageName;
537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private final String mVolumeName;
547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private final Uri mUri;
557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    // list of all properties in this group
577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private final Property[]    mProperties;
587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    // list of columns for database query
607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private String[]             mColumns;
617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private static final String ID_WHERE = Files.FileColumns._ID + "=?";
634356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood    private static final String FORMAT_WHERE = Files.FileColumns.FORMAT + "=?";
644356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood    private static final String ID_FORMAT_WHERE = ID_WHERE + " AND " + FORMAT_WHERE;
657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
664356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood    private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " + FORMAT_WHERE;
677d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    // constructs a property group for a list of properties
6835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn    public MtpPropertyGroup(MtpDatabase database, IContentProvider provider, String packageName,
6935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            String volume, int[] properties) {
707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mDatabase = database;
717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mProvider = provider;
7235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn        mPackageName = packageName;
737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mVolumeName = volume;
747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mUri = Files.getMtpObjectsUri(volume);
757d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
767d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int count = properties.length;
777d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        ArrayList<String> columns = new ArrayList<String>(count);
787d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        columns.add(Files.FileColumns._ID);
797d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
807d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mProperties = new Property[count];
817d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        for (int i = 0; i < count; i++) {
827d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            mProperties[i] = createProperty(properties[i], columns);
837d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
847d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        count = columns.size();
857d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        mColumns = new String[count];
867d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        for (int i = 0; i < count; i++) {
877d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            mColumns[i] = columns.get(i);
887d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
897d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
907d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
917d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private Property createProperty(int code, ArrayList<String> columns) {
927d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        String column = null;
937d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int type;
947d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
957d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood         switch (code) {
967d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_STORAGE_ID:
97b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood                column = Files.FileColumns.STORAGE_ID;
987d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT32;
997d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1007d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood             case MtpConstants.PROPERTY_OBJECT_FORMAT:
1017d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.FORMAT;
1027d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT16;
1037d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1047d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_PROTECTION_STATUS:
1057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                // protection status is always 0
1067d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT16;
1077d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1087d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_OBJECT_SIZE:
1097d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.SIZE;
1107d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT64;
1117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1127d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
1137d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.DATA;
1147d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1167d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_NAME:
1177d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = MediaColumns.TITLE;
1187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_DATE_MODIFIED:
1217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.DATE_MODIFIED;
1227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1237d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1247d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_DATE_ADDED:
1257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.DATE_ADDED;
1267d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
1297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Audio.AudioColumns.YEAR;
1307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_PARENT_OBJECT:
1337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Files.FileColumns.PARENT;
1347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT32;
1357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_PERSISTENT_UID:
1377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                // PUID is concatenation of storageID and object handle
138b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood                column = Files.FileColumns.STORAGE_ID;
1397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT128;
1407d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_DURATION:
1427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Audio.AudioColumns.DURATION;
1437d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT32;
1447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_TRACK:
1467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Audio.AudioColumns.TRACK;
1477d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UINT16;
1487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_DISPLAY_NAME:
1507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = MediaColumns.DISPLAY_NAME;
1517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1527d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_ARTIST:
1547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_ALBUM_NAME:
1577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_ALBUM_ARTIST:
1607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Audio.AudioColumns.ALBUM_ARTIST;
1617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1637d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_GENRE:
1647d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                // genre requires a special query
1657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1677d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_COMPOSER:
1687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Audio.AudioColumns.COMPOSER;
1697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            case MtpConstants.PROPERTY_DESCRIPTION:
1727d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                column = Images.ImageColumns.DESCRIPTION;
1737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_STR;
1747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
17571827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood            case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
17671827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood            case MtpConstants.PROPERTY_AUDIO_BITRATE:
17771827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood            case MtpConstants.PROPERTY_SAMPLE_RATE:
17871827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                // these are special cased
17971827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                type = MtpConstants.TYPE_UINT32;
18071827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                break;
18171827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood            case MtpConstants.PROPERTY_BITRATE_TYPE:
18271827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood            case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
18371827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                // these are special cased
18471827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                type = MtpConstants.TYPE_UINT16;
18571827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                break;
1867d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            default:
1877d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                type = MtpConstants.TYPE_UNDEFINED;
1887d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                Log.e(TAG, "unsupported property " + code);
1897d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                break;
1907d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
1917d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
1927d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        if (column != null) {
1937d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            columns.add(column);
1947d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return new Property(code, type, columns.size() - 1);
1957d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } else {
1967d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return new Property(code, type, -1);
1977d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
1987d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
1997d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
2007d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood   private String queryString(int id, String column) {
2017d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Cursor c = null;
2027d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        try {
2037d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // for now we are only reading properties from the "objects" table
20435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            c = mProvider.query(mPackageName, mUri,
2057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            new String [] { Files.FileColumns._ID, column },
20675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                            ID_WHERE, new String[] { Integer.toString(id) }, null, null);
2077d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null && c.moveToNext()) {
2087d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return c.getString(1);
2097d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            } else {
2107d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return "";
2117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2127d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } catch (Exception e) {
2137d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return null;
2147d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } finally {
2157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null) {
2167d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                c.close();
2177d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
2207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
2217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private String queryAudio(int id, String column) {
2227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Cursor c = null;
2237d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        try {
22435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            c = mProvider.query(mPackageName, Audio.Media.getContentUri(mVolumeName),
2257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            new String [] { Files.FileColumns._ID, column },
22675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                            ID_WHERE, new String[] { Integer.toString(id) }, null, null);
2277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null && c.moveToNext()) {
2287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return c.getString(1);
2297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            } else {
2307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return "";
2317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } catch (Exception e) {
2337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return null;
2347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } finally {
2357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null) {
2367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                c.close();
2377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2387d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
2407d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
2417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private String queryGenre(int id) {
2427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Cursor c = null;
2437d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        try {
2447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
24535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            c = mProvider.query(mPackageName, uri,
2467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
24775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                            null, null, null, null);
2487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null && c.moveToNext()) {
2497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return c.getString(1);
2507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            } else {
2517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return "";
2527d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } catch (Exception e) {
2547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            Log.e(TAG, "queryGenre exception", e);
2557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return null;
2567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } finally {
2577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null) {
2587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                c.close();
2597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
2627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
2637d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private Long queryLong(int id, String column) {
2647d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Cursor c = null;
2657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        try {
2667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // for now we are only reading properties from the "objects" table
26735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            c = mProvider.query(mPackageName, mUri,
2687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            new String [] { Files.FileColumns._ID, column },
26975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown                            ID_WHERE, new String[] { Integer.toString(id) }, null, null);
2707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null && c.moveToNext()) {
2717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                return new Long(c.getLong(1));
2727d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } catch (Exception e) {
2747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } finally {
2757d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null) {
2767d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                c.close();
2777d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
2787d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2797d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return null;
2807d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
2817d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
2827d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private static String nameFromPath(String path) {
2837d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        // extract name from full path
2847d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int start = 0;
2857d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int lastSlash = path.lastIndexOf('/');
2867d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        if (lastSlash >= 0) {
2877d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            start = lastSlash + 1;
2887d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2897d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        int end = path.length();
2907d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        if (end - start > 255) {
2917d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            end = start + 255;
2927d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
2937d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        return path.substring(start, end);
2947d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
2957d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
296b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    MtpPropertyList getPropertyList(int handle, int format, int depth) {
297071b2b6739c83d3de806cda5d7be2aba33fde1afMike Lockwood        //Log.d(TAG, "getPropertyList handle: " + handle + " format: " + format + " depth: " + depth);
2987d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        if (depth > 1) {
2997d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // we only support depth 0 and 1
3007d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // depth 0: single object, depth 1: immediate children
3017d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED);
3027d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
3037d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3047d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        String where;
3057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        String[] whereArgs;
3067d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        if (format == 0) {
3074356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood            if (handle == 0xFFFFFFFF) {
3084356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                // select all objects
3094356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                where = null;
3104356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                whereArgs = null;
3117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            } else {
3124356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                whereArgs = new String[] { Integer.toString(handle) };
3134356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                if (depth == 1) {
3144356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                    where = PARENT_WHERE;
3154356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                } else {
3164356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                    where = ID_WHERE;
3174356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                }
3187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
3197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } else {
3204356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood            if (handle == 0xFFFFFFFF) {
3214356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                // select all objects with given format
3224356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                where = FORMAT_WHERE;
3234356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                whereArgs = new String[] { Integer.toString(format) };
3247d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            } else {
3254356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                whereArgs = new String[] { Integer.toString(handle), Integer.toString(format) };
3264356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                if (depth == 1) {
3274356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                    where = PARENT_FORMAT_WHERE;
3284356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                } else {
3294356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                    where = ID_FORMAT_WHERE;
3304356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood                }
3317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
3327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
3337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        Cursor c = null;
3357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        try {
3367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // don't query if not necessary
3374356d81b34a57a4046d9fa2287c2d85b51c7ca24Mike Lockwood            if (depth > 0 || handle == 0xFFFFFFFF || mColumns.length > 1) {
33835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn                c = mProvider.query(mPackageName, mUri, mColumns, where, whereArgs, null, null);
3397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                if (c == null) {
3407d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
3417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                }
3427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
3437d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            int count = (c == null ? 1 : c.getCount());
3457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            MtpPropertyList result = new MtpPropertyList(count * mProperties.length,
3467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    MtpConstants.RESPONSE_OK);
3477d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            // iterate over all objects in the query
3497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            for (int objectIndex = 0; objectIndex < count; objectIndex++) {
3507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                if (c != null) {
3517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    c.moveToNext();
352fd22edc66818e0336597e23dafc9db4dcfb6878eMike Lockwood                    handle = (int)c.getLong(0);
3537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                }
3547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                // iterate over all properties in the query for the given object
3567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                for (int propertyIndex = 0; propertyIndex < mProperties.length; propertyIndex++) {
3577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    Property property = mProperties[propertyIndex];
3587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    int propertyCode = property.code;
3597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    int column = property.column;
3607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
3617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    // handle some special cases
3627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    switch (propertyCode) {
3637d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_PROTECTION_STATUS:
3647d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // protection status is always 0
3657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0);
3667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
3677d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
3687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // special case - need to extract file name from full path
3697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            String value = c.getString(column);
3707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (value != null) {
3717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, nameFromPath(value));
3727d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            } else {
3737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
3747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
3757d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
3767d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_NAME:
3777d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // first try title
3787d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            String name = c.getString(column);
3797d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // then try name
3807d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (name == null) {
3817d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                name = queryString(handle, Audio.PlaylistsColumns.NAME);
3827d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
3837d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // if title and name fail, extract name from full path
3847d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (name == null) {
3857d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                name = queryString(handle, Files.FileColumns.DATA);
3867d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                if (name != null) {
3877d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                    name = nameFromPath(name);
3887d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                }
3897d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
3907d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (name != null) {
3917d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, name);
3927d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            } else {
3937d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
3947d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
3957d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
3967d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_DATE_MODIFIED:
3977d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_DATE_ADDED:
3987d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // convert from seconds to DateTime
3997d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode, format_date_time(c.getInt(column)));
4007d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4017d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
4027d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // release date is stored internally as just the year
4037d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            int year = c.getInt(column);
4047d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            String dateTime = Integer.toString(year) + "0101T000000";
4057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode, dateTime);
4067d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4077d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_PERSISTENT_UID:
4087d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            // PUID is concatenation of storageID and object handle
409b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood                            long puid = c.getLong(column);
4107d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            puid <<= 32;
4117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            puid += handle;
4127d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT128, puid);
4137d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4147d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_TRACK:
4157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT16,
4167d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                        c.getInt(column) % 1000);
4177d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_ARTIST:
4197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode,
4207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                    queryAudio(handle, Audio.AudioColumns.ARTIST));
4217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_ALBUM_NAME:
4237d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            result.append(handle, propertyCode,
4247d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                    queryAudio(handle, Audio.AudioColumns.ALBUM));
4257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4267d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        case MtpConstants.PROPERTY_GENRE:
4277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            String genre = queryGenre(handle);
4287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (genre != null) {
4297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, genre);
4307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            } else {
4317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
4327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
4337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
43471827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                        case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC:
43571827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                        case MtpConstants.PROPERTY_AUDIO_BITRATE:
43671827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                        case MtpConstants.PROPERTY_SAMPLE_RATE:
43771827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            // we don't have these in our database, so return 0
43871827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT32, 0);
43971827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            break;
44071827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                        case MtpConstants.PROPERTY_BITRATE_TYPE:
44171827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                        case MtpConstants.PROPERTY_NUMBER_OF_CHANNELS:
44271827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            // we don't have these in our database, so return 0
44371827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0);
44471827748105252791854b87da8e0e0c66ff0d2cbMike Lockwood                            break;
4457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                        default:
4467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            if (property.type == MtpConstants.TYPE_STR) {
4477d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, c.getString(column));
4487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            } else if (property.type == MtpConstants.TYPE_UNDEFINED) {
4497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, property.type, 0);
4507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            } else {
4517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                result.append(handle, propertyCode, property.type,
4527d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                                        c.getLong(column));
4537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            }
4547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                            break;
4557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                    }
4567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                }
4577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
4587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
4597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return result;
4607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } catch (RemoteException e) {
4617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            return new MtpPropertyList(0, MtpConstants.RESPONSE_GENERAL_ERROR);
4627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        } finally {
4637d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            if (c != null) {
4647d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood                c.close();
4657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood            }
4667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        }
4677d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood        // impossible to get here, so no return statement
4687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    }
4697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood
4707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood    private native String format_date_time(long seconds);
4717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood}
472