• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.intelligence.search.sitemap;
18 
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.database.sqlite.SQLiteDatabase;
22 import androidx.annotation.WorkerThread;
23 import android.text.TextUtils;
24 import android.util.Log;
25 
26 import com.android.settings.intelligence.search.indexing.IndexDatabaseHelper;
27 import com.android.settings.intelligence.search.indexing.IndexDatabaseHelper.SiteMapColumns;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 
32 public class SiteMapManager {
33 
34     private static final String TAG = "SiteMapManager";
35     private static final boolean DEBUG_TIMING = false;
36 
37     public static final String[] SITE_MAP_COLUMNS = {
38             SiteMapColumns.PARENT_CLASS,
39             SiteMapColumns.PARENT_TITLE,
40             SiteMapColumns.CHILD_CLASS,
41             SiteMapColumns.CHILD_TITLE
42     };
43 
44     private final List<SiteMapPair> mPairs = new ArrayList<>();
45 
46     private boolean mInitialized;
47 
48     /**
49      * Given a fragment class name and its screen title, build a breadcrumb from Settings root to
50      * this screen.
51      * <p/>
52      * Not all screens have a full breadcrumb path leading up to root, it's because either some
53      * page in the breadcrumb path is not indexed, or it's only reachable via search.
54      */
55     @WorkerThread
buildBreadCrumb(Context context, String clazz, String screenTitle)56     public synchronized List<String> buildBreadCrumb(Context context, String clazz,
57             String screenTitle) {
58         init(context);
59         final long startTime = System.currentTimeMillis();
60         final List<String> breadcrumbs = new ArrayList<>();
61         if (!mInitialized) {
62             Log.w(TAG, "SiteMap is not initialized yet, skipping");
63             return breadcrumbs;
64         }
65         breadcrumbs.add(screenTitle);
66         String currentClass = clazz;
67         String currentTitle = screenTitle;
68         // Look up current page's parent, if found add it to breadcrumb string list, and repeat.
69         while (true) {
70             final SiteMapPair pair = lookUpParent(currentClass, currentTitle);
71             if (pair == null) {
72                 if (DEBUG_TIMING) {
73                     Log.d(TAG, "BreadCrumb timing: " + (System.currentTimeMillis() - startTime));
74                 }
75                 return breadcrumbs;
76             }
77             breadcrumbs.add(0, pair.getParentTitle());
78             currentClass = pair.getParentClass();
79             currentTitle = pair.getParentTitle();
80         }
81     }
82 
83     /**
84      * Initialize a list of {@link SiteMapPair}s. Each pair knows about a single parent-child
85      * page relationship.
86      */
87     @WorkerThread
init(Context context)88     private synchronized void init(Context context) {
89         if (mInitialized) {
90             // Make sure only init once.
91             return;
92         }
93         final long startTime = System.currentTimeMillis();
94         // First load site map from static index table.
95         final Context appContext = context.getApplicationContext();
96         final SQLiteDatabase db = IndexDatabaseHelper.getInstance(appContext).getReadableDatabase();
97         Cursor sitemap = db.query(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, SITE_MAP_COLUMNS, null,
98                 null, null, null, null);
99         while (sitemap.moveToNext()) {
100             final SiteMapPair pair = new SiteMapPair(
101                     sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_CLASS)),
102                     sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.PARENT_TITLE)),
103                     sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_CLASS)),
104                     sitemap.getString(sitemap.getColumnIndex(SiteMapColumns.CHILD_TITLE)));
105             mPairs.add(pair);
106         }
107         sitemap.close();
108         // Done.
109         mInitialized = true;
110         if (DEBUG_TIMING) {
111             Log.d(TAG, "Init timing: " + (System.currentTimeMillis() - startTime));
112         }
113     }
114 
115     @WorkerThread
lookUpParent(String clazz, String title)116     private SiteMapPair lookUpParent(String clazz, String title) {
117         for (SiteMapPair pair : mPairs) {
118             if (TextUtils.equals(pair.getChildClass(), clazz)
119                     && TextUtils.equals(title, pair.getChildTitle())) {
120                 return pair;
121             }
122         }
123         return null;
124     }
125 
126 }