MtpPropertyGroup.java revision 071b2b6739c83d3de806cda5d7be2aba33fde1af
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2010 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)package android.mtp;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)import android.content.IContentProvider;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.database.Cursor;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.net.Uri;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.os.RemoteException;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.provider.MediaStore;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.provider.MediaStore.Audio;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.provider.MediaStore.Files;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.provider.MediaStore.Images;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.provider.MediaStore.MediaColumns;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Log;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.ArrayList;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MtpPropertyGroup {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String TAG = "MtpPropertyGroup";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private class Property {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // MTP property code
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int     code;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // MTP data type
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int     type;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // column index for our query
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int     column;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Property(int code, int type, int column) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this.code = code;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this.type = type;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this.column = column;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final MtpDatabase mDatabase;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final IContentProvider mProvider;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final String mVolumeName;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final Uri mUri;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // list of all properties in this group
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final Property[]    mProperties;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // list of columns for database query
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private String[]             mColumns;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String ID_WHERE = Files.FileColumns._ID + "=?";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String ID_FORMAT_WHERE = ID_WHERE + " AND "
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            + Files.FileColumns.FORMAT + "=?";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            + Files.FileColumns.FORMAT + "=?";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // constructs a property group for a list of properties
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public MtpPropertyGroup(MtpDatabase database, IContentProvider provider, String volume,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int[] properties) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDatabase = database;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mProvider = provider;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mVolumeName = volume;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mUri = Files.getMtpObjectsUri(volume);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int count = properties.length;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ArrayList<String> columns = new ArrayList<String>(count);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        columns.add(Files.FileColumns._ID);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mProperties = new Property[count];
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < count; i++) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mProperties[i] = createProperty(properties[i], columns);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count = columns.size();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mColumns = new String[count];
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < count; i++) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mColumns[i] = columns.get(i);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private Property createProperty(int code, ArrayList<String> columns) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        String column = null;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int type;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         switch (code) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_STORAGE_ID:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // no query needed until we support multiple storage units
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT32;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             case MtpConstants.PROPERTY_OBJECT_FORMAT:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.FORMAT;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT16;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_PROTECTION_STATUS:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // protection status is always 0
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT16;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_OBJECT_SIZE:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.SIZE;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT64;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.DATA;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_NAME:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = MediaColumns.TITLE;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_DATE_MODIFIED:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.DATE_MODIFIED;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_DATE_ADDED:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.DATE_ADDED;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Audio.AudioColumns.YEAR;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                break;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_PARENT_OBJECT:
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Files.FileColumns.PARENT;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT32;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_PERSISTENT_UID:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // PUID is concatenation of storageID and object handle
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT128;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_DURATION:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Audio.AudioColumns.DURATION;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT32;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_TRACK:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Audio.AudioColumns.TRACK;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UINT16;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_DISPLAY_NAME:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = MediaColumns.DISPLAY_NAME;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_ARTIST:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_ALBUM_NAME:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_ALBUM_ARTIST:
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Audio.AudioColumns.ALBUM_ARTIST;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_GENRE:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // genre requires a special query
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_COMPOSER:
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Audio.AudioColumns.COMPOSER;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case MtpConstants.PROPERTY_DESCRIPTION:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                column = Images.ImageColumns.DESCRIPTION;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_STR;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                type = MtpConstants.TYPE_UNDEFINED;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                Log.e(TAG, "unsupported property " + code);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (column != null) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            columns.add(column);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return new Property(code, type, columns.size() - 1);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return new Property(code, type, -1);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private String queryString(int id, String column) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor c = null;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // for now we are only reading properties from the "objects" table
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = mProvider.query(mUri,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            new String [] { Files.FileColumns._ID, column },
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ID_WHERE, new String[] { Integer.toString(id) }, null);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null && c.moveToNext()) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return c.getString(1);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return "";
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (Exception e) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return null;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c.close();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    private String queryAudio(int id, String column) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor c = null;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = mProvider.query(Audio.Media.getContentUri(mVolumeName),
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            new String [] { Files.FileColumns._ID, column },
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ID_WHERE, new String[] { Integer.toString(id) }, null);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null && c.moveToNext()) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return c.getString(1);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return "";
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (Exception e) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return null;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c.close();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private String queryGenre(int id) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor c = null;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = mProvider.query(uri,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            null, null, null);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null && c.moveToNext()) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return c.getString(1);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return "";
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (Exception e) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Log.e(TAG, "queryGenre exception", e);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return null;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c.close();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private Long queryLong(int id, String column) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor c = null;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // for now we are only reading properties from the "objects" table
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = mProvider.query(mUri,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            new String [] { Files.FileColumns._ID, column },
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ID_WHERE, new String[] { Integer.toString(id) }, null);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null && c.moveToNext()) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return new Long(c.getLong(1));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (Exception e) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c.close();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return null;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static String nameFromPath(String path) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // extract name from full path
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int start = 0;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int lastSlash = path.lastIndexOf('/');
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (lastSlash >= 0) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            start = lastSlash + 1;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int end = path.length();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (end - start > 255) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            end = start + 255;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return path.substring(start, end);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MtpPropertyList getPropertyList(int handle, int format, int depth, int storageID) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        //Log.d(TAG, "getPropertyList handle: " + handle + " format: " + format + " depth: " + depth);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (depth > 1) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // we only support depth 0 and 1
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // depth 0: single object, depth 1: immediate children
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        String where;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        String[] whereArgs;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (format == 0) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            whereArgs = new String[] { Integer.toString(handle) };
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (depth == 1) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                where = PARENT_WHERE;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                where = ID_WHERE;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            whereArgs = new String[] { Integer.toString(handle), Integer.toString(format) };
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (depth == 1) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                where = PARENT_FORMAT_WHERE;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                where = ID_FORMAT_WHERE;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor c = null;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // don't query if not necessary
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (depth > 0 || mColumns.length > 1) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c = mProvider.query(mUri, mColumns, where, whereArgs, null);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (c == null) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int count = (c == null ? 1 : c.getCount());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MtpPropertyList result = new MtpPropertyList(count * mProperties.length,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    MtpConstants.RESPONSE_OK);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // iterate over all objects in the query
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (int objectIndex = 0; objectIndex < count; objectIndex++) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (c != null) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    c.moveToNext();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (depth == 1) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    handle = (int)c.getLong(0);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // iterate over all properties in the query for the given object
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                for (int propertyIndex = 0; propertyIndex < mProperties.length; propertyIndex++) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Property property = mProperties[propertyIndex];
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int propertyCode = property.code;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int column = property.column;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    // handle some special cases
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    switch (propertyCode) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_STORAGE_ID:
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT32,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    storageID);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_PROTECTION_STATUS:
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // protection status is always 0
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // special case - need to extract file name from full path
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            String value = c.getString(column);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (value != null) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, nameFromPath(value));
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else {
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_NAME:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // first try title
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            String name = c.getString(column);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // then try name
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (name == null) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                name = queryString(handle, Audio.PlaylistsColumns.NAME);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // if title and name fail, extract name from full path
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (name == null) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                name = queryString(handle, Files.FileColumns.DATA);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if (name != null) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    name = nameFromPath(name);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (name != null) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, name);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_DATE_MODIFIED:
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_DATE_ADDED:
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // convert from seconds to DateTime
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, format_date_time(c.getInt(column)));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // release date is stored internally as just the year
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int year = c.getInt(column);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            String dateTime = Integer.toString(year) + "0101T000000";
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, dateTime);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_PERSISTENT_UID:
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            // PUID is concatenation of storageID and object handle
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            long puid = storageID;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            puid <<= 32;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            puid += handle;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT128, puid);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_TRACK:
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode, MtpConstants.TYPE_UINT16,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        c.getInt(column) % 1000);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_ARTIST:
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    queryAudio(handle, Audio.AudioColumns.ARTIST));
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_ALBUM_NAME:
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            result.append(handle, propertyCode,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    queryAudio(handle, Audio.AudioColumns.ALBUM));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case MtpConstants.PROPERTY_GENRE:
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            String genre = queryGenre(handle);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (genre != null) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, genre);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        default:
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (property.type == MtpConstants.TYPE_STR) {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, c.getString(column));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else if (property.type == MtpConstants.TYPE_UNDEFINED) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, property.type, 0);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                result.append(handle, propertyCode, property.type,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        c.getLong(column));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return result;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (RemoteException e) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return new MtpPropertyList(0, MtpConstants.RESPONSE_GENERAL_ERROR);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (c != null) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c.close();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // impossible to get here, so no return statement
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private native String format_date_time(long seconds);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)