Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b431d715 authored by Kang Li's avatar Kang Li Committed by Android (Google) Code Review
Browse files

Merge "Add Sharing Histories to UsageStatsManager."

parents 06fd71ab 53b4314a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -34,4 +34,6 @@ interface IUsageStatsManager {
    boolean isAppInactive(String packageName, int userId);
    void whitelistAppTemporarily(String packageName, long duration, int userId);
    void onCarrierPrivilegedAppsChanged();
    void reportChooserSelection(String packageName, int userId, String contentType,
            in String[] annotations, String action);
}
+40 −0
Original line number Diff line number Diff line
@@ -85,6 +85,12 @@ public final class UsageEvents implements Parcelable {
         */
        public static final int SHORTCUT_INVOCATION = 8;

        /**
         * An event type denoting that a package was selected by the user for ChooserActivity.
         * @hide
         */
        public static final int CHOOSER_ACTION = 9;

        /**
         * {@hide}
         */
@@ -118,6 +124,27 @@ public final class UsageEvents implements Parcelable {
         */
        public String mShortcutId;

        /**
         * Action type passed to ChooserActivity
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String mAction;

        /**
         * Content type passed to ChooserActivity.
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String mContentType;

        /**
         * Content annotations passed to ChooserActivity.
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String[] mContentAnnotations;

        /**
         * The package name of the source of this event.
         */
@@ -307,6 +334,11 @@ public final class UsageEvents implements Parcelable {
            case Event.SHORTCUT_INVOCATION:
                p.writeString(event.mShortcutId);
                break;
            case Event.CHOOSER_ACTION:
                p.writeString(event.mAction);
                p.writeString(event.mContentType);
                p.writeStringArray(event.mContentAnnotations);
                break;
        }
    }

@@ -333,6 +365,9 @@ public final class UsageEvents implements Parcelable {
        // Fill out the event-dependant fields.
        eventOut.mConfiguration = null;
        eventOut.mShortcutId = null;
        eventOut.mAction = null;
        eventOut.mContentType = null;
        eventOut.mContentAnnotations = null;

        switch (eventOut.mEventType) {
            case Event.CONFIGURATION_CHANGE:
@@ -342,6 +377,11 @@ public final class UsageEvents implements Parcelable {
            case Event.SHORTCUT_INVOCATION:
                eventOut.mShortcutId = p.readString();
                break;
            case Event.CHOOSER_ACTION:
                eventOut.mAction = p.readString();
                eventOut.mContentType = p.readString();
                eventOut.mContentAnnotations = p.createStringArray();
                break;
        }
    }

+62 −0
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package android.app.usage;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;

/**
 * Contains usage statistics for an app package for a specific
@@ -61,6 +63,11 @@ public final class UsageStats implements Parcelable {
     */
    public int mLastEvent;

    /**
     * {@hide}
     */
    public ArrayMap<String, ArrayMap<String, Integer>> mChooserCounts;

    /**
     * {@hide}
     */
@@ -75,6 +82,7 @@ public final class UsageStats implements Parcelable {
        mTotalTimeInForeground = stats.mTotalTimeInForeground;
        mLaunchCount = stats.mLaunchCount;
        mLastEvent = stats.mLastEvent;
        mChooserCounts = stats.mChooserCounts;
    }

    public String getPackageName() {
@@ -142,6 +150,26 @@ public final class UsageStats implements Parcelable {
        mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
        mTotalTimeInForeground += right.mTotalTimeInForeground;
        mLaunchCount += right.mLaunchCount;
        if (mChooserCounts == null) {
            mChooserCounts = right.mChooserCounts;
        } else if (right.mChooserCounts != null) {
            final int chooserCountsSize = right.mChooserCounts.size();
            for (int i = 0; i < chooserCountsSize; i++) {
                String action = right.mChooserCounts.keyAt(i);
                ArrayMap<String, Integer> counts = right.mChooserCounts.valueAt(i);
                if (!mChooserCounts.containsKey(action) || mChooserCounts.get(action) == null) {
                    mChooserCounts.put(action, counts);
                    continue;
                }
                final int annotationSize = counts.size();
                for (int j = 0; j < annotationSize; j++) {
                    String key = counts.keyAt(j);
                    int rightValue = counts.valueAt(j);
                    int leftValue = mChooserCounts.get(action).getOrDefault(key, 0);
                    mChooserCounts.get(action).put(key, leftValue + rightValue);
                }
            }
        }
    }

    @Override
@@ -158,6 +186,21 @@ public final class UsageStats implements Parcelable {
        dest.writeLong(mTotalTimeInForeground);
        dest.writeInt(mLaunchCount);
        dest.writeInt(mLastEvent);
        Bundle allCounts = new Bundle();
        if (mChooserCounts != null) {
            final int chooserCountSize = mChooserCounts.size();
            for (int i = 0; i < chooserCountSize; i++) {
                String action = mChooserCounts.keyAt(i);
                ArrayMap<String, Integer> counts = mChooserCounts.valueAt(i);
                Bundle currentCounts = new Bundle();
                final int annotationSize = counts.size();
                for (int j = 0; j < annotationSize; j++) {
                    currentCounts.putInt(counts.keyAt(j), counts.valueAt(j));
                }
                allCounts.putBundle(action, currentCounts);
            }
        }
        dest.writeBundle(allCounts);
    }

    public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() {
@@ -171,6 +214,25 @@ public final class UsageStats implements Parcelable {
            stats.mTotalTimeInForeground = in.readLong();
            stats.mLaunchCount = in.readInt();
            stats.mLastEvent = in.readInt();
            Bundle allCounts = in.readBundle();
            if (allCounts != null) {
                stats.mChooserCounts = new ArrayMap<>();
                for (String action : allCounts.keySet()) {
                    if (!stats.mChooserCounts.containsKey(action)) {
                        ArrayMap<String, Integer> newCounts = new ArrayMap<>();
                        stats.mChooserCounts.put(action, newCounts);
                    }
                    Bundle currentCounts = allCounts.getBundle(action);
                    if (currentCounts != null) {
                        for (String key : currentCounts.keySet()) {
                            int value = currentCounts.getInt(key);
                            if (value > 0) {
                                stats.mChooserCounts.get(action).put(key, value);
                            }
                        }
                    }
                }
            }
            return stats;
        }

+19 −0
Original line number Diff line number Diff line
@@ -278,4 +278,23 @@ public final class UsageStatsManager {
        } catch (RemoteException re) {
        }
    }

    /**
     * Reports a Chooser action to the UsageStatsManager.
     *
     * @param packageName The package name of the app that is selected.
     * @param userId The user id of who makes the selection.
     * @param contentType The type of the content, e.g., Image, Video, App.
     * @param annotations The annotations of the content, e.g., Game, Selfie.
     * @param action The action type of Intent that invokes ChooserActivity.
     * {@link UsageEvents}
     * @hide
     */
    public void reportChooserSelection(String packageName, int userId, String contentType,
                                       String[] annotations, String action) {
        try {
            mService.reportChooserSelection(packageName, userId, contentType, annotations, action);
        } catch (RemoteException re) {
        }
    }
}
+32 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.app;
import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.app.Activity;
import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -403,6 +404,7 @@ public class ChooserActivity extends ResolverActivity {
                }
            }
        }
        updateChooserCounts(target, mContentType);
        return super.onTargetSelected(target, alwaysCheck);
    }

