android.util.ArrayMap#valueAt ( )源码实例Demo

下面列出了android.util.ArrayMap#valueAt ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: AndroidComponentPlugin   文件: ContextImpl.java
@Override
public void reloadSharedPreferences() {
    // Build the list of all per-context impls (i.e. caches) we know about
    ArrayList<SharedPreferencesImpl> spImpls = new ArrayList<>();
    synchronized (ContextImpl.class) {
        final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
        for (int i = 0; i < cache.size(); i++) {
            final SharedPreferencesImpl sp = cache.valueAt(i);
            if (sp != null) {
                spImpls.add(sp);
            }
        }
    }

    // Issue the reload outside the cache lock
    for (int i = 0; i < spImpls.size(); i++) {
        spImpls.get(i).startReloadIfChangedUnexpectedly();
    }
}
 
源代码2 项目: android_9.0.0_r45   文件: Transition.java
/**
 * Pauses this transition, sending out calls to {@link
 * TransitionListener#onTransitionPause(Transition)} to all listeners
 * and pausing all running animators started by this transition.
 *
 * @hide
 */
public void pause(View sceneRoot) {
    if (!mEnded) {
        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
        int numOldAnims = runningAnimators.size();
        if (sceneRoot != null) {
            WindowId windowId = sceneRoot.getWindowId();
            for (int i = numOldAnims - 1; i >= 0; i--) {
                AnimationInfo info = runningAnimators.valueAt(i);
                if (info.view != null && windowId != null && windowId.equals(info.windowId)) {
                    Animator anim = runningAnimators.keyAt(i);
                    anim.pause();
                }
            }
        }
        if (mListeners != null && mListeners.size() > 0) {
            ArrayList<TransitionListener> tmpListeners =
                    (ArrayList<TransitionListener>) mListeners.clone();
            int numListeners = tmpListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                tmpListeners.get(i).onTransitionPause(this);
            }
        }
        mPaused = true;
    }
}
 
/**
 * Dispatches the accessibility button availability changes to any registered callbacks.
 * This should be called on the service's main thread.
 */
void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {
    final ArrayMap<AccessibilityButtonCallback, Handler> entries;
    synchronized (mLock) {
        if (mCallbacks == null || mCallbacks.isEmpty()) {
            Slog.w(LOG_TAG,
                    "Received accessibility button availability change with no callbacks!");
            return;
        }

        // Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
        // modification.
        entries = new ArrayMap<>(mCallbacks);
    }

    for (int i = 0, count = entries.size(); i < count; i++) {
        final AccessibilityButtonCallback callback = entries.keyAt(i);
        final Handler handler = entries.valueAt(i);
        handler.post(() -> callback.onAvailabilityChanged(this, available));
    }
}
 
源代码4 项目: android_9.0.0_r45   文件: ConditionProviders.java
private Condition[] removeDuplicateConditions(String pkg, Condition[] conditions) {
    if (conditions == null || conditions.length == 0) return null;
    final int N = conditions.length;
    final ArrayMap<Uri, Condition> valid = new ArrayMap<Uri, Condition>(N);
    for (int i = 0; i < N; i++) {
        final Uri id = conditions[i].id;
        if (valid.containsKey(id)) {
            Slog.w(TAG, "Ignoring condition from " + pkg + " for duplicate id: " + id);
            continue;
        }
        valid.put(id, conditions[i]);
    }
    if (valid.size() == 0) return null;
    if (valid.size() == N) return conditions;
    final Condition[] rt = new Condition[valid.size()];
    for (int i = 0; i < rt.length; i++) {
        rt[i] = valid.valueAt(i);
    }
    return rt;
}
 
/**
 * Called when gesture detection becomes active or inactive
 * @hide
 */
public void onGestureDetectionActiveChanged(boolean active) {
    final ArrayMap<FingerprintGestureCallback, Handler> handlerMap;
    synchronized (mLock) {
        handlerMap = new ArrayMap<>(mCallbackHandlerMap);
    }
    int numListeners = handlerMap.size();
    for (int i = 0; i < numListeners; i++) {
        FingerprintGestureCallback callback = handlerMap.keyAt(i);
        Handler handler = handlerMap.valueAt(i);
        if (handler != null) {
            handler.post(() -> callback.onGestureDetectionAvailabilityChanged(active));
        } else {
            callback.onGestureDetectionAvailabilityChanged(active);
        }
    }
}
 
