Search in sources :

Example 41 with SearchableInfo

use of android.app.SearchableInfo in project XobotOS by xamarin.

the class Searchables method getSearchableInfo.

/**
     * Look up, or construct, based on the activity.
     *
     * The activities fall into three cases, based on meta-data found in
     * the manifest entry:
     * <ol>
     * <li>The activity itself implements search.  This is indicated by the
     * presence of a "android.app.searchable" meta-data attribute.
     * The value is a reference to an XML file containing search information.</li>
     * <li>A related activity implements search.  This is indicated by the
     * presence of a "android.app.default_searchable" meta-data attribute.
     * The value is a string naming the activity implementing search.  In this
     * case the factory will "redirect" and return the searchable data.</li>
     * <li>No searchability data is provided.  We return null here and other
     * code will insert the "default" (e.g. contacts) search.
     *
     * TODO: cache the result in the map, and check the map first.
     * TODO: it might make sense to implement the searchable reference as
     * an application meta-data entry.  This way we don't have to pepper each
     * and every activity.
     * TODO: can we skip the constructor step if it's a non-searchable?
     * TODO: does it make sense to plug the default into a slot here for
     * automatic return?  Probably not, but it's one way to do it.
     *
     * @param activity The name of the current activity, or null if the
     * activity does not define any explicit searchable metadata.
     */
public SearchableInfo getSearchableInfo(ComponentName activity) {
    // Step 1.  Is the result already hashed?  (case 1)
    SearchableInfo result;
    synchronized (this) {
        result = mSearchablesMap.get(activity);
        if (result != null)
            return result;
    }
    // Step 2.  See if the current activity references a searchable.
    // Note:  Conceptually, this could be a while(true) loop, but there's
    // no point in implementing reference chaining here and risking a loop.
    // References must point directly to searchable activities.
    ActivityInfo ai = null;
    try {
        ai = mContext.getPackageManager().getActivityInfo(activity, PackageManager.GET_META_DATA);
        String refActivityName = null;
        // First look for activity-specific reference
        Bundle md = ai.metaData;
        if (md != null) {
            refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
        }
        // If not found, try for app-wide reference
        if (refActivityName == null) {
            md = ai.applicationInfo.metaData;
            if (md != null) {
                refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
            }
        }
        // Irrespective of source, if a reference was found, follow it.
        if (refActivityName != null) {
            // This value is deprecated, return null
            if (refActivityName.equals(MD_SEARCHABLE_SYSTEM_SEARCH)) {
                return null;
            }
            String pkg = activity.getPackageName();
            ComponentName referredActivity;
            if (refActivityName.charAt(0) == '.') {
                referredActivity = new ComponentName(pkg, pkg + refActivityName);
            } else {
                referredActivity = new ComponentName(pkg, refActivityName);
            }
            // it against the original name so we can skip the check
            synchronized (this) {
                result = mSearchablesMap.get(referredActivity);
                if (result != null) {
                    mSearchablesMap.put(activity, result);
                    return result;
                }
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
    // case 3: no metadata
    }
    // Step 3.  None found. Return null.
    return null;
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) PackageManager(android.content.pm.PackageManager) Bundle(android.os.Bundle) SearchableInfo(android.app.SearchableInfo) ComponentName(android.content.ComponentName)

Example 42 with SearchableInfo

use of android.app.SearchableInfo in project XobotOS by xamarin.

the class SearchView method onVoiceClicked.

private void onVoiceClicked() {
    // guard against possible race conditions
    if (mSearchable == null) {
        return;
    }
    SearchableInfo searchable = mSearchable;
    try {
        if (searchable.getVoiceSearchLaunchWebSearch()) {
            Intent webSearchIntent = createVoiceWebSearchIntent(mVoiceWebSearchIntent, searchable);
            getContext().startActivity(webSearchIntent);
        } else if (searchable.getVoiceSearchLaunchRecognizer()) {
            Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent, searchable);
            getContext().startActivity(appSearchIntent);
        }
    } catch (ActivityNotFoundException e) {
        // Should not happen, since we check the availability of
        // voice search before showing the button. But just in case...
        Log.w(LOG_TAG, "Could not find voice search activity");
    }
}
Also used : ActivityNotFoundException(android.content.ActivityNotFoundException) SearchableInfo(android.app.SearchableInfo) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) RecognizerIntent(android.speech.RecognizerIntent)

