1a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang/*
2a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * Copyright (C) 2017 The Android Open Source Project
3a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang *
4a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * Licensed under the Apache License, Version 2.0 (the "License");
5a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * you may not use this file except in compliance with the License.
6a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * You may obtain a copy of the License at
7a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang *
8a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang *      http://www.apache.org/licenses/LICENSE-2.0
9a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang *
10a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * Unless required by applicable law or agreed to in writing, software
11a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * distributed under the License is distributed on an "AS IS" BASIS,
12a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * See the License for the specific language governing permissions and
14a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * limitations under the License.
152078bc2358031ef3a191900d9036daf4251911c1Matthew Fritze *
16a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang */
17a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
182078bc2358031ef3a191900d9036daf4251911c1Matthew Fritzepackage com.android.settings.search;
19a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
20a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport android.content.ContentValues;
21a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport android.content.Context;
22a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport android.database.sqlite.SQLiteDatabase;
23a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport android.database.sqlite.SQLiteException;
24a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport android.util.Log;
25a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
26a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport com.android.settings.search.IndexDatabaseHelper;
27a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport com.android.settings.utils.AsyncLoader;
28a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
29a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangimport static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_SAVED_QUERIES;
30a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
31a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang/**
32a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang * A background task to update saved queries.
33a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang */
34a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhangpublic class SavedQueryRecorder extends AsyncLoader<Void> {
35a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
36a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    private static final String LOG_TAG = "SavedQueryRecorder";
37a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
38a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    // Max number of saved search queries (who will be used for proposing suggestions)
39a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    private static long MAX_SAVED_SEARCH_QUERY = 64;
40a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
41a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    private final String mQuery;
42a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
43a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    public SavedQueryRecorder(Context context, String query) {
44a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        super(context);
45a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        mQuery = query;
46a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    }
47a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
48a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    @Override
49a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    protected void onDiscardResult(Void result) {
50a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
51a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    }
52a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
53a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    @Override
54a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    public Void loadInBackground() {
55a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        final long now = System.currentTimeMillis();
56a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
57a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        final ContentValues values = new ContentValues();
58a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        values.put(IndexDatabaseHelper.SavedQueriesColumns.QUERY, mQuery);
59a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        values.put(IndexDatabaseHelper.SavedQueriesColumns.TIME_STAMP, now);
60a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
61a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        final SQLiteDatabase database = getWritableDatabase();
62a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        if (database == null) {
63a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            return null;
64a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        }
65a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
66a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        long lastInsertedRowId;
67a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        try {
68a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            // First, delete all saved queries that are the same
69a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            database.delete(TABLE_SAVED_QUERIES,
70a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                    IndexDatabaseHelper.SavedQueriesColumns.QUERY + " = ?",
71a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                    new String[]{mQuery});
72a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
73a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            // Second, insert the saved query
74a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            lastInsertedRowId = database.insertOrThrow(TABLE_SAVED_QUERIES, null, values);
75a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
76a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            // Last, remove "old" saved queries
77a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            final long delta = lastInsertedRowId - MAX_SAVED_SEARCH_QUERY;
78a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            if (delta > 0) {
79a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                int count = database.delete(TABLE_SAVED_QUERIES,
80a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                        "rowId <= ?",
81a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                        new String[]{Long.toString(delta)});
82a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang                Log.d(LOG_TAG, "Deleted '" + count + "' saved Search query(ies)");
83a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            }
84a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        } catch (Exception e) {
85a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            Log.d(LOG_TAG, "Cannot update saved Search queries", e);
86a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        }
87a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        return null;
88a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    }
89a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang
90a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    private SQLiteDatabase getWritableDatabase() {
91a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        try {
92a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            return IndexDatabaseHelper.getInstance(getContext()).getWritableDatabase();
93a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        } catch (SQLiteException e) {
94a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            Log.e(LOG_TAG, "Cannot open writable database", e);
95a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang            return null;
96a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang        }
97a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang    }
98a8b089db8a6d495a18dc3ad91d3bd84b042fb004Fan Zhang}
99