源代码6 项目: android_9.0.0_r45   文件: Transition.java
/**
 * Match start/end values by Adapter transitionName. Adds matched values to mStartValuesList
 * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using
 * startNames and endNames as a guide for which Views have unique transitionNames.
 */
private void matchNames(ArrayMap<View, TransitionValues> unmatchedStart,
        ArrayMap<View, TransitionValues> unmatchedEnd,
        ArrayMap<String, View> startNames, ArrayMap<String, View> endNames) {
    int numStartNames = startNames.size();
    for (int i = 0; i < numStartNames; i++) {
        View startView = startNames.valueAt(i);
        if (startView != null && isValidTarget(startView)) {
            View endView = endNames.get(startNames.keyAt(i));
            if (endView != null && isValidTarget(endView)) {
                TransitionValues startValues = unmatchedStart.get(startView);
                TransitionValues endValues = unmatchedEnd.get(endView);
                if (startValues != null && endValues != null) {
                    mStartValuesList.add(startValues);
                    mEndValuesList.add(endValues);
                    unmatchedStart.remove(startView);
                    unmatchedEnd.remove(endView);
                }
            }
        }
    }
}
 
/**
 * Iterates over the shared elements and adds them to the members in order.
 * Shared elements that are nested in other shared elements are placed after the
 * elements that they are nested in. This means that layout ordering can be done
 * from first to last.
 *
 * @param sharedElements The map of transition names to shared elements to set into
 *                       the member fields.
 */
private void setSharedElements(ArrayMap<String, View> sharedElements) {
    boolean isFirstRun = true;
    while (!sharedElements.isEmpty()) {
        final int numSharedElements = sharedElements.size();
        for (int i = numSharedElements - 1; i >= 0; i--) {
            final View view = sharedElements.valueAt(i);
            final String name = sharedElements.keyAt(i);
            if (isFirstRun && (view == null || !view.isAttachedToWindow() || name == null)) {
                sharedElements.removeAt(i);
            } else if (!isNested(view, sharedElements)) {
                mSharedElementNames.add(name);
                mSharedElements.add(view);
                sharedElements.removeAt(i);
            }
        }
        isFirstRun = false;
    }
}
 
源代码8 项目: android_9.0.0_r45   文件: ManagedServices.java
private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
    boolean removed = false;
    final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(uninstalledUserId);
    if (approvedByType != null) {
        int M = approvedByType.size();
        for (int j = 0; j < M; j++) {
            final ArraySet<String> approved = approvedByType.valueAt(j);
            int O = approved.size();
            for (int k = O - 1; k >= 0; k--) {
                final String packageOrComponent = approved.valueAt(k);
                final String packageName = getPackageName(packageOrComponent);
                if (TextUtils.equals(pkg, packageName)) {
                    approved.removeAt(k);
                    if (DEBUG) {
                        Slog.v(TAG, "Removing " + packageOrComponent
                                + " from approved list; uninstalled");
                    }
                }
            }
        }
    }
    return removed;
}
 
源代码9 项目: android_9.0.0_r45   文件: SnoozeHelper.java
protected @NonNull List<NotificationRecord> getSnoozed() {
    List<NotificationRecord> snoozedForUser = new ArrayList<>();
    int[] userIds = mUserProfiles.getCurrentProfileIds();
    if (userIds != null) {
        final int N = userIds.length;
        for (int i = 0; i < N; i++) {
            final ArrayMap<String, ArrayMap<String, NotificationRecord>> snoozedPkgs =
                    mSnoozedNotifications.get(userIds[i]);
            if (snoozedPkgs != null) {
                final int M = snoozedPkgs.size();
                for (int j = 0; j < M; j++) {
                    final ArrayMap<String, NotificationRecord> records = snoozedPkgs.valueAt(j);
                    if (records != null) {
                        snoozedForUser.addAll(records.values());
                    }
                }
            }
        }
    }
    return snoozedForUser;
}
 
