Home | History | Annotate | Download | only in quicksearchbox
      1 /*
      2  * Copyright (C) 2010 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.quicksearchbox;
     18 
     19 import com.google.common.annotations.VisibleForTesting;
     20 
     21 import android.app.SearchManager;
     22 import android.content.Intent;
     23 import android.net.Uri;
     24 import android.os.Bundle;
     25 
     26 /**
     27  * Some utilities for suggestions.
     28  */
     29 public class SuggestionUtils {
     30 
     31     private SuggestionUtils() {
     32     }
     33 
     34     public static Intent getSuggestionIntent(SuggestionCursor suggestion, Bundle appSearchData) {
     35         String action = suggestion.getSuggestionIntentAction();
     36 
     37         String data = suggestion.getSuggestionIntentDataString();
     38         String query = suggestion.getSuggestionQuery();
     39         String userQuery = suggestion.getUserQuery();
     40         String extraData = suggestion.getSuggestionIntentExtraData();
     41 
     42         // Now build the Intent
     43         Intent intent = new Intent(action);
     44         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     45         // We need CLEAR_TOP to avoid reusing an old task that has other activities
     46         // on top of the one we want.
     47         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
     48         if (data != null) {
     49             intent.setData(Uri.parse(data));
     50         }
     51         intent.putExtra(SearchManager.USER_QUERY, userQuery);
     52         if (query != null) {
     53             intent.putExtra(SearchManager.QUERY, query);
     54         }
     55         if (extraData != null) {
     56             intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
     57         }
     58         if (appSearchData != null) {
     59             intent.putExtra(SearchManager.APP_DATA, appSearchData);
     60         }
     61 
     62         intent.setComponent(suggestion.getSuggestionIntentComponent());
     63         return intent;
     64     }
     65 
     66     /**
     67      * Gets a unique key that identifies a suggestion. This is used to avoid
     68      * duplicate suggestions.
     69      */
     70     public static String getSuggestionKey(Suggestion suggestion) {
     71         String action = makeKeyComponent(suggestion.getSuggestionIntentAction());
     72         String data = makeKeyComponent(normalizeUrl(suggestion.getSuggestionIntentDataString()));
     73         String query = makeKeyComponent(normalizeUrl(suggestion.getSuggestionQuery()));
     74         // calculating accurate size of string builder avoids an allocation vs starting with
     75         // the default size and having to expand.
     76         int size = action.length() + 2 + data.length() + query.length();
     77         return new StringBuilder(size)
     78                 .append(action)
     79                 .append('#')
     80                 .append(data)
     81                 .append('#')
     82                 .append(query)
     83                 .toString();
     84     }
     85 
     86     private static String makeKeyComponent(String str) {
     87         return str == null ? "" : str;
     88     }
     89 
     90     private static final String SCHEME_SEPARATOR = "://";
     91     private static final String DEFAULT_SCHEME = "http";
     92 
     93     /**
     94      * Simple url normalization that adds http:// if no scheme exists, and
     95      * strips empty paths, e.g.,
     96      * www.google.com/ -> http://www.google.com.  Used to prevent obvious
     97      * duplication of nav suggestions, bookmarks and urls entered by the user.
     98      */
     99     @VisibleForTesting
    100     static String normalizeUrl(String url) {
    101         String normalized;
    102         if (url != null) {
    103             int start;
    104             int schemePos = url.indexOf(SCHEME_SEPARATOR);
    105             if (schemePos == -1) {
    106                 // no scheme - add the default
    107                 normalized = DEFAULT_SCHEME + SCHEME_SEPARATOR + url;
    108                 start = DEFAULT_SCHEME.length() + SCHEME_SEPARATOR.length();
    109             } else {
    110                 normalized = url;
    111                 start = schemePos + SCHEME_SEPARATOR.length();
    112             }
    113             int end = normalized.length();
    114             if (normalized.indexOf('/', start) == end - 1) {
    115                 end--;
    116             }
    117             return normalized.substring(0, end);
    118         }
    119         return url;
    120     }
    121 
    122 }
    123