@Override protected List<Label> doInBackground(Void... params) { final List<Label> allLabels = mClient.getAllLabels(); if ((allLabels == null) || allLabels.isEmpty()) { return null; } final PackageManager pm = mContext.getPackageManager(); final List<Label> candidates = new ArrayList<>(allLabels); ListIterator<Label> i = candidates.listIterator(); // Iterate through the labels database, and prune labels that belong // to valid packages. while (i.hasNext()) { final Label l = i.next(); // Ensure the label has a matching installed package. final String packageName = l.getPackageName(); PackageInfo packageInfo; try { packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); } catch (NameNotFoundException e) { // If there's no installed package, leave the label in the // list for removal. LogUtils.log( CustomLabelManager.class, Log.VERBOSE, "Consistency check removing label for unknown package %s.", packageName); continue; } // Ensure the signature hash of the application matches // the hash of the package when the label was stored. final String expectedHash = l.getPackageSignature(); final String actualHash = computePackageSignatureHash(packageInfo); if (TextUtils.isEmpty(expectedHash) || TextUtils.isEmpty(actualHash) || !expectedHash.equals(actualHash)) { // If the expected or actual signature hashes aren't // valid, or they don't match, leave the label in the list // for removal. LogUtils.log( CustomLabelManager.class, Log.WARN, "Consistency check removing label due to signature mismatch " + "for package %s.", packageName); continue; } // If the label has passed all consistency checks, prune the // label from the list of potentials for removal. i.remove(); } return candidates; // now containing only labels for removal }
// Note this comparator is not consistent with equals in Label, we should just implement // compareTo there, but will wait for BrailleBack to be merged with TalkBack @Override public int compare(Label first, Label second) { if (first == null) { if (second == null) { return 0; } else { return -1; } } if (second == null) return 1; int ret = first.getPackageName().compareTo(second.getPackageName()); if (ret != 0) return ret; return first.getViewName().compareTo(second.getViewName()); }
@Override protected void onPostExecute(Label result) { LogUtils.log( this, Log.VERBOSE, "LabelAddTask(%d) complete, stored as %s", hashCode(), result); mRequest.invokeCallback(result); if (result != null) { sendCacheRefreshIntent(result.getPackageName()); } super.onPostExecute(result); }
/** * Retrieves a {@link Label} from the label cache given a fully-qualified resource identifier * name. * * @param resourceName The fully-qualified resource identifier, such as * "com.android.deskclock:id/analog_appwidget", as provided by {@link * AccessibilityNodeInfo#getViewIdResourceName()} * @return The {@link Label} matching the provided identifier, or {@code null} if no such label * exists or has not yet been fetched from storage */ public Label getLabelForViewIdFromCache(String resourceName) { if (!isInitialized()) { return null; } Pair<String, String> parsedId = splitResourceName(resourceName); if (parsedId == null) { return null; } Label search = new Label(parsedId.first, null, parsedId.second, null, null, 0, null, 0); Label result = mLabelCache.ceiling(search); // TODO: This can be done much simplier with modifying equals in Label but want to wait // until BrailleBack is integrate to ensure compatibility if (result != null && search.getViewName() != null && search.getViewName().equals(result.getViewName()) && search.getPackageName() != null && search.getPackageName().equals(result.getPackageName())) { return result; } return null; }