源代码10 项目: android_9.0.0_r45   文件: SnoozeHelper.java
protected boolean cancel(int userId, boolean includeCurrentProfiles) {
    int[] userIds = {userId};
    if (includeCurrentProfiles) {
        userIds = mUserProfiles.getCurrentProfileIds();
    }
    final int N = userIds.length;
    for (int i = 0; i < N; i++) {
        final ArrayMap<String, ArrayMap<String, NotificationRecord>> snoozedPkgs =
                mSnoozedNotifications.get(userIds[i]);
        if (snoozedPkgs != null) {
            final int M = snoozedPkgs.size();
            for (int j = 0; j < M; j++) {
                final ArrayMap<String, NotificationRecord> records = snoozedPkgs.valueAt(j);
                if (records != null) {
                    int P = records.size();
                    for (int k = 0; k < P; k++) {
                        records.valueAt(k).isCanceled = true;
                    }
                }
            }
            return true;
        }
    }
    return false;
}
 
源代码11 项目: android_9.0.0_r45   文件: ManagedServices.java
public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
    out.startTag(null, getConfig().xmlTag);

    out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));

    if (forBackup) {
        trimApprovedListsAccordingToInstalledServices();
    }

    final int N = mApproved.size();
    for (int i = 0 ; i < N; i++) {
        final int userId = mApproved.keyAt(i);
        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
        if (approvedByType != null) {
            final int M = approvedByType.size();
            for (int j = 0; j < M; j++) {
                final boolean isPrimary = approvedByType.keyAt(j);
                final Set<String> approved = approvedByType.valueAt(j);
                if (approved != null) {
                    String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
                    out.startTag(null, TAG_MANAGED_SERVICES);
                    out.attribute(null, ATT_APPROVED_LIST, allowedItems);
                    out.attribute(null, ATT_USER_ID, Integer.toString(userId));
                    out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
                    out.endTag(null, TAG_MANAGED_SERVICES);

                    if (!forBackup && isPrimary) {
                        // Also write values to settings, for observers who haven't migrated yet
                        Settings.Secure.putStringForUser(mContext.getContentResolver(),
                                getConfig().secureSettingName, allowedItems, userId);
                    }

                }
            }
        }
    }

    out.endTag(null, getConfig().xmlTag);
}
 
源代码12 项目: android_9.0.0_r45   文件: AccessibilityService.java
/**
 * Dispatches magnification changes to any registered listeners. This
 * should be called on the service's main thread.
 */
void dispatchMagnificationChanged(final @NonNull Region region, final float scale,
        final float centerX, final float centerY) {
    final ArrayMap<OnMagnificationChangedListener, Handler> entries;
    synchronized (mLock) {
        if (mListeners == null || mListeners.isEmpty()) {
            Slog.d(LOG_TAG, "Received magnification changed "
                    + "callback with no listeners registered!");
            setMagnificationCallbackEnabled(false);
            return;
        }

        // Listeners may remove themselves. Perform a shallow copy to avoid concurrent
        // modification.
        entries = new ArrayMap<>(mListeners);
    }

    for (int i = 0, count = entries.size(); i < count; i++) {
        final OnMagnificationChangedListener listener = entries.keyAt(i);
        final Handler handler = entries.valueAt(i);
        if (handler != null) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    listener.onMagnificationChanged(MagnificationController.this,
                            region, scale, centerX, centerY);
                }
            });
        } else {
            // We're already on the main thread, just run the listener.
            listener.onMagnificationChanged(this, region, scale, centerX, centerY);
        }
    }
}
 
