Merge "Move timeout from RankerResolverServiceComparator to abstract class." into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b6b549baf6
@@ -22,9 +22,14 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -35,6 +40,8 @@ import java.util.List;
|
||||
abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> {
|
||||
|
||||
private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "AbstractResolverComp";
|
||||
|
||||
private AfterCompute mAfterCompute;
|
||||
protected final PackageManager mPm;
|
||||
@@ -47,6 +54,46 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
|
||||
// can be null if mHttp == false or current user has no default browser package
|
||||
private final String mDefaultBrowserPackageName;
|
||||
|
||||
// message types
|
||||
static final int RANKER_SERVICE_RESULT = 0;
|
||||
static final int RANKER_RESULT_TIMEOUT = 1;
|
||||
|
||||
// timeout for establishing connections with a ResolverRankerService, collecting features and
|
||||
// predicting ranking scores.
|
||||
private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
|
||||
|
||||
protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case RANKER_SERVICE_RESULT:
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "RANKER_SERVICE_RESULT");
|
||||
}
|
||||
if (mHandler.hasMessages(RANKER_RESULT_TIMEOUT)) {
|
||||
if (msg.obj != null) {
|
||||
handleResultMessage(msg);
|
||||
} else {
|
||||
Log.e(TAG, "Receiving null prediction results.");
|
||||
}
|
||||
mHandler.removeMessages(RANKER_RESULT_TIMEOUT);
|
||||
afterCompute();
|
||||
}
|
||||
break;
|
||||
|
||||
case RANKER_RESULT_TIMEOUT:
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "RANKER_RESULT_TIMEOUT; unbinding services");
|
||||
}
|
||||
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
||||
afterCompute();
|
||||
break;
|
||||
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AbstractResolverComparator(Context context, Intent intent) {
|
||||
String scheme = intent.getScheme();
|
||||
mHttp = "http".equals(scheme) || "https".equals(scheme);
|
||||
@@ -142,9 +189,16 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
|
||||
* #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the
|
||||
* comparator for those calls. Note that {@link #getScore(ComponentName)} uses {@link
|
||||
* ComponentName}, so the implementation will have to be prepared to identify a {@link
|
||||
* ResolvedComponentInfo} by {@link ComponentName}.
|
||||
* ResolvedComponentInfo} by {@link ComponentName}. {@link #beforeCompute()} will be called
|
||||
* before doing any computing.
|
||||
*/
|
||||
abstract void compute(List<ResolvedComponentInfo> targets);
|
||||
final void compute(List<ResolvedComponentInfo> targets) {
|
||||
beforeCompute();
|
||||
doCompute(targets);
|
||||
}
|
||||
|
||||
/** Implementation of compute called after {@link #beforeCompute()}. */
|
||||
abstract void doCompute(List<ResolvedComponentInfo> targets);
|
||||
|
||||
/**
|
||||
* Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo}
|
||||
@@ -152,6 +206,9 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
|
||||
*/
|
||||
abstract float getScore(ComponentName name);
|
||||
|
||||
/** Handles result message sent to mHandler. */
|
||||
abstract void handleResultMessage(Message message);
|
||||
|
||||
/**
|
||||
* Reports to UsageStats what was chosen.
|
||||
*/
|
||||
@@ -172,10 +229,26 @@ abstract class AbstractResolverComparator implements Comparator<ResolvedComponen
|
||||
void updateModel(ComponentName componentName) {
|
||||
}
|
||||
|
||||
/** Called before {@link #doCompute(List)}. Sets up 500ms timeout. */
|
||||
void beforeCompute() {
|
||||
if (DEBUG) Log.d(TAG, "Setting watchdog timer for " + WATCHDOG_TIMEOUT_MILLIS + "ms");
|
||||
if (mHandler == null) {
|
||||
Log.d(TAG, "Error: Handler is Null; Needs to be initialized.");
|
||||
return;
|
||||
}
|
||||
mHandler.sendEmptyMessageDelayed(RANKER_RESULT_TIMEOUT, WATCHDOG_TIMEOUT_MILLIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the {@link ResolverActivity} is destroyed.
|
||||
* Called when the {@link ResolverActivity} is destroyed. This calls {@link #afterCompute()}. If
|
||||
* this call needs to happen at a different time during destroy, the method should be
|
||||
* overridden.
|
||||
*/
|
||||
abstract void destroy();
|
||||
void destroy() {
|
||||
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
||||
mHandler.removeMessages(RANKER_RESULT_TIMEOUT);
|
||||
afterCompute();
|
||||
}
|
||||
|
||||
private boolean isDefaultBrowser(ResolveInfo ri) {
|
||||
// It makes sense to prefer the default browser
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Message;
|
||||
import android.os.UserHandle;
|
||||
import android.view.textclassifier.Log;
|
||||
|
||||
@@ -73,7 +74,7 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
||||
}
|
||||
|
||||
@Override
|
||||
void compute(List<ResolvedComponentInfo> targets) {
|
||||
void doCompute(List<ResolvedComponentInfo> targets) {
|
||||
List<AppTarget> appTargets = new ArrayList<>();
|
||||
for (ResolvedComponentInfo target : targets) {
|
||||
appTargets.add(new AppTarget.Builder(new AppTargetId(target.name.flattenToString()))
|
||||
@@ -82,14 +83,23 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
||||
}
|
||||
mAppPredictor.sortTargets(appTargets, mContext.getMainExecutor(),
|
||||
sortedAppTargets -> {
|
||||
for (int i = 0; i < sortedAppTargets.size(); i++) {
|
||||
mTargetRanks.put(new ComponentName(sortedAppTargets.get(i).getPackageName(),
|
||||
sortedAppTargets.get(i).getClassName()), i);
|
||||
}
|
||||
afterCompute();
|
||||
Message msg =
|
||||
Message.obtain(mHandler, RANKER_SERVICE_RESULT, sortedAppTargets);
|
||||
msg.sendToTarget();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleResultMessage(Message msg) {
|
||||
if (msg.what == RANKER_SERVICE_RESULT) {
|
||||
final List<AppTarget> sortedAppTargets = (List<AppTarget>) msg.obj;
|
||||
for (int i = 0; i < sortedAppTargets.size(); i++) {
|
||||
mTargetRanks.put(new ComponentName(sortedAppTargets.get(i).getPackageName(),
|
||||
sortedAppTargets.get(i).getClassName()), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
float getScore(ComponentName name) {
|
||||
Integer rank = mTargetRanks.get(name);
|
||||
@@ -111,9 +121,4 @@ class AppPredictionServiceResolverComparator extends AbstractResolverComparator
|
||||
.setClassName(componentName.getClassName()).build(),
|
||||
ACTION_LAUNCH).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
void destroy() {
|
||||
// Do nothing. App Predictor destruction is handled by caller.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package com.android.internal.app;
|
||||
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -28,9 +27,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
@@ -67,10 +64,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
|
||||
private static final float RECENCY_MULTIPLIER = 2.f;
|
||||
|
||||
// message types
|
||||
private static final int RESOLVER_RANKER_SERVICE_RESULT = 0;
|
||||
private static final int RESOLVER_RANKER_RESULT_TIMEOUT = 1;
|
||||
|
||||
// timeout for establishing connections with a ResolverRankerService.
|
||||
private static final int CONNECTION_COST_TIMEOUT_MILLIS = 200;
|
||||
// timeout for establishing connections with a ResolverRankerService, collecting features and
|
||||
@@ -93,57 +86,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
private Context mContext;
|
||||
private CountDownLatch mConnectSignal;
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case RESOLVER_RANKER_SERVICE_RESULT:
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "RESOLVER_RANKER_SERVICE_RESULT");
|
||||
}
|
||||
if (mHandler.hasMessages(RESOLVER_RANKER_RESULT_TIMEOUT)) {
|
||||
if (msg.obj != null) {
|
||||
final List<ResolverTarget> receivedTargets =
|
||||
(List<ResolverTarget>) msg.obj;
|
||||
if (receivedTargets != null && mTargets != null
|
||||
&& receivedTargets.size() == mTargets.size()) {
|
||||
final int size = mTargets.size();
|
||||
boolean isUpdated = false;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final float predictedProb =
|
||||
receivedTargets.get(i).getSelectProbability();
|
||||
if (predictedProb != mTargets.get(i).getSelectProbability()) {
|
||||
mTargets.get(i).setSelectProbability(predictedProb);
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
if (isUpdated) {
|
||||
mRankerServiceName = mResolvedRankerName;
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Receiving null prediction results.");
|
||||
}
|
||||
mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
|
||||
afterCompute();
|
||||
}
|
||||
break;
|
||||
|
||||
case RESOLVER_RANKER_RESULT_TIMEOUT:
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "RESOLVER_RANKER_RESULT_TIMEOUT; unbinding services");
|
||||
}
|
||||
mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
|
||||
afterCompute();
|
||||
break;
|
||||
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ResolverRankerServiceResolverComparator(Context context, Intent intent,
|
||||
String referrerPackage, AfterCompute afterCompute) {
|
||||
super(context, intent);
|
||||
@@ -159,11 +101,35 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
setCallBack(afterCompute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleResultMessage(Message msg) {
|
||||
if (msg.what != RANKER_SERVICE_RESULT) {
|
||||
return;
|
||||
}
|
||||
final List<ResolverTarget> receivedTargets = (List<ResolverTarget>) msg.obj;
|
||||
if (receivedTargets != null && mTargets != null
|
||||
&& receivedTargets.size() == mTargets.size()) {
|
||||
final int size = mTargets.size();
|
||||
boolean isUpdated = false;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
final float predictedProb =
|
||||
receivedTargets.get(i).getSelectProbability();
|
||||
if (predictedProb != mTargets.get(i).getSelectProbability()) {
|
||||
mTargets.get(i).setSelectProbability(predictedProb);
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
if (isUpdated) {
|
||||
mRankerServiceName = mResolvedRankerName;
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
|
||||
}
|
||||
}
|
||||
|
||||
// compute features for each target according to usage stats of targets.
|
||||
@Override
|
||||
public void compute(List<ResolvedComponentInfo> targets) {
|
||||
reset();
|
||||
|
||||
public void doCompute(List<ResolvedComponentInfo> targets) {
|
||||
final long recentSinceTime = mCurrentTime - RECENCY_TIME_PERIOD;
|
||||
|
||||
float mostRecencyScore = 1.0f;
|
||||
@@ -322,8 +288,8 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
// unbind the service and clear unhandled messges.
|
||||
@Override
|
||||
public void destroy() {
|
||||
mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
|
||||
mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
|
||||
mHandler.removeMessages(RANKER_SERVICE_RESULT);
|
||||
mHandler.removeMessages(RANKER_RESULT_TIMEOUT);
|
||||
if (mConnection != null) {
|
||||
mContext.unbindService(mConnection);
|
||||
mConnection.destroy();
|
||||
@@ -417,15 +383,6 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
return null;
|
||||
}
|
||||
|
||||
// set a watchdog, to avoid waiting for ranking service for too long.
|
||||
private void startWatchDog(int timeOutLimit) {
|
||||
if (DEBUG) Log.d(TAG, "Setting watchdog timer for " + timeOutLimit + "ms");
|
||||
if (mHandler == null) {
|
||||
Log.d(TAG, "Error: Handler is Null; Needs to be initialized.");
|
||||
}
|
||||
mHandler.sendEmptyMessageDelayed(RESOLVER_RANKER_RESULT_TIMEOUT, timeOutLimit);
|
||||
}
|
||||
|
||||
private class ResolverRankerServiceConnection implements ServiceConnection {
|
||||
private final CountDownLatch mConnectSignal;
|
||||
|
||||
@@ -442,7 +399,7 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
}
|
||||
synchronized (mLock) {
|
||||
final Message msg = Message.obtain();
|
||||
msg.what = RESOLVER_RANKER_SERVICE_RESULT;
|
||||
msg.what = RANKER_SERVICE_RESULT;
|
||||
msg.obj = targets;
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
@@ -477,12 +434,13 @@ class ResolverRankerServiceResolverComparator extends AbstractResolverComparator
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
@Override
|
||||
void beforeCompute() {
|
||||
super.beforeCompute();
|
||||
mTargetsDict.clear();
|
||||
mTargets = null;
|
||||
mRankerServiceName = new ComponentName(mContext, this.getClass());
|
||||
mResolvedRankerName = null;
|
||||
startWatchDog(WATCHDOG_TIMEOUT_MILLIS);
|
||||
initRanker(mContext);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user