Index.java revision caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275f
16f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio/*
26f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * Copyright (C) 2014 The Android Open Source Project
36f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio *
46f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
56f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * you may not use this file except in compliance with the License.
66f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * You may obtain a copy of the License at
76f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio *
86f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
96f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio *
106f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
116f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
126f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * See the License for the specific language governing permissions and
146f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio * limitations under the License.
156f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio */
166f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
17fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Megliopackage com.android.settings.search;
186f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
19fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.content.ContentResolver;
206f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.content.ContentValues;
216f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.content.Context;
22fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.content.Intent;
23b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglioimport android.content.pm.ApplicationInfo;
24b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglioimport android.content.pm.PackageInfo;
25fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.content.pm.PackageManager;
26fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.content.pm.ResolveInfo;
276f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.content.res.TypedArray;
286f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.content.res.XmlResourceParser;
296f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.database.Cursor;
306f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.database.DatabaseUtils;
316f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.database.sqlite.SQLiteDatabase;
32fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.net.Uri;
336f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.os.AsyncTask;
34fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.provider.SearchIndexableData;
35fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.provider.SearchIndexableResource;
36fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport android.provider.SearchIndexablesContract;
376f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.text.TextUtils;
386f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.util.AttributeSet;
396f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.util.Log;
406f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.util.TypedValue;
416f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport android.util.Xml;
426f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport com.android.settings.R;
436f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport org.xmlpull.v1.XmlPullParser;
446f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport org.xmlpull.v1.XmlPullParserException;
456f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
466f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.io.IOException;
47b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglioimport java.lang.reflect.Field;
486f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.util.ArrayList;
4945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglioimport java.util.Collections;
506f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.util.List;
516f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.util.Locale;
526f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.util.concurrent.ExecutionException;
536f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglioimport java.util.concurrent.atomic.AtomicBoolean;
546f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
55b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_RANK;
56b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE;
57b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON;
58b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF;
59b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES;
60b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS;
61b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE;
62b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME;
63b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID;
64b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION;
65b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE;
66b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS;
67b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY;
68b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio
69b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK;
70b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID;
71b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
72b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
73b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
74b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE;
75b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglioimport static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS;
76b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio
77fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport static com.android.settings.search.IndexDatabaseHelper.Tables;
78fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglioimport static com.android.settings.search.IndexDatabaseHelper.IndexColumns;
796f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
806f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Megliopublic class Index {
816f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
82b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    private static final String LOG_TAG = "Index";
836f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
846f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    // Those indices should match the indices of SELECT_COLUMNS !
857d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_RANK = 0;
866f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    public static final int COLUMN_INDEX_TITLE = 1;
879593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    public static final int COLUMN_INDEX_SUMMARY_ON = 2;
889593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    public static final int COLUMN_INDEX_SUMMARY_OFF = 3;
89a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    public static final int COLUMN_INDEX_ENTRIES = 4;
907d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_KEYWORDS = 5;
917d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_CLASS_NAME = 6;
927d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_SCREEN_TITLE = 7;
937d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_ICON = 8;
947d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_INTENT_ACTION = 9;
957d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 10;
967d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 11;
977d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_ENABLED = 12;
987d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio    public static final int COLUMN_INDEX_KEY = 13;
996f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
1006f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    // If you change the order of columns here, you SHOULD change the COLUMN_INDEX_XXX values
1016f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private static final String[] SELECT_COLUMNS = new String[] {
1029593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_RANK,               // 0
1039593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_TITLE,              // 1
1049593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_ON,         // 2
1059593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_OFF,        // 3
106a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            IndexColumns.DATA_ENTRIES,            // 4
1077d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.DATA_KEYWORDS,           // 5
1087d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.CLASS_NAME,              // 6
1097d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.SCREEN_TITLE,            // 7
1107d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.ICON,                    // 8
1117d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.INTENT_ACTION,           // 9
1127d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.INTENT_TARGET_PACKAGE,   // 10
1137d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.INTENT_TARGET_CLASS,     // 11
1147d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.ENABLED,                 // 12
1157d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            IndexColumns.DATA_KEY_REF             // 13
1166f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    };
1176f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
1180d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    private static final String[] MATCH_COLUMNS = {
1190d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            IndexColumns.DATA_TITLE,
120489362c83c11f7d531c8c0c08c285499cd2b3869Fabrice Di Meglio            IndexColumns.DATA_TITLE_NORMALIZED,
1219593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_ON,
1229593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_ON_NORMALIZED,
1239593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_OFF,
1249593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            IndexColumns.DATA_SUMMARY_OFF_NORMALIZED,
125a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            IndexColumns.DATA_ENTRIES,
1260d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            IndexColumns.DATA_KEYWORDS
1270d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    };
1280d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio
1296f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private static final String EMPTY = "";
1306f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private static final String NON_BREAKING_HYPHEN = "\u2011";
1316f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private static final String HYPHEN = "-";
1326f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
1339593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
1349593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            "SEARCH_INDEX_DATA_PROVIDER";
1359593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
1369593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen";
1379593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference";
138a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference";
1399593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
14045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio    private static final List<String> EMPTY_LIST = Collections.<String>emptyList();
14145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
1426f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private static Index sInstance;
1436f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private final AtomicBoolean mIsAvailable = new AtomicBoolean(false);
14451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private final UpdateData mDataToProcess = new UpdateData();
145d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio    private Context mContext;
146b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
14751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    /**
14851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio     * A private class to describe the update data for the Index database
14951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio     */
15051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private class UpdateData {
15151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        public List<SearchIndexableData> dataToUpdate;
15251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        public List<String> dataToDelete;
15351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        public boolean forceUpdate = false;
1546f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
15551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        public UpdateData() {
15651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            dataToUpdate = new ArrayList<SearchIndexableData>();
15751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            dataToDelete = new ArrayList<String>();
15851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
15951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
16051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        public void clear() {
16151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            dataToUpdate.clear();
16251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            dataToDelete.clear();
16351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            forceUpdate = false;
16451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
16551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
1666f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
1676f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    /**
1686f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio     * A basic singleton
1696f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio     */
1706f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    public static Index getInstance(Context context) {
1716f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        if (sInstance == null) {
1726f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            sInstance = new Index(context);
173d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        } else {
174d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio            sInstance.setContext(context);
1756f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
1766f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        return sInstance;
1776f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
1786f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
1796f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    public Index(Context context) {
1806f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        mContext = context;
1816f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
1826f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
183d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio    public void setContext(Context context) {
184d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        mContext = context;
185d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio    }
186d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio
1876f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    public boolean isAvailable() {
1886f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        return mIsAvailable.get();
1896f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
1906f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
19151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    public Cursor search(String query) {
19251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final String sql = buildSQL(query);
19351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        Log.d(LOG_TAG, "Query: " + sql);
19451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return getReadableDatabase().rawQuery(sql, null);
19551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
19651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
197fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    public void addIndexableData(SearchIndexableData data) {
19851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        synchronized (mDataToProcess) {
19951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            mDataToProcess.dataToUpdate.add(data);
200fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
201fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
202fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
203fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    public void addIndexableData(SearchIndexableResource[] array) {
20451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        synchronized (mDataToProcess) {
205b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final int count = array.length;
206b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            for (int n = 0; n < count; n++) {
20751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                mDataToProcess.dataToUpdate.add(array[n]);
208b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            }
209b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
210b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    }
211b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
212b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    public void deleteIndexableData(String[] array) {
21351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        synchronized (mDataToProcess) {
214b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final int count = array.length;
215b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            for (int n = 0; n < count; n++) {
21651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                mDataToProcess.dataToDelete.add(array[n]);
217b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            }
218b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
219b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    }
220b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
221b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    public boolean update() {
222fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
223fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        List<ResolveInfo> list =
224fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                mContext.getPackageManager().queryIntentContentProviders(intent, 0);
225fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
226fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        final int size = list.size();
227fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        for (int n = 0; n < size; n++) {
228fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            final ResolveInfo info = list.get(n);
229b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            if (!isWellKnownProvider(info)) {
230b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio                continue;
231b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            }
232fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            final String authority = info.providerInfo.authority;
233fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            final String packageName = info.providerInfo.packageName;
23451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            addIndexablesFromRemoteProvider(packageName, authority);
23551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
23651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
23751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return updateInternal();
23851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
23951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
240b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio    /**
241b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio     * Only allow a "well known" SearchIndexablesProvider. The provider should:
242b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio     *
243b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio     * - have read/write {@link android.Manifest.permission#READ_SEARCH_INDEXABLES}
244b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio     * - be from a privileged package
245b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio     */
246b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio    private boolean isWellKnownProvider(ResolveInfo info) {
247b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        final String authority = info.providerInfo.authority;
248b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        final String packageName = info.providerInfo.applicationInfo.packageName;
249b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
250b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) {
251b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            return false;
252b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        }
253b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
254b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        final String readPermission = info.providerInfo.readPermission;
255b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        final String writePermission = info.providerInfo.writePermission;
256b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
257b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) {
258b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            return false;
259b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        }
260b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
261b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) ||
262b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) {
263b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            return false;
264b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        }
265b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
266b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        return isPrivilegedPackage(packageName);
267b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio    }
268b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
269b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio    private boolean isPrivilegedPackage(String packageName) {
270b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        final PackageManager pm = mContext.getPackageManager();
271b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        try {
272b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            PackageInfo packInfo = pm.getPackageInfo(packageName, 0);
273b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            return ((packInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0);
274b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        } catch (PackageManager.NameNotFoundException e) {
275b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio            return false;
276b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio        }
277b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio    }
278b1648e6c546523cd3ede111c6b494a96477de2f1Fabrice Di Meglio
27951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    public boolean updateFromRemoteProvider(String packageName, String authority) {
28051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (!addIndexablesFromRemoteProvider(packageName, authority)) {
28151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return false;
28251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
28351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return updateInternal();
28451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
28551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
28651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    public boolean updateFromClassNameResource(String className, boolean includeInSearchResults) {
28751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (className == null) {
28851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            throw new IllegalArgumentException("class name cannot be null!");
28951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
29051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final SearchIndexableResource res = SearchIndexableResources.getResourceByName(className);
29151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (res == null ) {
29251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Log.e(LOG_TAG, "Cannot find SearchIndexableResources for class name: " + className);
29351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return false;
294fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
29551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        res.enabled = includeInSearchResults;
29651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        addIndexableData(res);
29751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        mDataToProcess.forceUpdate = true;
29851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        boolean result = updateInternal();
29951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        res.enabled = false;
30051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return result;
30151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
302fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
3033b2269567004d47a287e3fc7a711557802424c54Fabrice Di Meglio    public boolean updateFromSearchIndexableData(SearchIndexableData data) {
30451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        addIndexableData(data);
3053b2269567004d47a287e3fc7a711557802424c54Fabrice Di Meglio        mDataToProcess.forceUpdate = true;
306fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        return updateInternal();
307fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
308fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
30951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private SQLiteDatabase getReadableDatabase() {
31051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return IndexDatabaseHelper.getInstance(mContext).getReadableDatabase();
31151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
31251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
31351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private SQLiteDatabase getWritableDatabase() {
31451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return IndexDatabaseHelper.getInstance(mContext).getWritableDatabase();
31551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
31651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
31751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private boolean addIndexablesFromRemoteProvider(String packageName, String authority) {
31851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final Context packageContext;
31951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        try {
32051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            packageContext = mContext.createPackageContext(packageName, 0);
32151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
32251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final Uri uriForResources = buildUriForXmlResources(authority);
32351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            addIndexablesForXmlResourceUri(packageContext, packageName, uriForResources,
32451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS);
32551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
32651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final Uri uriForRawData = buildUriForRawData(authority);
32751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            addIndexablesForRawDataUri(packageContext, packageName, uriForRawData,
32851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    SearchIndexablesContract.INDEXABLES_RAW_COLUMNS);
32951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return true;
33051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (PackageManager.NameNotFoundException e) {
33151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Log.w(LOG_TAG, "Could not create context for " + packageName + ": "
33251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    + Log.getStackTraceString(e));
33351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return false;
33451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
33551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
33651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
337fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    private static Uri buildUriForXmlResources(String authority) {
338fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        return Uri.parse("content://" + authority + "/" +
339fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                SearchIndexablesContract.INDEXABLES_XML_RES_PATH);
340fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
341fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
342fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    private static Uri buildUriForRawData(String authority) {
343fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        return Uri.parse("content://" + authority + "/" +
344fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                SearchIndexablesContract.INDEXABLES_RAW_PATH);
345fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
346fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
34751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private boolean updateInternal() {
34851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        synchronized (mDataToProcess) {
34951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final UpdateIndexTask task = new UpdateIndexTask();
35051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            task.execute(mDataToProcess);
35151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            try {
35251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                final boolean result = task.get();
35351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                mDataToProcess.clear();
35451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                return result;
35551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            } catch (InterruptedException e) {
35651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
35751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                return false;
35851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            } catch (ExecutionException e) {
35951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                Log.e(LOG_TAG, "Cannot update index: " + e.getMessage());
36051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                return false;
36151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
36251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
36351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
364fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
36551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void addIndexablesForXmlResourceUri(Context packageContext, String packageName,
36651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Uri uri, String[] projection) {
36751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
36851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final ContentResolver resolver = packageContext.getContentResolver();
369fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        final Cursor cursor = resolver.query(uri, projection,
370fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                null, null, null);
371fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
372fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        if (cursor == null) {
373fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString());
374fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            return;
375fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
376fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
377fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        try {
378fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            final int count = cursor.getCount();
379fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            if (count > 0) {
380fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                while (cursor.moveToNext()) {
381b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final int rank = cursor.getInt(COLUMN_INDEX_XML_RES_RANK);
382b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final int xmlResId = cursor.getInt(COLUMN_INDEX_XML_RES_RESID);
383fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
384b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String className = cursor.getString(COLUMN_INDEX_XML_RES_CLASS_NAME);
385b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final int iconResId = cursor.getInt(COLUMN_INDEX_XML_RES_ICON_RESID);
386fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
387b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String action = cursor.getString(COLUMN_INDEX_XML_RES_INTENT_ACTION);
388b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String targetPackage = cursor.getString(
389b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                            COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE);
390b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String targetClass = cursor.getString(
391b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                            COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS);
392fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
3935135dce1429facfd764f4afffe69d60c19589750Fabrice Di Meglio                    SearchIndexableResource sir = new SearchIndexableResource(packageContext);
394fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.rank = rank;
395fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.xmlResId = xmlResId;
396fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.className = className;
397fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.packageName = packageName;
398fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.iconResId = iconResId;
399fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.intentAction = action;
400fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.intentTargetPackage = targetPackage;
401fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    sir.intentTargetClass = targetClass;
402fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
403fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    addIndexableData(sir);
404fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                }
405fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            }
406fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        } finally {
407fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            cursor.close();
408fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
409fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
410fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
41151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void addIndexablesForRawDataUri(Context packageContext, String packageName,
41251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Uri uri, String[] projection) {
413fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
41451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final ContentResolver resolver = packageContext.getContentResolver();
415fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        final Cursor cursor = resolver.query(uri, projection,
416fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                null, null, null);
417fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
418fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        if (cursor == null) {
419fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString());
420fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            return;
421fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
422fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
423fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        try {
424fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            final int count = cursor.getCount();
425fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            if (count > 0) {
426fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                while (cursor.moveToNext()) {
427b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final int rank = cursor.getInt(COLUMN_INDEX_RAW_RANK);
428b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String title = cursor.getString(COLUMN_INDEX_RAW_TITLE);
429b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String summaryOn = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_ON);
430b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String summaryOff = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_OFF);
431b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String entries = cursor.getString(COLUMN_INDEX_RAW_ENTRIES);
432b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String keywords = cursor.getString(COLUMN_INDEX_RAW_KEYWORDS);
433fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
434b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String screenTitle = cursor.getString(COLUMN_INDEX_RAW_SCREEN_TITLE);
435fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
436b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String className = cursor.getString(COLUMN_INDEX_RAW_CLASS_NAME);
437b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final int iconResId = cursor.getInt(COLUMN_INDEX_RAW_ICON_RESID);
438fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
439b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String action = cursor.getString(COLUMN_INDEX_RAW_INTENT_ACTION);
440b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String targetPackage = cursor.getString(
441b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                            COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE);
442b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String targetClass = cursor.getString(
443b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                            COLUMN_INDEX_RAW_INTENT_TARGET_CLASS);
444fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
445b914322590d74b508ff94b4426cb4b11a324e72cFabrice Di Meglio                    final String key = cursor.getString(COLUMN_INDEX_RAW_KEY);
446c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio
4475135dce1429facfd764f4afffe69d60c19589750Fabrice Di Meglio                    SearchIndexableRaw data = new SearchIndexableRaw(packageContext);
448fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.rank = rank;
449fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.title = title;
4509593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    data.summaryOn = summaryOn;
4519593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    data.summaryOff = summaryOff;
452a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                    data.entries = entries;
453fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.keywords = keywords;
454fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.screenTitle = screenTitle;
455fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.className = className;
456fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.packageName = packageName;
457fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.iconResId = iconResId;
458fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.intentAction = action;
459fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.intentTargetPackage = targetPackage;
460fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    data.intentTargetClass = targetClass;
461c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                    data.key = key;
462fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
463fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                    addIndexableData(data);
464fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio                }
465fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            }
466fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        } finally {
467fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio            cursor.close();
468fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
469fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio    }
470fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
4716f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    private String buildSQL(String query) {
4726f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        StringBuilder sb = new StringBuilder();
4730d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        sb.append(buildSQLForColumn(query, MATCH_COLUMNS));
4746f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" ORDER BY ");
4756f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(IndexColumns.DATA_RANK);
4766f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        return sb.toString();
4776f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
4786f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
4790d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    private String buildSQLForColumn(String query, String[] columnNames) {
4806f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        StringBuilder sb = new StringBuilder();
4816f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append("SELECT ");
4826f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        for (int n = 0; n < SELECT_COLUMNS.length; n++) {
4836f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            sb.append(SELECT_COLUMNS[n]);
4846f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            if (n < SELECT_COLUMNS.length - 1) {
4856f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                sb.append(", ");
4866f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            }
4876f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
4886f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" FROM ");
4896f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(Tables.TABLE_PREFS_INDEX);
4906f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" WHERE ");
4910d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        sb.append(buildWhereStringForColumns(query, columnNames));
4926f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
4936f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        return sb.toString();
4946f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
4956f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
4960d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    private String buildWhereStringForColumns(String query, String[] columnNames) {
4970d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        final StringBuilder sb = new StringBuilder(Tables.TABLE_PREFS_INDEX);
4986f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" MATCH ");
4990d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        DatabaseUtils.appendEscapedSQLString(sb, buildMatchStringForColumns(query, columnNames));
5006f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" AND ");
5016f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(IndexColumns.LOCALE);
5026f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        sb.append(" = ");
5036f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        DatabaseUtils.appendEscapedSQLString(sb, Locale.getDefault().toString());
50451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        sb.append(" AND ");
50551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        sb.append(IndexColumns.ENABLED);
50651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        sb.append(" = 1");
5076f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        return sb.toString();
5086f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
5096f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
5100d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    private String buildMatchStringForColumns(String query, String[] columnNames) {
5110d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        final String value = query + "*";
5120d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        StringBuilder sb = new StringBuilder();
5130d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        final int count = columnNames.length;
5140d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        for (int n = 0; n < count; n++) {
5150d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            sb.append(columnNames[n]);
5160d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            sb.append(":");
5170d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            sb.append(value);
5180d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            if (n < count - 1) {
5190d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio                sb.append(" OR ");
5200d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio            }
5210d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        }
5220d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio        return sb.toString();
5230d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio    }
5240d4005a1c755c4233bdf75d30a1b6ebc99856ec7Fabrice Di Meglio
52551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr,
52651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                                             SearchIndexableData data) {
52751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (data instanceof SearchIndexableResource) {
52851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            indexOneResource(database, localeStr, (SearchIndexableResource) data);
52951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } else if (data instanceof SearchIndexableRaw) {
53051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            indexOneRaw(database, localeStr, (SearchIndexableRaw) data);
53151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
5326f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
5336f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
53451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void indexOneResource(SQLiteDatabase database, String localeStr,
53551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                                  SearchIndexableResource sir) {
53645f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
53745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        if (sir == null) {
53845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            Log.e(LOG_TAG, "Cannot index a null resource!");
53945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            return;
54045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        }
54145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
54245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        // Will be non null only for a Local provider
54345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        final Indexable.SearchIndexProvider provider =
54445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                TextUtils.isEmpty(sir.className) ? null : getSearchIndexProvider(sir.className);
54545f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
546a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) {
54745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            List<String> doNotIndexKeys = EMPTY_LIST;
54845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            if (provider != null) {
54945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                doNotIndexKeys = provider.getNonIndexableKeys(sir.context);
55045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            }
55151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            indexFromResource(sir.context, database, localeStr,
55251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    sir.xmlResId, sir.className, sir.iconResId, sir.rank,
55345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                    sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass,
55445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                    doNotIndexKeys);
55551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } else if (!TextUtils.isEmpty(sir.className)) {
55645f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            indexFromLocalProvider(mContext, database, localeStr, provider, sir.className,
55745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                    sir.iconResId, sir.rank, sir.enabled);
55851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
5596f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
5606f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
56151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void indexFromResource(Context context, SQLiteDatabase database, String localeStr,
56245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio           int xmlResId, String fragmentName, int iconResId, int rank,
56345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio           String intentAction, String intentTargetPackage, String intentTargetClass,
56445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio           List<String> doNotIndexKeys) {
565b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
56651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        XmlResourceParser parser = null;
56751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        try {
56851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            parser = context.getResources().getXml(xmlResId);
56951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
57051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            int type;
57151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
57251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    && type != XmlPullParser.START_TAG) {
57351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                // Parse next until start tag is found
57451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
57551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
57651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            String nodeName = parser.getName();
5779593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            if (!NODE_NAME_PREFERENCE_SCREEN.equals(nodeName)) {
57851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                throw new RuntimeException(
57951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                        "XML document must start with <PreferenceScreen> tag; found"
58051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                                + nodeName + " at " + parser.getPositionDescription());
58151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
58251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
58351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final int outerDepth = parser.getDepth();
58451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final AttributeSet attrs = Xml.asAttributeSet(parser);
58545f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
58651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final String screenTitle = getDataTitle(context, attrs);
58751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
588c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio            String key = getDataKey(context, attrs);
58951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
59045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            String title;
59145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            String summary;
59245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            String keywords;
59345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
59451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            // Insert rows for the main PreferenceScreen node. Rewrite the data for removing
59551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            // hyphens.
59645f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            if (!doNotIndexKeys.contains(key)) {
59745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                title = getDataTitle(context, attrs);
59845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                summary = getDataSummary(context, attrs);
59945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                keywords = getDataKeywords(context, attrs);
60045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
60145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                updateOneRowWithFilteredData(database, localeStr, title, summary, null, null,
60245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        fragmentName, screenTitle, iconResId, rank,
60345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        keywords, intentAction, intentTargetPackage, intentTargetClass, true, key);
60445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            }
60551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
60651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
60751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
60851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
60951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    continue;
61051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                }
61151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
6129593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                nodeName = parser.getName();
6139593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
61445f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                key = getDataKey(context, attrs);
61545f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                if (doNotIndexKeys.contains(key)) {
61645f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                    continue;
61745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                }
61845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
61951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                title = getDataTitle(context, attrs);
62051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                keywords = getDataKeywords(context, attrs);
62151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
6229593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) {
6239593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    summary = getDataSummary(context, attrs);
6249593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
625a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                    String entries = null;
626dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio
627a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                    if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) {
628a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                        entries = getDataEntries(context, attrs);
629a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                    }
630a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio
6319593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    // Insert rows for the child nodes of PreferenceScreen
632a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                    updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries,
6337d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio                            fragmentName, screenTitle, iconResId, rank,
634c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                            keywords, intentAction, intentTargetPackage, intentTargetClass,
635c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                            true, key);
636c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                } else {
6379593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    final String summaryOn = getDataSummaryOn(context, attrs);
6389593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    final String summaryOff = getDataSummaryOff(context, attrs);
6399593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
6409593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff,
6417d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio                            null, fragmentName, screenTitle, iconResId, rank,
642c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                            keywords, intentAction, intentTargetPackage, intentTargetClass,
643c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                            true, key);
6449593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                }
64551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
64651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
64751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (XmlPullParserException e) {
64851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            throw new RuntimeException("Error parsing PreferenceScreen", e);
64951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (IOException e) {
65051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            throw new RuntimeException("Error parsing PreferenceScreen", e);
65151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } finally {
65251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            if (parser != null) parser.close();
653b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
65451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
655b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
65651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void indexOneRaw(SQLiteDatabase database, String localeStr,
65751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                             SearchIndexableRaw raw) {
65851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        // Should be the same locale as the one we are processing
65951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (!raw.locale.toString().equalsIgnoreCase(localeStr)) {
66051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return;
66151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
66251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
66351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        updateOneRowWithFilteredData(database, localeStr,
66451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.title,
6659593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                raw.summaryOn,
6669593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                raw.summaryOff,
667a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                raw.entries,
66851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.className,
66951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.screenTitle,
67051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.iconResId,
67151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.rank,
67251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.keywords,
67351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.intentAction,
67451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.intentTargetPackage,
67551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                raw.intentTargetClass,
676c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                raw.enabled,
677c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                raw.key);
67851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
67951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
680a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio    private Indexable.SearchIndexProvider getSearchIndexProvider(String className) {
68151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        try {
682a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            final Class<?> clazz = Class.forName(className);
68351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            if (Indexable.class.isAssignableFrom(clazz)) {
6849593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
685a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                return (Indexable.SearchIndexProvider) f.get(null);
68651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
68751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (ClassNotFoundException e) {
688a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            Log.e(LOG_TAG, "Cannot find class: " + className, e);
68951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (NoSuchFieldException e) {
6909593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            Log.e(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e);
69151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } catch (IllegalAccessException e) {
6929593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            Log.e(LOG_TAG,
6939593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                    "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'", e);
69451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
695a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        return null;
696a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio    }
697a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
69845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio    private void indexFromLocalProvider(Context context, SQLiteDatabase database, String localeStr,
69945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                Indexable.SearchIndexProvider provider, String className, int iconResId, int rank,
70045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                boolean enabled) {
70145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
702a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        if (provider == null) {
70345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio            Log.w(LOG_TAG, "Cannot find provider: " + className);
704a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            return;
705a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        }
706a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
70745f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        final List<String> doNotIndexKeys = provider.getNonIndexableKeys(context);
70845f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio        final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(context, enabled);
70945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
710a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        if (rawList != null) {
711a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            final int rawSize = rawList.size();
712a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            for (int i = 0; i < rawSize; i++) {
713a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                SearchIndexableRaw raw = rawList.get(i);
714a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
715a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                // Should be the same locale as the one we are processing
716a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                if (!raw.locale.toString().equalsIgnoreCase(localeStr)) {
717a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                    continue;
718a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                }
719a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
72045f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                if (doNotIndexKeys.contains(raw.key)) {
72145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                    continue;
72245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                }
72345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio
724a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                updateOneRowWithFilteredData(database, localeStr,
725a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.title,
726a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.summaryOn,
727a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.summaryOff,
728a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.entries,
72945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        className,
730a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.screenTitle,
73145f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        iconResId,
73245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        rank,
733a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.keywords,
734a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.intentAction,
735a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.intentTargetPackage,
736a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.intentTargetClass,
737a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.enabled,
738a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        raw.key);
739a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            }
740a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        }
741a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
742a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        final List<SearchIndexableResource> resList =
74345f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                provider.getXmlResourcesToIndex(context, enabled);
744a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        if (resList != null) {
745a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            final int resSize = resList.size();
746a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            for (int i = 0; i < resSize; i++) {
747a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                SearchIndexableResource item = resList.get(i);
748a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
749a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                // Should be the same locale as the one we are processing
750a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                if (!item.locale.toString().equalsIgnoreCase(localeStr)) {
751a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                    continue;
752a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                }
753a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio
754caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav                final int itemIconResId = (item.iconResId == 0) ? iconResId : item.iconResId;
755caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav                final int itemRank = (item.rank == 0) ? rank : item.rank;
756caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav                String itemClassName = (TextUtils.isEmpty(item.className))
757caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav                        ? className : item.className;
758caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav
75945f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                indexFromResource(context, database, localeStr,
760caa0b54cbcb71b1124ea50cb0cf5abb6a4d1275fSvetoslav                        item.xmlResId, itemClassName, itemIconResId, itemRank,
761a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio                        item.intentAction, item.intentTargetPackage,
76245f754e50618076213ed6911ff1e6c37b4db0467Fabrice Di Meglio                        item.intentTargetClass, doNotIndexKeys);
763a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio            }
764a9d37050cb427cca92587341f399606edfc8ef8dFabrice Di Meglio        }
76551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
76651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
76751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void updateOneRowWithFilteredData(SQLiteDatabase database, String locale,
768dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio            String title, String summaryOn, String summaryOff, String entries,
7697d39310c8d159190cfcc63aa6647714c056d76f6Fabrice Di Meglio            String className,
770a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            String screenTitle, int iconResId, int rank, String keywords,
77151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            String intentAction, String intentTargetPackage, String intentTargetClass,
772c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio            boolean enabled, String key) {
77351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
77451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        String updatedTitle;
77551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (title != null) {
77651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            updatedTitle = title.replaceAll(NON_BREAKING_HYPHEN, HYPHEN);
77751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
77851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        else {
77951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            updatedTitle = EMPTY;
78051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
78151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
7829593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        String updatedSummaryOn;
7839593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        if (summaryOn != null) {
7849593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            updatedSummaryOn = summaryOn.replaceAll(NON_BREAKING_HYPHEN, HYPHEN);
78551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        } else {
7869593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            updatedSummaryOn = EMPTY;
7879593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        }
7889593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
7899593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        String updatedSummaryOff;
7909593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        if (summaryOff != null) {
7919593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            updatedSummaryOff = summaryOff.replaceAll(NON_BREAKING_HYPHEN, HYPHEN);
7929593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        } else {
7939593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            updatedSummaryOff = EMPTY;
79451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
79551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
79651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        String normalizedTitle = updatedTitle.replaceAll(HYPHEN, EMPTY);
7979593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        String normalizedSummaryOn = updatedSummaryOn.replaceAll(HYPHEN, EMPTY);
7989593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        String normalizedSummaryOff = updatedSummaryOff.replaceAll(HYPHEN, EMPTY);
79951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
80051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        updateOneRow(database, locale,
8019593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                updatedTitle, normalizedTitle, updatedSummaryOn, normalizedSummaryOn,
802dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio                updatedSummaryOff, normalizedSummaryOff, entries,
803dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio                className, screenTitle, iconResId,
804c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                rank, keywords, intentAction, intentTargetPackage, intentTargetClass, enabled, key);
80551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
80651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
80751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private void updateOneRow(SQLiteDatabase database, String locale,
80851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            String updatedTitle, String normalizedTitle,
8099593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio            String updatedSummaryOn, String normalizedSummaryOn,
810dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio            String updatedSummaryOff, String normalizedSummaryOff, String entries,
811dd41dfc483e830bdb33df858dec99e2c4c806bfcFabrice Di Meglio            String className, String screenTitle, int iconResId, int rank, String keywords,
81251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            String intentAction, String intentTargetPackage, String intentTargetClass,
813c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio            boolean enabled, String key) {
81451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
81551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (TextUtils.isEmpty(updatedTitle)) {
81651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return;
81751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        }
81851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
81951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        ContentValues values = new ContentValues();
82051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.DOCID, updatedTitle.hashCode());
82151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.LOCALE, locale);
82251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.DATA_RANK, rank);
82351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.DATA_TITLE, updatedTitle);
82451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.DATA_TITLE_NORMALIZED, normalizedTitle);
8259593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        values.put(IndexColumns.DATA_SUMMARY_ON, updatedSummaryOn);
8269593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        values.put(IndexColumns.DATA_SUMMARY_ON_NORMALIZED, normalizedSummaryOn);
8279593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        values.put(IndexColumns.DATA_SUMMARY_OFF, updatedSummaryOff);
8289593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        values.put(IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, normalizedSummaryOff);
829a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        values.put(IndexColumns.DATA_ENTRIES, entries);
83051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.DATA_KEYWORDS, keywords);
83151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.CLASS_NAME, className);
83251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.SCREEN_TITLE, screenTitle);
83351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.INTENT_ACTION, intentAction);
83451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.INTENT_TARGET_PACKAGE, intentTargetPackage);
83551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.INTENT_TARGET_CLASS, intentTargetClass);
83651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.ICON, iconResId);
83751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        values.put(IndexColumns.ENABLED, enabled);
838c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio        values.put(IndexColumns.DATA_KEY_REF, key);
83951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
84051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        database.replaceOrThrow(Tables.TABLE_PREFS_INDEX, null, values);
84151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
84251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
843c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio    private String getDataKey(Context context, AttributeSet attrs) {
844c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio        return getData(context, attrs,
845c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                com.android.internal.R.styleable.Preference,
846c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                com.android.internal.R.styleable.Preference_key);
847c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio    }
848c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio
84951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private String getDataTitle(Context context, AttributeSet attrs) {
85051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return getData(context, attrs,
85151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                com.android.internal.R.styleable.Preference,
85251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                com.android.internal.R.styleable.Preference_title);
85351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
85451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
85551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private String getDataSummary(Context context, AttributeSet attrs) {
85651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return getData(context, attrs,
85751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                com.android.internal.R.styleable.Preference,
85851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                com.android.internal.R.styleable.Preference_summary);
85951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
86051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
8619593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    private String getDataSummaryOn(Context context, AttributeSet attrs) {
8629593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        return getData(context, attrs,
8639593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                com.android.internal.R.styleable.CheckBoxPreference,
8649593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                com.android.internal.R.styleable.CheckBoxPreference_summaryOn);
8659593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    }
8669593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
8679593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    private String getDataSummaryOff(Context context, AttributeSet attrs) {
8689593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio        return getData(context, attrs,
8699593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                com.android.internal.R.styleable.CheckBoxPreference,
8709593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio                com.android.internal.R.styleable.CheckBoxPreference_summaryOff);
8719593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio    }
8729593782d154f378a0c911cd015d410c18fe74a92Fabrice Di Meglio
873a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    private String getDataEntries(Context context, AttributeSet attrs) {
874a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        return getDataEntries(context, attrs,
875a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                com.android.internal.R.styleable.ListPreference,
876a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                com.android.internal.R.styleable.ListPreference_entries);
877a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    }
878a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio
87951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private String getDataKeywords(Context context, AttributeSet attrs) {
88051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return getData(context, attrs, R.styleable.Preference, R.styleable.Preference_keywords);
88151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    }
88251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
88351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio    private String getData(Context context, AttributeSet set, int[] attrs, int resId) {
88451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final TypedArray sa = context.obtainStyledAttributes(set, attrs);
88551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        final TypedValue tv = sa.peekValue(resId);
88651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
88751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        CharSequence data = null;
88851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        if (tv != null && tv.type == TypedValue.TYPE_STRING) {
88951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            if (tv.resourceId != 0) {
89051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                data = context.getText(tv.resourceId);
89151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            } else {
89251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                data = tv.string;
89351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
894b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
89551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        return (data != null) ? data.toString() : null;
896b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    }
897b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
898a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    private String getDataEntries(Context context, AttributeSet set, int[] attrs, int resId) {
899a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        final TypedArray sa = context.obtainStyledAttributes(set, attrs);
900a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        final TypedValue tv = sa.peekValue(resId);
901a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio
902a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        String[] data = null;
903a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) {
904a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            if (tv.resourceId != 0) {
905a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio                data = context.getResources().getStringArray(tv.resourceId);
906a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            }
907a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        }
908a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        final int count = (data == null ) ? 0 : data.length;
909a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        if (count == 0) {
910a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            return null;
911a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        }
912a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        final StringBuilder result = new StringBuilder();
913a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        for (int n = 0; n < count; n++) {
914a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            result.append(data[n]);
915a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio            result.append(" ");
916a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        }
917a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio        return result.toString();
918a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio    }
919a41707200b6628376e8fb575e782d8228c0d32a2Fabrice Di Meglio
920d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio    private int getResId(Context context, AttributeSet set, int[] attrs, int resId) {
921d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        final TypedArray sa = context.obtainStyledAttributes(set, attrs);
922d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        final TypedValue tv = sa.peekValue(resId);
923d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio
924d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        if (tv != null && tv.type == TypedValue.TYPE_STRING) {
925d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio            return tv.resourceId;
926d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        } else {
927d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio            return 0;
928d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio        }
929d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio   }
930d25314d3305ed1a07b53991a978cd71219ef2a10Fabrice Di Meglio
931b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    /**
9326f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio     * A private class for updating the Index database
9336f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio     */
934b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio    private class UpdateIndexTask extends AsyncTask<UpdateData, Integer, Boolean> {
9356f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
9366f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        @Override
9376f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        protected void onPreExecute() {
9386f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            super.onPreExecute();
9396f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            mIsAvailable.set(false);
9406f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
9416f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
9426f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        @Override
9436f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        protected void onPostExecute(Boolean aBoolean) {
9446f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            super.onPostExecute(aBoolean);
9456f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            mIsAvailable.set(true);
9466f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
9476f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
9486f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        @Override
949b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        protected Boolean doInBackground(UpdateData... params) {
9506f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            boolean result = false;
951b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
95251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final List<SearchIndexableData> dataToUpdate = params[0].dataToUpdate;
953b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final List<String> dataToDelete = params[0].dataToDelete;
95451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final boolean forceUpdate = params[0].forceUpdate;
9552f4556e31b5d69e508ab9431eef4fea5f8d89e4fFabrice Di Meglio            final SQLiteDatabase database = getWritableDatabase();
956b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final String localeStr = Locale.getDefault().toString();
957b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
9586f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            try {
9596f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                database.beginTransaction();
96051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                if (dataToUpdate.size() > 0) {
96151bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                    processDataToUpdate(database, localeStr, dataToUpdate, forceUpdate);
962b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio                }
963b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio                if (dataToDelete.size() > 0) {
964b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio                    processDataToDelete(database, localeStr, dataToDelete);
9656f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                }
9666f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                database.setTransactionSuccessful();
9676f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                result = true;
9686f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            } finally {
9696f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                database.endTransaction();
9706f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            }
971b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            return result;
972b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
973b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
97451bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        private boolean processDataToUpdate(SQLiteDatabase database, String localeStr,
97551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                List<SearchIndexableData> dataToUpdate, boolean forceUpdate) {
97651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio
97751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            if (!forceUpdate && isLocaleAlreadyIndexed(database, localeStr)) {
97851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                Log.d(LOG_TAG, "Locale '" + localeStr + "' is already indexed");
97951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                return true;
98051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            }
981b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
982b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            boolean result = false;
983b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final long current = System.currentTimeMillis();
984b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
98551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final int count = dataToUpdate.size();
986b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            for (int n = 0; n < count; n++) {
98751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                final SearchIndexableData data = dataToUpdate.get(n);
98851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                indexOneSearchIndexableData(database, localeStr, data);
989b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            }
990b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
991b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final long now = System.currentTimeMillis();
99251bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " +
993b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio                    (now - current) + " millis");
994b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            return result;
995b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        }
996b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
99751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        private boolean processDataToDelete(SQLiteDatabase database, String localeStr,
99851bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                                            List<String> dataToDelete) {
999b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
1000b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            boolean result = false;
1001b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            final long current = System.currentTimeMillis();
1002b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
100351bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final int count = dataToDelete.size();
1004b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            for (int n = 0; n < count; n++) {
100551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                final String data = dataToDelete.get(n);
100651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio                delete(database, data);
1007b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            }
1008b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio
10096f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            final long now = System.currentTimeMillis();
101051bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            Log.d(LOG_TAG, "Deleting data for locale '" + localeStr + "' took " +
10116f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                    (now - current) + " millis");
10126f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            return result;
10136f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
10146f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio
101551bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio        private int delete(SQLiteDatabase database, String title) {
101651bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final String whereClause = IndexColumns.DATA_TITLE + "=?";
101751bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            final String[] whereArgs = new String[] { title };
1018fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
101951bfee595c3ce587e2e26565fd9e8f4ae02c3482Fabrice Di Meglio            return database.delete(Tables.TABLE_PREFS_INDEX, whereClause, whereArgs);
1020fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio        }
1021fa7dc240e978b1b77bb5c80a78cd1f8c77648301Fabrice Di Meglio
1022b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio        private boolean isLocaleAlreadyIndexed(SQLiteDatabase database, String locale) {
10236f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            Cursor cursor = null;
10246f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            boolean result = false;
10256f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            final StringBuilder sb = new StringBuilder(IndexColumns.LOCALE);
10266f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            sb.append(" = ");
1027b8dfbf140986a9c0781f268ea40914063f026436Fabrice Di Meglio            DatabaseUtils.appendEscapedSQLString(sb, locale);
10286f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            try {
10296f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                // We care only for 1 row
10306f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                cursor = database.query(Tables.TABLE_PREFS_INDEX, null,
10316f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                        sb.toString(), null, null, null, null, "1");
10326f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                final int count = cursor.getCount();
10336f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                result = (count >= 1);
10346f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            } finally {
10356f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                if (cursor != null) {
10366f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                    cursor.close();
10376f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio                }
10386f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            }
10396f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio            return result;
10406f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio        }
10416f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio    }
10426f0739a3d9a9eca1591ae6bada1dd4d1d92c0defFabrice Di Meglio}
1043