源代码13 项目: android_9.0.0_r45   文件: ManagedServices.java
public void dump(ProtoOutputStream proto, DumpFilter filter) {
    proto.write(ManagedServicesProto.CAPTION, getCaption());
    final int N = mApproved.size();
    for (int i = 0 ; i < N; i++) {
        final int userId = mApproved.keyAt(i);
        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
        if (approvedByType != null) {
            final int M = approvedByType.size();
            for (int j = 0; j < M; j++) {
                final boolean isPrimary = approvedByType.keyAt(j);
                final ArraySet<String> approved = approvedByType.valueAt(j);
                if (approvedByType != null && approvedByType.size() > 0) {
                    final long sToken = proto.start(ManagedServicesProto.APPROVED);
                    for (String s : approved) {
                        proto.write(ServiceProto.NAME, s);
                    }
                    proto.write(ServiceProto.USER_ID, userId);
                    proto.write(ServiceProto.IS_PRIMARY, isPrimary);
                    proto.end(sToken);
                }
            }
        }
    }

    for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
        if (filter != null && !filter.matches(cmpt)) continue;
        cmpt.writeToProto(proto, ManagedServicesProto.ENABLED);
    }

    for (ManagedServiceInfo info : mServices) {
        if (filter != null && !filter.matches(info.component)) continue;
        info.writeToProto(proto, ManagedServicesProto.LIVE_SERVICES, this);
    }

    for (ComponentName name : mSnoozingForCurrentProfiles) {
        name.writeToProto(proto, ManagedServicesProto.SNOOZED);
    }
}
 
源代码14 项目: android_9.0.0_r45   文件: ActiveServices.java
private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses,
        boolean evenPersistent, boolean doit, boolean killProcess,
        ArrayMap<ComponentName, ServiceRecord> services) {
    boolean didSomething = false;
    for (int i = services.size() - 1; i >= 0; i--) {
        ServiceRecord service = services.valueAt(i);
        final boolean sameComponent = packageName == null
                || (service.packageName.equals(packageName)
                    && (filterByClasses == null
                        || filterByClasses.contains(service.name.getClassName())));
        if (sameComponent
                && (service.app == null || evenPersistent || !service.app.persistent)) {
            if (!doit) {
                return true;
            }
            didSomething = true;
            Slog.i(TAG, "  Force stopping service " + service);
            if (service.app != null) {
                service.app.removed = killProcess;
                if (!service.app.persistent) {
                    service.app.services.remove(service);
                    if (service.whitelistManager) {
                        updateWhitelistManagerLocked(service.app);
                    }
                }
            }
            service.app = null;
            service.isolatedProc = null;
            if (mTmpCollectionResults == null) {
                mTmpCollectionResults = new ArrayList<>();
            }
            mTmpCollectionResults.add(service);
        }
    }
    return didSomething;
}
 
源代码15 项目: android_9.0.0_r45   文件: Transition.java
/**
 * Force the transition to move to its end state, ending all the animators.
 *
 * @hide
 */
void forceToEnd(ViewGroup sceneRoot) {
    ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
    int numOldAnims = runningAnimators.size();
    if (sceneRoot != null) {
        WindowId windowId = sceneRoot.getWindowId();
        for (int i = numOldAnims - 1; i >= 0; i--) {
            AnimationInfo info = runningAnimators.valueAt(i);
            if (info.view != null && windowId != null && windowId.equals(info.windowId)) {
                Animator anim = runningAnimators.keyAt(i);
                anim.end();
            }
        }
    }
}
 
源代码16 项目: android_9.0.0_r45   文件: ManagedServices.java
protected List<String> getAllowedPackages(int userId) {
    final List<String> allowedPackages = new ArrayList<>();
    final ArrayMap<Boolean, ArraySet<String>> allowedByType =
            mApproved.getOrDefault(userId, new ArrayMap<>());
    for (int i = 0; i < allowedByType.size(); i++) {
        final ArraySet<String> allowed = allowedByType.valueAt(i);
        for (int j = 0; j < allowed.size(); j++) {
            String pkgName = getPackageName(allowed.valueAt(j));
            if (!TextUtils.isEmpty(pkgName)) {
                allowedPackages.add(pkgName);
            }
        }
    }
    return allowedPackages;
}
 