Example 43 with SearchableInfo

use of android.app.SearchableInfo in project android_frameworks_base by ResurrectionRemix.

the class Searchables method getSearchableInfo.

/**
     * Look up, or construct, based on the activity.
     *
     * The activities fall into three cases, based on meta-data found in
     * the manifest entry:
     * <ol>
     * <li>The activity itself implements search.  This is indicated by the
     * presence of a "android.app.searchable" meta-data attribute.
     * The value is a reference to an XML file containing search information.</li>
     * <li>A related activity implements search.  This is indicated by the
     * presence of a "android.app.default_searchable" meta-data attribute.
     * The value is a string naming the activity implementing search.  In this
     * case the factory will "redirect" and return the searchable data.</li>
     * <li>No searchability data is provided.  We return null here and other
     * code will insert the "default" (e.g. contacts) search.
     *
     * TODO: cache the result in the map, and check the map first.
     * TODO: it might make sense to implement the searchable reference as
     * an application meta-data entry.  This way we don't have to pepper each
     * and every activity.
     * TODO: can we skip the constructor step if it's a non-searchable?
     * TODO: does it make sense to plug the default into a slot here for
     * automatic return?  Probably not, but it's one way to do it.
     *
     * @param activity The name of the current activity, or null if the
     * activity does not define any explicit searchable metadata.
     */
public SearchableInfo getSearchableInfo(ComponentName activity) {
    // Step 1.  Is the result already hashed?  (case 1)
    SearchableInfo result;
    synchronized (this) {
        result = mSearchablesMap.get(activity);
        if (result != null)
            return result;
    }
    // Step 2.  See if the current activity references a searchable.
    // Note:  Conceptually, this could be a while(true) loop, but there's
    // no point in implementing reference chaining here and risking a loop.
    // References must point directly to searchable activities.
    ActivityInfo ai = null;
    try {
        ai = mPm.getActivityInfo(activity, PackageManager.GET_META_DATA, mUserId);
    } catch (RemoteException re) {
        Log.e(LOG_TAG, "Error getting activity info " + re);
        return null;
    }
    String refActivityName = null;
    // First look for activity-specific reference
    Bundle md = ai.metaData;
    if (md != null) {
        refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
    }
    // If not found, try for app-wide reference
    if (refActivityName == null) {
        md = ai.applicationInfo.metaData;
        if (md != null) {
            refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
        }
    }
    // Irrespective of source, if a reference was found, follow it.
    if (refActivityName != null) {
        // This value is deprecated, return null
        if (refActivityName.equals(MD_SEARCHABLE_SYSTEM_SEARCH)) {
            return null;
        }
        String pkg = activity.getPackageName();
        ComponentName referredActivity;
        if (refActivityName.charAt(0) == '.') {
            referredActivity = new ComponentName(pkg, pkg + refActivityName);
        } else {
            referredActivity = new ComponentName(pkg, refActivityName);
        }
        // it against the original name so we can skip the check
        synchronized (this) {
            result = mSearchablesMap.get(referredActivity);
            if (result != null) {
                mSearchablesMap.put(activity, result);
                return result;
            }
        }
    }
    // Step 3.  None found. Return null.
    return null;
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) Bundle(android.os.Bundle) SearchableInfo(android.app.SearchableInfo) ComponentName(android.content.ComponentName) RemoteException(android.os.RemoteException)

Example 44 with SearchableInfo

use of android.app.SearchableInfo in project android_frameworks_base by ResurrectionRemix.

the class Searchables method updateSearchableList.