@@ -547,21 +549,47 @@ public class ChooserActivity extends ResolverActivity {
        // Do nothing. We'll send the voice stuff ourselves.
    }

    void updateChooserCounts(TargetInfo info, String annotation) {
        if (info != null) {
            UsageStatsManager usageStatsManager =
                    (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
            if (usageStatsManager == null) {
                if (DEBUG) {
                    Log.d(TAG, "Can not start UsageStatsManager");
                }
                return;
            }
            final ResolveInfo ri = info.getResolveInfo();
            if (ri != null && ri.activityInfo != null) {
                usageStatsManager.reportChooserSelection(ri.activityInfo.packageName, getUserId(),
                        annotation, null, info.getResolvedIntent().getAction());
                if (DEBUG) {
                    Log.d(TAG, "ResolveInfo Package is" + ri.activityInfo.packageName);
                }
            } else if(DEBUG) {
                Log.d(TAG, "Can not log Chooser Counts of null ResovleInfo");
            }
        }
    }

    void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) {
        if (mRefinementResultReceiver != null) {
            mRefinementResultReceiver.destroy();
            mRefinementResultReceiver = null;
        }

        if (selectedTarget == null) {
            Log.e(TAG, "Refinement result intent did not match any known targets; canceling");
        } else if (!checkTargetSourceIntent(selectedTarget, matchingIntent)) {
            Log.e(TAG, "onRefinementResult: Selected target " + selectedTarget
                    + " cannot match refined source intent " + matchingIntent);
        } else if (super.onTargetSelected(selectedTarget.cloneFilledIn(matchingIntent, 0), false)) {
        } else {
            TargetInfo clonedTarget = selectedTarget.cloneFilledIn(matchingIntent, 0);
            if (super.onTargetSelected(clonedTarget, false)) {
                updateChooserCounts(clonedTarget, mContentType);
                finish();
                return;
            }
        }
        onRefinementCanceled();
    }

Loading