源代码17 项目: android_9.0.0_r45   文件: ShortcutPackage.java
@Override
public JSONObject dumpCheckin(boolean clear) throws JSONException {
    final JSONObject result = super.dumpCheckin(clear);

    int numDynamic = 0;
    int numPinned = 0;
    int numManifest = 0;
    int numBitmaps = 0;
    long totalBitmapSize = 0;

    final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
    final int size = shortcuts.size();
    for (int i = 0; i < size; i++) {
        final ShortcutInfo si = shortcuts.valueAt(i);

        if (si.isDynamic()) numDynamic++;
        if (si.isDeclaredInManifest()) numManifest++;
        if (si.isPinned()) numPinned++;

        if (si.getBitmapPath() != null) {
            numBitmaps++;
            totalBitmapSize += new File(si.getBitmapPath()).length();
        }
    }

    result.put(KEY_DYNAMIC, numDynamic);
    result.put(KEY_MANIFEST, numManifest);
    result.put(KEY_PINNED, numPinned);
    result.put(KEY_BITMAPS, numBitmaps);
    result.put(KEY_BITMAP_BYTES, totalBitmapSize);

    // TODO Log update frequency too.

    return result;
}
 
源代码18 项目: Study_Android_Demo   文件: SettingsState.java
private void doWriteState() {
    boolean wroteState = false;
    final int version;
    final ArrayMap<String, Setting> settings;

    synchronized (mLock) {
        version = mVersion;
        settings = new ArrayMap<>(mSettings);
        mDirty = false;
        mWriteScheduled = false;
    }

    synchronized (mWriteLock) {
        if (DEBUG_PERSISTENCE) {
            Slog.i(LOG_TAG, "[PERSIST START]");
        }

        AtomicFile destination = new AtomicFile(mStatePersistFile);
        FileOutputStream out = null;
        try {
            out = destination.startWrite();

            XmlSerializer serializer = Xml.newSerializer();
            serializer.setOutput(out, StandardCharsets.UTF_8.name());
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
                    true);
            serializer.startDocument(null, true);
            serializer.startTag(null, TAG_SETTINGS);
            serializer.attribute(null, ATTR_VERSION, String.valueOf(version));

            final int settingCount = settings.size();
            for (int i = 0; i < settingCount; i++) {
                Setting setting = settings.valueAt(i);

                writeSingleSetting(mVersion, serializer, setting.getId(), setting.getName(),
                        setting.getValue(), setting.getDefaultValue(), setting.getPackageName(),
                        setting.getTag(), setting.isDefaultFromSystem());

                if (DEBUG_PERSISTENCE) {
                    Slog.i(LOG_TAG, "[PERSISTED]" + setting.getName() + "="
                            + setting.getValue());
                }
            }

            serializer.endTag(null, TAG_SETTINGS);
            serializer.endDocument();
            destination.finishWrite(out);

            wroteState = true;

            if (DEBUG_PERSISTENCE) {
                Slog.i(LOG_TAG, "[PERSIST END]");
            }
        } catch (Throwable t) {
            Slog.wtf(LOG_TAG, "Failed to write settings, restoring backup", t);
            destination.failWrite(out);
        } finally {
            IoUtils.closeQuietly(out);
        }
    }

    if (wroteState) {
        synchronized (mLock) {
            addHistoricalOperationLocked(HISTORICAL_OPERATION_PERSIST, null);
        }
    }
}
 
