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 17package com.android.settings.search; 18 19import static com.android.settings.search.InstalledAppResultLoader.getWordDifference; 20 21import android.accessibilityservice.AccessibilityServiceInfo; 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.Intent; 25import android.content.pm.PackageManager; 26import android.content.pm.ResolveInfo; 27import android.content.pm.ServiceInfo; 28import android.graphics.drawable.Drawable; 29import android.support.annotation.VisibleForTesting; 30import android.support.v4.content.ContextCompat; 31import android.view.accessibility.AccessibilityManager; 32 33import com.android.settings.R; 34import com.android.settings.accessibility.AccessibilitySettings; 35import com.android.settings.dashboard.SiteMapManager; 36import com.android.settings.utils.AsyncLoader; 37 38import java.util.HashSet; 39import java.util.List; 40import java.util.Objects; 41import java.util.Set; 42 43public class AccessibilityServiceResultLoader extends AsyncLoader<Set<? extends SearchResult>> { 44 45 private static final int NAME_NO_MATCH = -1; 46 47 private List<String> mBreadcrumb; 48 private SiteMapManager mSiteMapManager; 49 @VisibleForTesting 50 final String mQuery; 51 private final AccessibilityManager mAccessibilityManager; 52 private final PackageManager mPackageManager; 53 54 55 public AccessibilityServiceResultLoader(Context context, String query, 56 SiteMapManager mapManager) { 57 super(context); 58 mSiteMapManager = mapManager; 59 mPackageManager = context.getPackageManager(); 60 mAccessibilityManager = 61 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); 62 mQuery = query; 63 } 64 65 @Override 66 public Set<? extends SearchResult> loadInBackground() { 67 final Set<SearchResult> results = new HashSet<>(); 68 final Context context = getContext(); 69 final List<AccessibilityServiceInfo> services = mAccessibilityManager 70 .getInstalledAccessibilityServiceList(); 71 final String screenTitle = context.getString(R.string.accessibility_settings); 72 for (AccessibilityServiceInfo service : services) { 73 if (service == null) { 74 continue; 75 } 76 final ResolveInfo resolveInfo = service.getResolveInfo(); 77 if (service.getResolveInfo() == null) { 78 continue; 79 } 80 final ServiceInfo serviceInfo = resolveInfo.serviceInfo; 81 final CharSequence title = resolveInfo.loadLabel(mPackageManager); 82 final int wordDiff = getWordDifference(title.toString(), mQuery); 83 if (wordDiff == NAME_NO_MATCH) { 84 continue; 85 } 86 final Drawable icon; 87 if (resolveInfo.getIconResource() == 0) { 88 icon = ContextCompat.getDrawable(context, R.mipmap.ic_accessibility_generic); 89 } else { 90 icon = resolveInfo.loadIcon(mPackageManager); 91 } 92 final String componentName = new ComponentName(serviceInfo.packageName, 93 serviceInfo.name).flattenToString(); 94 final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context, 95 AccessibilitySettings.class.getName(), componentName, screenTitle); 96 97 results.add(new SearchResult.Builder() 98 .setTitle(title) 99 .addBreadcrumbs(getBreadCrumb()) 100 .setPayload(new ResultPayload(intent)) 101 .setRank(wordDiff) 102 .setIcon(icon) 103 .setStableId(Objects.hash(screenTitle, componentName)) 104 .build()); 105 } 106 return results; 107 } 108 109 private List<String> getBreadCrumb() { 110 if (mBreadcrumb == null || mBreadcrumb.isEmpty()) { 111 final Context context = getContext(); 112 mBreadcrumb = mSiteMapManager.buildBreadCrumb( 113 context, AccessibilitySettings.class.getName(), 114 context.getString(R.string.accessibility_settings)); 115 } 116 return mBreadcrumb; 117 } 118 119 @Override 120 protected void onDiscardResult(Set<? extends SearchResult> result) { 121 122 } 123} 124