MtpDatabaseConstants.java revision 9fca541ab8acb06bb390319251526fa9807b846f
1/*
2 * Copyright (C) 2015 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
17package com.android.mtp;
18
19import android.annotation.IntDef;
20import android.database.sqlite.SQLiteQueryBuilder;
21import android.provider.DocumentsContract.Document;
22import android.provider.DocumentsContract.Root;
23
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26import java.util.HashMap;
27import java.util.Map;
28
29/**
30 * Class containing MtpDatabase constants.
31 */
32class MtpDatabaseConstants {
33    static final int DATABASE_VERSION = 1;
34    static final String DATABASE_NAME = "database";
35
36    static final int FLAG_DATABASE_IN_MEMORY = 1;
37    static final int FLAG_DATABASE_IN_FILE = 0;
38
39    /**
40     * Table representing documents including root documents.
41     */
42    static final String TABLE_DOCUMENTS = "Documents";
43
44    /**
45     * Table containing additional information only available for root documents.
46     * The table uses same primary keys with corresponding documents.
47     */
48    static final String TABLE_ROOT_EXTRA = "RootExtra";
49
50    /**
51     * 'FROM' closure of joining TABLE_DOCUMENTS and TABLE_ROOT_EXTRA.
52     */
53    static final String JOIN_ROOTS = createJoinFromClosure(
54            TABLE_DOCUMENTS,
55            TABLE_ROOT_EXTRA,
56            Document.COLUMN_DOCUMENT_ID,
57            Root.COLUMN_ROOT_ID);
58
59    static final String COLUMN_DEVICE_ID = "device_id";
60    static final String COLUMN_STORAGE_ID = "storage_id";
61    static final String COLUMN_OBJECT_HANDLE = "object_handle";
62    static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id";
63    static final String COLUMN_DOCUMENT_TYPE = "document_type";
64    static final String COLUMN_ROW_STATE = "row_state";
65
66    /**
67     * The state represents that the row has a valid object handle.
68     */
69    static final int ROW_STATE_VALID = 0;
70
71    /**
72     * The state represents that the rows added at the previous cycle and need to be updated with
73     * fresh values.
74     * The row may not have valid object handle. External application can still fetch the documents.
75     * If the external application tries to fetch object handle, the provider resolves pending
76     * documents with invalidated documents ahead.
77     */
78    static final int ROW_STATE_INVALIDATED = 1;
79
80    /**
81     * Mapping mode that uses MTP identifier to find corresponding rows.
82     */
83    static final int MAP_BY_MTP_IDENTIFIER = 0;
84
85    /**
86     * Mapping mode that uses name to find corresponding rows.
87     */
88    static final int MAP_BY_NAME = 1;
89
90    @IntDef(value = { DOCUMENT_TYPE_DEVICE, DOCUMENT_TYPE_STORAGE, DOCUMENT_TYPE_OBJECT })
91    @Retention(RetentionPolicy.SOURCE)
92    public @interface DocumentType {}
93
94    /**
95     * Document that represents a MTP device.
96     */
97    static final int DOCUMENT_TYPE_DEVICE = 0;
98
99    /**
100     * Document that represents a MTP storage.
101     */
102    static final int DOCUMENT_TYPE_STORAGE = 1;
103
104    /**
105     * Document that represents a MTP object.
106     */
107    static final int DOCUMENT_TYPE_OBJECT = 2;
108
109    static final String SELECTION_DOCUMENT_ID = Document.COLUMN_DOCUMENT_ID + " = ?";
110    static final String SELECTION_ROOT_ID = Root.COLUMN_ROOT_ID + " = ?";
111
112    static final String QUERY_CREATE_DOCUMENTS =
113            "CREATE TABLE " + TABLE_DOCUMENTS + " (" +
114            Document.COLUMN_DOCUMENT_ID +
115                " INTEGER PRIMARY KEY AUTOINCREMENT," +
116            COLUMN_DEVICE_ID + " INTEGER NOT NULL," +
117            COLUMN_STORAGE_ID + " INTEGER," +
118            COLUMN_OBJECT_HANDLE + " INTEGER," +
119            COLUMN_PARENT_DOCUMENT_ID + " INTEGER," +
120            COLUMN_ROW_STATE + " INTEGER NOT NULL," +
121            COLUMN_DOCUMENT_TYPE + " INTEGER NOT NULL," +
122            Document.COLUMN_MIME_TYPE + " TEXT," +
123            Document.COLUMN_DISPLAY_NAME + " TEXT NOT NULL," +
124            Document.COLUMN_SUMMARY + " TEXT," +
125            Document.COLUMN_LAST_MODIFIED + " INTEGER," +
126            Document.COLUMN_ICON + " INTEGER," +
127            Document.COLUMN_FLAGS + " INTEGER NOT NULL," +
128            Document.COLUMN_SIZE + " INTEGER);";
129
130    static final String QUERY_CREATE_ROOT_EXTRA =
131            "CREATE TABLE " + TABLE_ROOT_EXTRA + " (" +
132            Root.COLUMN_ROOT_ID + " INTEGER PRIMARY KEY," +
133            Root.COLUMN_FLAGS + " INTEGER NOT NULL," +
134            Root.COLUMN_AVAILABLE_BYTES + " INTEGER," +
135            Root.COLUMN_CAPACITY_BYTES + " INTEGER," +
136            Root.COLUMN_MIME_TYPES + " TEXT NOT NULL);";
137
138    /**
139     * Map for columns names to provide DocumentContract.Root compatible columns.
140     * @see SQLiteQueryBuilder#setProjectionMap(Map)
141     */
142    static final Map<String, String> COLUMN_MAP_ROOTS;
143    static {
144        COLUMN_MAP_ROOTS = new HashMap<>();
145        COLUMN_MAP_ROOTS.put(Root.COLUMN_ROOT_ID, TABLE_ROOT_EXTRA + "." + Root.COLUMN_ROOT_ID);
146        COLUMN_MAP_ROOTS.put(Root.COLUMN_FLAGS, TABLE_ROOT_EXTRA + "." + Root.COLUMN_FLAGS);
147        COLUMN_MAP_ROOTS.put(
148                Root.COLUMN_ICON,
149                TABLE_DOCUMENTS + "." + Document.COLUMN_ICON + " AS " + Root.COLUMN_ICON);
150        COLUMN_MAP_ROOTS.put(
151                Root.COLUMN_TITLE,
152                TABLE_DOCUMENTS + "." + Document.COLUMN_DISPLAY_NAME + " AS " + Root.COLUMN_TITLE);
153        COLUMN_MAP_ROOTS.put(
154                Root.COLUMN_SUMMARY,
155                TABLE_DOCUMENTS + "." + Document.COLUMN_SUMMARY + " AS " + Root.COLUMN_SUMMARY);
156        COLUMN_MAP_ROOTS.put(
157                Root.COLUMN_DOCUMENT_ID,
158                TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID +
159                " AS " + Root.COLUMN_DOCUMENT_ID);
160        COLUMN_MAP_ROOTS.put(
161                Root.COLUMN_AVAILABLE_BYTES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_AVAILABLE_BYTES);
162        COLUMN_MAP_ROOTS.put(
163                Root.COLUMN_CAPACITY_BYTES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_CAPACITY_BYTES);
164        COLUMN_MAP_ROOTS.put(
165                Root.COLUMN_MIME_TYPES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_MIME_TYPES);
166        COLUMN_MAP_ROOTS.put(COLUMN_DEVICE_ID, COLUMN_DEVICE_ID);
167    }
168
169    private static String createJoinFromClosure(
170            String table1, String table2, String column1, String column2) {
171        return table1 + " INNER JOIN " + table2 +
172                " ON " + table1 + "." + column1 + " = " + table2 + "." + column2;
173    }
174}
175