/**
     * Builds an entire list (suitable for display) of
     * activities that are searchable, by iterating the entire set of
     * ACTION_SEARCH & ACTION_WEB_SEARCH intents.
     *
     * Also clears the hash of all activities -> searches which will
     * refill as the user clicks "search".
     *
     * This should only be done at startup and again if we know that the
     * list has changed.
     *
     * TODO: every activity that provides a ACTION_SEARCH intent should
     * also provide searchability meta-data.  There are a bunch of checks here
     * that, if data is not found, silently skip to the next activity.  This
     * won't help a developer trying to figure out why their activity isn't
     * showing up in the list, but an exception here is too rough.  I would
     * like to find a better notification mechanism.
     *
     * TODO: sort the list somehow?  UI choice.
     */
public void updateSearchableList() {
    // These will become the new values at the end of the method
    HashMap<ComponentName, SearchableInfo> newSearchablesMap = new HashMap<ComponentName, SearchableInfo>();
    ArrayList<SearchableInfo> newSearchablesList = new ArrayList<SearchableInfo>();
    ArrayList<SearchableInfo> newSearchablesInGlobalSearchList = new ArrayList<SearchableInfo>();
    // Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers.
    List<ResolveInfo> searchList;
    final Intent intent = new Intent(Intent.ACTION_SEARCH);
    long ident = Binder.clearCallingIdentity();
    try {
        searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
        List<ResolveInfo> webSearchInfoList;
        final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
        webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
        // analyze each one, generate a Searchables record, and record
        if (searchList != null || webSearchInfoList != null) {
            int search_count = (searchList == null ? 0 : searchList.size());
            int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
            int count = search_count + web_search_count;
            for (int ii = 0; ii < count; ii++) {
                // for each component, try to find metadata
                ResolveInfo info = (ii < search_count) ? searchList.get(ii) : webSearchInfoList.get(ii - search_count);
                ActivityInfo ai = info.activityInfo;
                // Check first to avoid duplicate entries.
                if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
                    SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai, mUserId);
                    if (searchable != null) {
                        newSearchablesList.add(searchable);
                        newSearchablesMap.put(searchable.getSearchActivity(), searchable);
                        if (searchable.shouldIncludeInGlobalSearch()) {
                            newSearchablesInGlobalSearchList.add(searchable);
                        }
                    }
                }
            }
        }
        List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
        // Find the global search activity
        ComponentName newGlobalSearchActivity = findGlobalSearchActivity(newGlobalSearchActivities);
        // Find the web search activity
        ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
        // Store a consistent set of new values
        synchronized (this) {
            mSearchablesMap = newSearchablesMap;
            mSearchablesList = newSearchablesList;
            mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
            mGlobalSearchActivities = newGlobalSearchActivities;
            mCurrentGlobalSearchActivity = newGlobalSearchActivity;
            mWebSearchActivity = newWebSearchActivity;
        }
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) ActivityInfo(android.content.pm.ActivityInfo) HashMap(java.util.HashMap) SearchableInfo(android.app.SearchableInfo) ArrayList(java.util.ArrayList) ComponentName(android.content.ComponentName) Intent(android.content.Intent)

Example 45 with SearchableInfo

use of android.app.SearchableInfo in project android_frameworks_base by ResurrectionRemix.

the class Searchables method dump.

void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    pw.println("Searchable authorities:");
    synchronized (this) {
        if (mSearchablesList != null) {
            for (SearchableInfo info : mSearchablesList) {
                pw.print("  ");
                pw.println(info.getSuggestAuthority());
            }
        }
    }
}
Also used : SearchableInfo(android.app.SearchableInfo)

Aggregations

SearchableInfo (android.app.SearchableInfo)54 Intent (android.content.Intent)22 ComponentName (android.content.ComponentName)17 PendingIntent (android.app.PendingIntent)15 ActivityNotFoundException (android.content.ActivityNotFoundException)15 RecognizerIntent (android.speech.RecognizerIntent)15 Searchables (com.android.server.search.Searchables)15 ActivityInfo (android.content.pm.ActivityInfo)12 ResolveInfo (android.content.pm.ResolveInfo)6 Bundle (android.os.Bundle)6 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 RemoteException (android.os.RemoteException)5 SearchManager (android.app.SearchManager)2 PackageManager (android.content.pm.PackageManager)2 MenuItem (android.view.MenuItem)1 CompositeSubscription (rx.subscriptions.CompositeSubscription)1