MtpDatabaseConstants.java revision 3bb37e7ff0a7b0a8086007633ad927fec59a6e94
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 = 5;
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     * Table containing last boot count.
52     */
53    static final String TABLE_LAST_BOOT_COUNT = "LastBootCount";
54
55    /**
56     * 'FROM' closure of joining TABLE_DOCUMENTS and TABLE_ROOT_EXTRA.
57     */
58    static final String JOIN_ROOTS = createJoinFromClosure(
59            TABLE_DOCUMENTS,
60            TABLE_ROOT_EXTRA,
61            Document.COLUMN_DOCUMENT_ID,
62            Root.COLUMN_ROOT_ID);
63
64    static final String COLUMN_DEVICE_ID = "device_id";
65    static final String COLUMN_STORAGE_ID = "storage_id";
66    static final String COLUMN_OBJECT_HANDLE = "object_handle";
67    static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id";
68    static final String COLUMN_DOCUMENT_TYPE = "document_type";
69    static final String COLUMN_ROW_STATE = "row_state";
70    static final String COLUMN_MAPPING_KEY = "mapping_key";
71
72    /**
73     * Value for TABLE_LAST_BOOT_COUNT.
74     * Type: INTEGER
75     */
76    static final String COLUMN_VALUE = "value";
77
78    /**
79     * The state represents that the row has a valid object handle.
80     */
81    static final int ROW_STATE_VALID = 0;
82
83    /**
84     * The state represents that the rows added at the previous cycle and need to be updated with
85     * fresh values.
86     * The row may not have valid object handle. External application can still fetch the documents.
87     * If the external application tries to fetch object handle, the provider resolves pending
88     * documents with invalidated documents ahead.
89     */
90    static final int ROW_STATE_INVALIDATED = 1;
91
92    /**
93     * The documents are of device/storage that are disconnected now. The documents are invisible
94     * but their document ID will be reuse when the device/storage is connected again.
95     */
96    static final int ROW_STATE_DISCONNECTED = 2;
97
98    @IntDef(value = { DOCUMENT_TYPE_DEVICE, DOCUMENT_TYPE_STORAGE, DOCUMENT_TYPE_OBJECT })
99    @Retention(RetentionPolicy.SOURCE)
100    public @interface DocumentType {}
101
102    /**
103     * Document that represents a MTP device.
104     */
105    static final int DOCUMENT_TYPE_DEVICE = 0;
106
107    /**
108     * Document that represents a MTP storage.
109     */
110    static final int DOCUMENT_TYPE_STORAGE = 1;
111
112    /**
113     * Document that represents a MTP object.
114     */
115    static final int DOCUMENT_TYPE_OBJECT = 2;
116
117    static final String SELECTION_DOCUMENT_ID = Document.COLUMN_DOCUMENT_ID + " = ?";
118    static final String SELECTION_ROOT_ID = Root.COLUMN_ROOT_ID + " = ?";
119
120    static final String QUERY_CREATE_DOCUMENTS =
121            "CREATE TABLE " + TABLE_DOCUMENTS + " (" +
122            Document.COLUMN_DOCUMENT_ID +
123                " INTEGER PRIMARY KEY AUTOINCREMENT," +
124            COLUMN_DEVICE_ID + " INTEGER," +
125            COLUMN_STORAGE_ID + " INTEGER," +
126            COLUMN_OBJECT_HANDLE + " INTEGER," +
127            COLUMN_PARENT_DOCUMENT_ID + " INTEGER," +
128            COLUMN_ROW_STATE + " INTEGER NOT NULL," +
129            COLUMN_DOCUMENT_TYPE + " INTEGER NOT NULL," +
130            COLUMN_MAPPING_KEY + " STRING," +
131            Document.COLUMN_MIME_TYPE + " TEXT NOT NULL," +
132            Document.COLUMN_DISPLAY_NAME + " TEXT NOT NULL," +
133            Document.COLUMN_SUMMARY + " TEXT," +
134            Document.COLUMN_LAST_MODIFIED + " INTEGER," +
135            Document.COLUMN_ICON + " INTEGER," +
136            Document.COLUMN_FLAGS + " INTEGER NOT NULL," +
137            Document.COLUMN_SIZE + " INTEGER);";
138
139    static final String QUERY_CREATE_ROOT_EXTRA =
140            "CREATE TABLE " + TABLE_ROOT_EXTRA + " (" +
141            Root.COLUMN_ROOT_ID + " INTEGER PRIMARY KEY," +
142            Root.COLUMN_FLAGS + " INTEGER NOT NULL," +
143            Root.COLUMN_AVAILABLE_BYTES + " INTEGER," +
144            Root.COLUMN_CAPACITY_BYTES + " INTEGER," +
145            Root.COLUMN_MIME_TYPES + " TEXT NOT NULL);";
146
147    static final String QUERY_CREATE_LAST_BOOT_COUNT =
148            "CREATE TABLE " + TABLE_LAST_BOOT_COUNT + " (value INTEGER NOT NULL);";
149
150    /**
151     * Map for columns names to provide DocumentContract.Root compatible columns.
152     * @see SQLiteQueryBuilder#setProjectionMap(Map)
153     */
154    static final Map<String, String> COLUMN_MAP_ROOTS;
155    static {
156        COLUMN_MAP_ROOTS = new HashMap<>();
157        COLUMN_MAP_ROOTS.put(Root.COLUMN_ROOT_ID, TABLE_ROOT_EXTRA + "." + Root.COLUMN_ROOT_ID);
158        COLUMN_MAP_ROOTS.put(Root.COLUMN_FLAGS, TABLE_ROOT_EXTRA + "." + Root.COLUMN_FLAGS);
159        COLUMN_MAP_ROOTS.put(
160                Root.COLUMN_ICON,
161                TABLE_DOCUMENTS + "." + Document.COLUMN_ICON + " AS " + Root.COLUMN_ICON);
162        COLUMN_MAP_ROOTS.put(
163                Root.COLUMN_TITLE,
164                TABLE_DOCUMENTS + "." + Document.COLUMN_DISPLAY_NAME + " AS " + Root.COLUMN_TITLE);
165        COLUMN_MAP_ROOTS.put(
166                Root.COLUMN_SUMMARY,
167                TABLE_DOCUMENTS + "." + Document.COLUMN_SUMMARY + " AS " + Root.COLUMN_SUMMARY);
168        COLUMN_MAP_ROOTS.put(
169                Root.COLUMN_DOCUMENT_ID,
170                TABLE_DOCUMENTS + "." + Document.COLUMN_DOCUMENT_ID +
171                " AS " + Root.COLUMN_DOCUMENT_ID);
172        COLUMN_MAP_ROOTS.put(
173                Root.COLUMN_AVAILABLE_BYTES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_AVAILABLE_BYTES);
174        COLUMN_MAP_ROOTS.put(
175                Root.COLUMN_CAPACITY_BYTES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_CAPACITY_BYTES);
176        COLUMN_MAP_ROOTS.put(
177                Root.COLUMN_MIME_TYPES, TABLE_ROOT_EXTRA + "." + Root.COLUMN_MIME_TYPES);
178        COLUMN_MAP_ROOTS.put(COLUMN_DEVICE_ID, COLUMN_DEVICE_ID);
179    }
180
181    private static String createJoinFromClosure(
182            String table1, String table2, String column1, String column2) {
183        return table1 + " LEFT JOIN " + table2 +
184                " ON " + table1 + "." + column1 + " = " + table2 + "." + column2;
185    }
186}
187