RecentsProvider.java revision b156f4bf8cdfe475a7116b627d84a281e1a281b7
1/*
2 * Copyright (C) 2013 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.documentsui;
18
19import android.content.ContentProvider;
20import android.content.ContentResolver;
21import android.content.ContentValues;
22import android.content.Context;
23import android.content.UriMatcher;
24import android.database.Cursor;
25import android.database.sqlite.SQLiteDatabase;
26import android.database.sqlite.SQLiteOpenHelper;
27import android.net.Uri;
28import android.text.format.DateUtils;
29import android.util.Log;
30
31public class RecentsProvider extends ContentProvider {
32    private static final String TAG = "RecentsProvider";
33
34    // TODO: offer view of recents that handles backend root resolution before
35    // returning cursor, include extra columns
36
37    public static final String AUTHORITY = "com.android.documentsui.recents";
38
39    private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
40
41    private static final int URI_RECENT_OPEN = 1;
42    private static final int URI_RECENT_CREATE = 2;
43    private static final int URI_RESUME = 3;
44
45    static {
46        sMatcher.addURI(AUTHORITY, "recent_open", URI_RECENT_OPEN);
47        sMatcher.addURI(AUTHORITY, "recent_create", URI_RECENT_CREATE);
48        sMatcher.addURI(AUTHORITY, "resume/*", URI_RESUME);
49    }
50
51    private static final String TABLE_RECENT_OPEN = "recent_open";
52    private static final String TABLE_RECENT_CREATE = "recent_create";
53    private static final String TABLE_RESUME = "resume";
54
55    /**
56     * String of URIs pointing at a storage backend, stored as a JSON array,
57     * starting with root.
58     */
59    public static final String COL_PATH = "path";
60    public static final String COL_URI = "uri";
61    public static final String COL_PACKAGE_NAME = "package_name";
62    public static final String COL_TIMESTAMP = "timestamp";
63
64    public static Uri buildRecentOpen() {
65        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
66                .authority(AUTHORITY).appendPath("recent_open").build();
67    }
68
69    public static Uri buildRecentCreate() {
70        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
71                .authority(AUTHORITY).appendPath("recent_create").build();
72    }
73
74    public static Uri buildResume(String packageName) {
75        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
76                .authority(AUTHORITY).appendPath("resume").appendPath(packageName).build();
77    }
78
79    private DatabaseHelper mHelper;
80
81    private static class DatabaseHelper extends SQLiteOpenHelper {
82        private static final String DB_NAME = "recents.db";
83
84        private static final int VERSION_INIT = 1;
85
86        public DatabaseHelper(Context context) {
87            super(context, DB_NAME, null, VERSION_INIT);
88        }
89
90        @Override
91        public void onCreate(SQLiteDatabase db) {
92            db.execSQL("CREATE TABLE " + TABLE_RECENT_OPEN + " (" +
93                    COL_URI + " TEXT PRIMARY KEY ON CONFLICT REPLACE," +
94                    COL_TIMESTAMP + " INTEGER" +
95                    ")");
96
97            db.execSQL("CREATE TABLE " + TABLE_RECENT_CREATE + " (" +
98                    COL_PATH + " TEXT PRIMARY KEY ON CONFLICT REPLACE," +
99                    COL_TIMESTAMP + " INTEGER" +
100                    ")");
101
102            db.execSQL("CREATE TABLE " + TABLE_RESUME + " (" +
103                    COL_PACKAGE_NAME + " TEXT PRIMARY KEY ON CONFLICT REPLACE," +
104                    COL_PATH + " TEXT," +
105                    COL_TIMESTAMP + " INTEGER" +
106                    ")");
107        }
108
109        @Override
110        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
111            Log.w(TAG, "Upgrading database; wiping app data");
112            db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECENT_OPEN);
113            db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECENT_CREATE);
114            db.execSQL("DROP TABLE IF EXISTS " + TABLE_RESUME);
115            onCreate(db);
116        }
117    }
118
119    @Override
120    public boolean onCreate() {
121        mHelper = new DatabaseHelper(getContext());
122        return true;
123    }
124
125    @Override
126    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
127            String sortOrder) {
128        final SQLiteDatabase db = mHelper.getReadableDatabase();
129        switch (sMatcher.match(uri)) {
130            case URI_RECENT_OPEN: {
131                return db.query(TABLE_RECENT_OPEN, projection,
132                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
133            }
134            case URI_RECENT_CREATE: {
135                return db.query(TABLE_RECENT_CREATE, projection,
136                        buildWhereYounger(DateUtils.WEEK_IN_MILLIS), null, null, null, sortOrder);
137            }
138            case URI_RESUME: {
139                final String packageName = uri.getPathSegments().get(1);
140                return db.query(TABLE_RESUME, projection, COL_PACKAGE_NAME + "=?",
141                        new String[] { packageName }, null, null, null);
142            }
143            default: {
144                throw new UnsupportedOperationException("Unsupported Uri " + uri);
145            }
146        }
147    }
148
149    @Override
150    public String getType(Uri uri) {
151        return null;
152    }
153
154    @Override
155    public Uri insert(Uri uri, ContentValues values) {
156        final SQLiteDatabase db = mHelper.getWritableDatabase();
157        switch (sMatcher.match(uri)) {
158            case URI_RECENT_OPEN: {
159                values.put(COL_TIMESTAMP, System.currentTimeMillis());
160                db.insert(TABLE_RECENT_OPEN, null, values);
161                db.delete(TABLE_RECENT_OPEN, buildWhereOlder(DateUtils.WEEK_IN_MILLIS), null);
162                return uri;
163            }
164            case URI_RECENT_CREATE: {
165                values.put(COL_TIMESTAMP, System.currentTimeMillis());
166                db.insert(TABLE_RECENT_CREATE, null, values);
167                db.delete(TABLE_RECENT_CREATE, buildWhereOlder(DateUtils.WEEK_IN_MILLIS), null);
168                return uri;
169            }
170            case URI_RESUME: {
171                final String packageName = uri.getPathSegments().get(1);
172                values.put(COL_PACKAGE_NAME, packageName);
173                values.put(COL_TIMESTAMP, System.currentTimeMillis());
174                db.insert(TABLE_RESUME, null, values);
175                return uri;
176            }
177            default: {
178                throw new UnsupportedOperationException("Unsupported Uri " + uri);
179            }
180        }
181    }
182
183    @Override
184    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
185        throw new UnsupportedOperationException("Unsupported Uri " + uri);
186    }
187
188    @Override
189    public int delete(Uri uri, String selection, String[] selectionArgs) {
190        throw new UnsupportedOperationException("Unsupported Uri " + uri);
191    }
192
193    private static String buildWhereOlder(long deltaMillis) {
194        return COL_TIMESTAMP + "<" + (System.currentTimeMillis() - deltaMillis);
195    }
196
197    private static String buildWhereYounger(long deltaMillis) {
198        return COL_TIMESTAMP + ">" + (System.currentTimeMillis() - deltaMillis);
199    }
200}
201