源代码19 项目: android_9.0.0_r45   文件: AutofillManager.java
private void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) {
    synchronized (mLock) {
        if (sessionId != mSessionId) {
            return;
        }

        final AutofillClient client = getClient();
        if (client == null) {
            return;
        }

        final int itemCount = ids.size();
        int numApplied = 0;
        ArrayMap<View, SparseArray<AutofillValue>> virtualValues = null;
        final View[] views = client.autofillClientFindViewsByAutofillIdTraversal(
                Helper.toArray(ids));

        ArrayList<AutofillId> failedIds = null;

        for (int i = 0; i < itemCount; i++) {
            final AutofillId id = ids.get(i);
            final AutofillValue value = values.get(i);
            final int viewId = id.getViewId();
            final View view = views[i];
            if (view == null) {
                // Most likely view has been removed after the initial request was sent to the
                // the service; this is fine, but we need to update the view status in the
                // server side so it can be triggered again.
                Log.d(TAG, "autofill(): no View with id " + id);
                if (failedIds == null) {
                    failedIds = new ArrayList<>();
                }
                failedIds.add(id);
                continue;
            }
            if (id.isVirtual()) {
                if (virtualValues == null) {
                    // Most likely there will be just one view with virtual children.
                    virtualValues = new ArrayMap<>(1);
                }
                SparseArray<AutofillValue> valuesByParent = virtualValues.get(view);
                if (valuesByParent == null) {
                    // We don't know the size yet, but usually it will be just a few fields...
                    valuesByParent = new SparseArray<>(5);
                    virtualValues.put(view, valuesByParent);
                }
                valuesByParent.put(id.getVirtualChildId(), value);
            } else {
                // Mark the view as to be autofilled with 'value'
                if (mLastAutofilledData == null) {
                    mLastAutofilledData = new ParcelableMap(itemCount - i);
                }
                mLastAutofilledData.put(id, value);

                view.autofill(value);

                // Set as autofilled if the values match now, e.g. when the value was updated
                // synchronously.
                // If autofill happens async, the view is set to autofilled in
                // notifyValueChanged.
                setAutofilledIfValuesIs(view, value);

                numApplied++;
            }
        }

        if (failedIds != null) {
            if (sVerbose) {
                Log.v(TAG, "autofill(): total failed views: " + failedIds);
            }
            try {
                mService.setAutofillFailure(mSessionId, failedIds, mContext.getUserId());
            } catch (RemoteException e) {
                // In theory, we could ignore this error since it's not a big deal, but
                // in reality, we rather crash the app anyways, as the failure could be
                // a consequence of something going wrong on the server side...
                e.rethrowFromSystemServer();
            }
        }

        if (virtualValues != null) {
            for (int i = 0; i < virtualValues.size(); i++) {
                final View parent = virtualValues.keyAt(i);
                final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
                parent.autofill(childrenValues);
                numApplied += childrenValues.size();
                // TODO: we should provide a callback so the parent can call failures; something
                // like notifyAutofillFailed(View view, int[] childrenIds);
            }
        }

        mMetricsLogger.write(newLog(MetricsEvent.AUTOFILL_DATASET_APPLIED)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, itemCount)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, numApplied));
    }
}
 
源代码20 项目: android_9.0.0_r45   文件: ShortcutPackage.java
public void dump(@NonNull PrintWriter pw, @NonNull String prefix, DumpFilter filter) {
    pw.println();

    pw.print(prefix);
    pw.print("Package: ");
    pw.print(getPackageName());
    pw.print("  UID: ");
    pw.print(mPackageUid);
    pw.println();

    pw.print(prefix);
    pw.print("  ");
    pw.print("Calls: ");
    pw.print(getApiCallCount(/*unlimited=*/ false));
    pw.println();

    // getApiCallCount() may have updated mLastKnownForegroundElapsedTime.
    pw.print(prefix);
    pw.print("  ");
    pw.print("Last known FG: ");
    pw.print(mLastKnownForegroundElapsedTime);
    pw.println();

    // This should be after getApiCallCount(), which may update it.
    pw.print(prefix);
    pw.print("  ");
    pw.print("Last reset: [");
    pw.print(mLastResetTime);
    pw.print("] ");
    pw.print(ShortcutService.formatTime(mLastResetTime));
    pw.println();

    getPackageInfo().dump(pw, prefix + "  ");
    pw.println();

    pw.print(prefix);
    pw.println("  Shortcuts:");
    long totalBitmapSize = 0;
    final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts;
    final int size = shortcuts.size();
    for (int i = 0; i < size; i++) {
        final ShortcutInfo si = shortcuts.valueAt(i);
        pw.println(si.toDumpString(prefix + "    "));
        if (si.getBitmapPath() != null) {
            final long len = new File(si.getBitmapPath()).length();
            pw.print(prefix);
            pw.print("      ");
            pw.print("bitmap size=");
            pw.println(len);

            totalBitmapSize += len;
        }
    }
    pw.print(prefix);
    pw.print("  ");
    pw.print("Total bitmap size: ");
    pw.print(totalBitmapSize);
    pw.print(" (");
    pw.print(Formatter.formatFileSize(mShortcutUser.mService.mContext, totalBitmapSize));
    pw.println(")");
}