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

Commit ddd19b35 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move some common functionality to AbstractResolverComparator."

parents 1b46c8c8 93562442
Loading
Loading
Loading
Loading
+116 −9
Original line number Original line Diff line number Diff line
package com.android.internal.app;
package com.android.internal.app;


import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.UserHandle;
import android.util.Log;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Comparator;
import java.util.List;
import java.util.List;


@@ -10,20 +18,102 @@ import java.util.List;
 */
 */
abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> {
abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> {


    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;

    protected AfterCompute mAfterCompute;
    protected AfterCompute mAfterCompute;
    protected final PackageManager mPm;
    protected final UsageStatsManager mUsm;
    protected String[] mAnnotations;
    protected String mContentType;

    // True if the current share is a link.
    private final boolean mHttp;
    // can be null if mHttp == false or current user has no default browser package
    private final String mDefaultBrowserPackageName;

    AbstractResolverComparator(Context context, Intent intent) {
        String scheme = intent.getScheme();
        mHttp = "http".equals(scheme) || "https".equals(scheme);
        mContentType = intent.getType();
        getContentAnnotations(intent);

        mPm = context.getPackageManager();
        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        mDefaultBrowserPackageName = mHttp
                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
                : null;
    }

    // get annotations of content from intent.
    private void getContentAnnotations(Intent intent) {
        ArrayList<String> annotations = intent.getStringArrayListExtra(
                Intent.EXTRA_CONTENT_ANNOTATIONS);
        if (annotations != null) {
            int size = annotations.size();
            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
            }
            mAnnotations = new String[size];
            for (int i = 0; i < size; i++) {
                mAnnotations[i] = annotations.get(i);
            }
        }
    }


    /**
    /**
     * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting.
     * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting.
     */
     */
    public interface AfterCompute {
    interface AfterCompute {


        public void afterCompute();
        void afterCompute();
    }
    }


    public void setCallBack(AfterCompute afterCompute) {
    void setCallBack(AfterCompute afterCompute) {
        mAfterCompute = afterCompute;
        mAfterCompute = afterCompute;
    }
    }


    @Override
    public final int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);

        // We want to put the one targeted to another user at the end of the dialog.
        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
        }
        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
            return -1;
        }

        if (mHttp) {
            // Special case: we want filters that match URI paths/schemes to be
            // ordered before others.  This is for the case when opening URIs,
            // to make native apps go above browsers - except for 1 even more special case
            // which is the default browser, as we want that to go above them all.
            if (isDefaultBrowser(lhs)) {
                return -1;
            }

            if (isDefaultBrowser(rhs)) {
                return 1;
            }
            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
            if (lhsSpecific != rhsSpecific) {
                return lhsSpecific ? -1 : 1;
            }
        }
        return compare(lhs, rhs);
    }

    /**
     * Delegated to when used as a {@link Comparator<ResolvedComponentInfo>} if there is not a
     * special case. The {@link ResolveInfo ResolveInfos} are the first {@link ResolveInfo} in
     * {@link ResolvedComponentInfo#getResolveInfoAt(int)} from the parameters of {@link
     * #compare(ResolvedComponentInfo, ResolvedComponentInfo)}
     */
    abstract int compare(ResolveInfo lhs, ResolveInfo rhs);

    /**
    /**
     * Computes features for each target. This will be called before calls to {@link
     * Computes features for each target. This will be called before calls to {@link
     * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the
     * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the
@@ -31,19 +121,22 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
     * ComponentName}, so the implementation will have to be prepared to identify a {@link
     * ComponentName}, so the implementation will have to be prepared to identify a {@link
     * ResolvedComponentInfo} by {@link ComponentName}.
     * ResolvedComponentInfo} by {@link ComponentName}.
     */
     */
    public abstract void compute(List<ResolvedComponentInfo> targets);
    abstract void compute(List<ResolvedComponentInfo> targets);


    /**
    /**
     * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo}
     * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo}
     * when {@link #compute(List)} was called before this.
     * when {@link #compute(List)} was called before this.
     */
     */
    public abstract float getScore(ComponentName name);
    abstract float getScore(ComponentName name);


    /**
    /**
     * Reports to UsageStats what was chosen.
     * Reports to UsageStats what was chosen.
     */
     */
    // TODO(b/129014961) Move implemetation here and make final.
    final void updateChooserCounts(String packageName, int userId, String action) {
    public abstract void updateChooserCounts(String packageName, int userId, String action);
        if (mUsm != null) {
            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
        }
    }


    /**
    /**
     * Updates the model used to rank the componentNames.
     * Updates the model used to rank the componentNames.
@@ -53,11 +146,25 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
     *
     *
     * @param componentName the component that the user clicked
     * @param componentName the component that the user clicked
     */
     */
    public void updateModel(ComponentName componentName) {
    void updateModel(ComponentName componentName) {
    }
    }


    /**
    /**
     * Called when the {@link ResolverActivity} is destroyed.
     * Called when the {@link ResolverActivity} is destroyed.
     */
     */
    public abstract void destroy();
    abstract void destroy();

    private boolean isDefaultBrowser(ResolveInfo ri) {
        // It makes sense to prefer the default browser
        // only if the targeted user is the current user
        if (ri.targetUserId != UserHandle.USER_CURRENT) {
            return false;
        }

        if (ri.activityInfo.packageName != null
                    && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
            return true;
        }
        return false;
    }
}
}
+2 −87
Original line number Original line Diff line number Diff line
@@ -60,8 +60,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator


    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;


    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;

    // One week
    // One week
    private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 7;
    private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 7;


@@ -80,11 +78,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
    private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
    private static final int WATCHDOG_TIMEOUT_MILLIS = 500;


    private final Collator mCollator;
    private final Collator mCollator;
    private final boolean mHttp;
    // can be null if mHttp == false or current user has no default browser package
    private final String mDefaultBrowserPackageName;
    private final PackageManager mPm;
    private final UsageStatsManager mUsm;
    private final Map<String, UsageStats> mStats;
    private final Map<String, UsageStats> mStats;
    private final long mCurrentTime;
    private final long mCurrentTime;
    private final long mSinceTime;
    private final long mSinceTime;
@@ -92,8 +85,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
    private final String mReferrerPackage;
    private final String mReferrerPackage;
    private final Object mLock = new Object();
    private final Object mLock = new Object();
    private ArrayList<ResolverTarget> mTargets;
    private ArrayList<ResolverTarget> mTargets;
    private String mContentType;
    private String[] mAnnotations;
    private String mAction;
    private String mAction;
    private ComponentName mResolvedRankerName;
    private ComponentName mResolvedRankerName;
    private ComponentName mRankerServiceName;
    private ComponentName mRankerServiceName;
@@ -155,43 +146,17 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator


    public ResolverRankerServiceResolverComparator(Context context, Intent intent,
    public ResolverRankerServiceResolverComparator(Context context, Intent intent,
                String referrerPackage, AfterCompute afterCompute) {
                String referrerPackage, AfterCompute afterCompute) {
        super(context, intent);
        mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
        mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
        String scheme = intent.getScheme();
        mHttp = "http".equals(scheme) || "https".equals(scheme);
        mReferrerPackage = referrerPackage;
        mReferrerPackage = referrerPackage;
        mAfterCompute = afterCompute;
        mAfterCompute = afterCompute;
        mContext = context;
        mContext = context;


        mPm = context.getPackageManager();
        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);

        mCurrentTime = System.currentTimeMillis();
        mCurrentTime = System.currentTimeMillis();
        mSinceTime = mCurrentTime - USAGE_STATS_PERIOD;
        mSinceTime = mCurrentTime - USAGE_STATS_PERIOD;
        mStats = mUsm.queryAndAggregateUsageStats(mSinceTime, mCurrentTime);
        mStats = mUsm.queryAndAggregateUsageStats(mSinceTime, mCurrentTime);
        mContentType = intent.getType();
        getContentAnnotations(intent);
        mAction = intent.getAction();
        mAction = intent.getAction();
        mRankerServiceName = new ComponentName(mContext, this.getClass());
        mRankerServiceName = new ComponentName(mContext, this.getClass());

        mDefaultBrowserPackageName = mHttp
                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
                : null;
    }

    // get annotations of content from intent.
    private void getContentAnnotations(Intent intent) {
        ArrayList<String> annotations = intent.getStringArrayListExtra(
                Intent.EXTRA_CONTENT_ANNOTATIONS);
        if (annotations != null) {
            int size = annotations.size();
            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
            }
            mAnnotations = new String[size];
            for (int i = 0; i < size; i++) {
                mAnnotations[i] = annotations.get(i);
            }
        }
    }
    }


    // compute features for each target according to usage stats of targets.
    // compute features for each target according to usage stats of targets.
@@ -286,36 +251,7 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
    }
    }


    @Override
    @Override
    public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
    public int compare(ResolveInfo lhs, ResolveInfo rhs) {
        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);

        // We want to put the one targeted to another user at the end of the dialog.
        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
        }
        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
            return -1;
        }

        if (mHttp) {
            // Special case: we want filters that match URI paths/schemes to be
            // ordered before others.  This is for the case when opening URIs,
            // to make native apps go above browsers - except for 1 even more special case
            // which is the default browser, as we want that to go above them all.
            if (isDefaultBrowser(lhs)) {
                return -1;
            }
            if (isDefaultBrowser(rhs)) {
                return 1;
            }
            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
            if (lhsSpecific != rhsSpecific) {
                return lhsSpecific ? -1 : 1;
            }
        }

        if (mStats != null) {
        if (mStats != null) {
            final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
            final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
                    lhs.activityInfo.packageName, lhs.activityInfo.name));
                    lhs.activityInfo.packageName, lhs.activityInfo.name));
@@ -349,13 +285,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
        return 0;
        return 0;
    }
    }


    @Override
    public void updateChooserCounts(String packageName, int userId, String action) {
        if (mUsm != null) {
            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
        }
    }

    // update ranking model when the connection to it is valid.
    // update ranking model when the connection to it is valid.
    @Override
    @Override
    public void updateModel(ComponentName componentName) {
    public void updateModel(ComponentName componentName) {
@@ -407,20 +336,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
        }
        }
    }
    }


    private boolean isDefaultBrowser(ResolveInfo ri) {
        // It makes sense to prefer the default browser
        // only if the targeted user is the current user
        if (ri.targetUserId != UserHandle.USER_CURRENT) {
            return false;
        }

        if (ri.activityInfo.packageName != null
                && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
            return true;
        }
        return false;
    }

    // records metrics for evaluation.
    // records metrics for evaluation.
    private void logMetrics(int selectedPos) {
    private void logMetrics(int selectedPos) {
        if (mRankerServiceName != null) {
        if (mRankerServiceName != null) {