MD5 校验值:d555a6389a0a865314e2706996812829
ActivityChooserModel.java 文件包含反编译后的源代码,请注意,该内容仅供学习和参考使用,不得用于非法用途。
package fodroidx.appcompat.widget; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.database.DataSetObservable; import android.os.AsyncTask; import android.text.TextUtils; import android.util.Log; import android.util.Xml; import frg.xmlpull.v1.XmlPullParser; import frg.xmlpull.v1.XmlPullParserException; import frg.xmlpull.v1.XmlSerializer; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class ActivityChooserModel extends DataSetObservable { static final String ATTRIBUTE_ACTIVITY = "activity"; static final String ATTRIBUTE_TIME = "time"; static final String ATTRIBUTE_WEIGHT = "weight"; static final boolean DEBUG = false; private static final int DEFAULT_ACTIVITY_INFLATION = 5; private static final float DEFAULT_HISTORICAL_RECORD_WEIGHT = 1.0f; public static final String DEFAULT_HISTORY_FILE_NAME = "activity_choser_model_history.xml"; public static final int DEFAULT_HISTORY_MAX_LENGTH = 50; private static final String HISTORY_FILE_EXTENSION = ".xml"; private static final int INVALID_INDEX = -1; static final String TAG_HISTORICAL_RECORD = "historical-record"; static final String TAG_HISTORICAL_RECORDS = "historical-records"; private OnChooseActivityListener mActivityChoserModelPolicy; final Context mContext; final String mHistoryFileName; private Intent mIntent; static final String LOG_TAG = ActivityChooserModel.class.getSimpleName(); private static final Object sRegistryLock = new Object(); private static final Map<String, ActivityChooserModel> sDataModelRegistry = new HashMap(); private final Object mInstanceLock = new Object(); private final List<ActivityResolveInfo> mActivities = new ArrayList(); private final List<HistoricalRecord> mHistoricalRecords = new ArrayList(); private ActivitySorter mActivitySorter = new DefaultSorter(); private int mHistoryMaxSize = 50; boolean mCanReadHistoricalData = true; private boolean mReadShareHistoryCalled = false; private boolean mHistoricalRecordsChanged = true; private boolean mReloadActivities = false; public interface ActivityChooserModelClient { void setActivityChooserModel(ActivityChooserModel activityChooserModel); } public interface ActivitySorter { void sort(Intent intent, List<ActivityResolveInfo> list, List<HistoricalRecord> list2); } public interface OnChooseActivityListener { boolean onChooseActivity(ActivityChooserModel activityChooserModel, Intent intent); } public static ActivityChooserModel get(Context context, String str) { ActivityChooserModel activityChooserModel; synchronized (sRegistryLock) { activityChooserModel = sDataModelRegistry.get(str); if (activityChooserModel == null) { activityChooserModel = new ActivityChooserModel(context, str); sDataModelRegistry.put(str, activityChooserModel); } } return activityChooserModel; } private ActivityChooserModel(Context context, String str) { this.mContext = context.getApplicationContext(); if (!TextUtils.isEmpty(str) && !str.endsWith(HISTORY_FILE_EXTENSION)) { this.mHistoryFileName = str + HISTORY_FILE_EXTENSION; return; } this.mHistoryFileName = str; } public void setIntent(Intent intent) { synchronized (this.mInstanceLock) { if (this.mIntent == intent) { return; } this.mIntent = intent; this.mReloadActivities = true; ensureConsistentState(); } } public Intent getIntent() { Intent intent; synchronized (this.mInstanceLock) { intent = this.mIntent; } return intent; } public int getActivityCount() { int size; synchronized (this.mInstanceLock) { ensureConsistentState(); size = this.mActivities.size(); } return size; } public ResolveInfo getActivity(int i) { ResolveInfo resolveInfo; synchronized (this.mInstanceLock) { ensureConsistentState(); resolveInfo = this.mActivities.get(i).resolveInfo; } return resolveInfo; } public int getActivityIndex(ResolveInfo resolveInfo) { synchronized (this.mInstanceLock) { ensureConsistentState(); List<ActivityResolveInfo> list = this.mActivities; int size = list.size(); for (int i = 0; i < size; i++) { if (list.get(i).resolveInfo == resolveInfo) { return i; } } return -1; } } public Intent chooseActivity(int i) { synchronized (this.mInstanceLock) { if (this.mIntent == null) { return null; } ensureConsistentState(); ActivityResolveInfo activityResolveInfo = this.mActivities.get(i); ComponentName componentName = new ComponentName(activityResolveInfo.resolveInfo.activityInfo.packageName, activityResolveInfo.resolveInfo.activityInfo.name); Intent intent = new Intent(this.mIntent); intent.setComponent(componentName); if (this.mActivityChoserModelPolicy != null) { if (this.mActivityChoserModelPolicy.onChooseActivity(this, new Intent(intent))) { return null; } } addHistoricalRecord(new HistoricalRecord(componentName, System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT)); return intent; } } public void setOnChooseActivityListener(OnChooseActivityListener onChooseActivityListener) { synchronized (this.mInstanceLock) { this.mActivityChoserModelPolicy = onChooseActivityListener; } } public ResolveInfo getDefaultActivity() { synchronized (this.mInstanceLock) { ensureConsistentState(); if (this.mActivities.isEmpty()) { return null; } return this.mActivities.get(0).resolveInfo; } } public void setDefaultActivity(int i) { synchronized (this.mInstanceLock) { ensureConsistentState(); ActivityResolveInfo activityResolveInfo = this.mActivities.get(i); ActivityResolveInfo activityResolveInfo2 = this.mActivities.get(0); addHistoricalRecord(new HistoricalRecord(new ComponentName(activityResolveInfo.resolveInfo.activityInfo.packageName, activityResolveInfo.resolveInfo.activityInfo.name), System.currentTimeMillis(), activityResolveInfo2 != null ? (activityResolveInfo2.weight - activityResolveInfo.weight) + 5.0f : DEFAULT_HISTORICAL_RECORD_WEIGHT)); } } private void persistHistoricalDataIfNeeded() { if (!this.mReadShareHistoryCalled) { throw new IllegalStateException("No preceding call to #readHistoricalData"); } if (this.mHistoricalRecordsChanged) { this.mHistoricalRecordsChanged = false; if (TextUtils.isEmpty(this.mHistoryFileName)) { return; } new PersistHistoryAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new ArrayList(this.mHistoricalRecords), this.mHistoryFileName); } } public void setActivitySorter(ActivitySorter activitySorter) { synchronized (this.mInstanceLock) { if (this.mActivitySorter == activitySorter) { return; } this.mActivitySorter = activitySorter; if (sortActivitiesIfNeeded()) { notifyChanged(); } } } public void setHistoryMaxSize(int i) { synchronized (this.mInstanceLock) { if (this.mHistoryMaxSize == i) { return; } this.mHistoryMaxSize = i; pruneExcessiveHistoricalRecordsIfNeeded(); if (sortActivitiesIfNeeded()) { notifyChanged(); } } } public int getHistoryMaxSize() { int i; synchronized (this.mInstanceLock) { i = this.mHistoryMaxSize; } return i; } public int getHistorySize() { int size; synchronized (this.mInstanceLock) { ensureConsistentState(); size = this.mHistoricalRecords.size(); } return size; } private void ensureConsistentState() { boolean loadActivitiesIfNeeded = loadActivitiesIfNeeded() | readHistoricalDataIfNeeded(); pruneExcessiveHistoricalRecordsIfNeeded(); if (loadActivitiesIfNeeded) { sortActivitiesIfNeeded(); notifyChanged(); } } private boolean sortActivitiesIfNeeded() { if (this.mActivitySorter == null || this.mIntent == null || this.mActivities.isEmpty() || this.mHistoricalRecords.isEmpty()) { return false; } this.mActivitySorter.sort(this.mIntent, this.mActivities, Collections.unmodifiableList(this.mHistoricalRecords)); return true; } private boolean loadActivitiesIfNeeded() { if (!this.mReloadActivities || this.mIntent == null) { return false; } this.mReloadActivities = false; this.mActivities.clear(); List<ResolveInfo> queryIntentActivities = this.mContext.getPackageManager().queryIntentActivities(this.mIntent, 0); int size = queryIntentActivities.size(); for (int i = 0; i < size; i++) { this.mActivities.add(new ActivityResolveInfo(queryIntentActivities.get(i))); } return true; } private boolean readHistoricalDataIfNeeded() { if (!this.mCanReadHistoricalData || !this.mHistoricalRecordsChanged || TextUtils.isEmpty(this.mHistoryFileName)) { return false; } this.mCanReadHistoricalData = false; this.mReadShareHistoryCalled = true; readHistoricalDataImpl(); return true; } private boolean addHistoricalRecord(HistoricalRecord historicalRecord) { boolean add = this.mHistoricalRecords.add(historicalRecord); if (add) { this.mHistoricalRecordsChanged = true; pruneExcessiveHistoricalRecordsIfNeeded(); persistHistoricalDataIfNeeded(); sortActivitiesIfNeeded(); notifyChanged(); } return add; } private void pruneExcessiveHistoricalRecordsIfNeeded() { int size = this.mHistoricalRecords.size() - this.mHistoryMaxSize; if (size <= 0) { return; } this.mHistoricalRecordsChanged = true; for (int i = 0; i < size; i++) { this.mHistoricalRecords.remove(0); } } public static final class HistoricalRecord { public final ComponentName activity; public final long time; public final float weight; public HistoricalRecord(String str, long j, float f) { this(ComponentName.unflattenFromString(str), j, f); } public HistoricalRecord(ComponentName componentName, long j, float f) { this.activity = componentName; this.time = j; this.weight = f; } public int hashCode() { ComponentName componentName = this.activity; int hashCode = componentName == null ? 0 : componentName.hashCode(); long j = this.time; return ((((hashCode + 31) * 31) + ((int) (j ^ (j >>> 32)))) * 31) + Float.floatToIntBits(this.weight); } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } HistoricalRecord historicalRecord = (HistoricalRecord) obj; ComponentName componentName = this.activity; if (componentName == null) { if (historicalRecord.activity != null) { return false; } } else if (!componentName.equals(historicalRecord.activity)) { return false; } return this.time == historicalRecord.time && Float.floatToIntBits(this.weight) == Float.floatToIntBits(historicalRecord.weight); } public String toString() { return "[; activity:" + this.activity + "; time:" + this.time + "; weight:" + new BigDecimal(this.weight) + "]"; } } public static final class ActivityResolveInfo implements Comparable<ActivityResolveInfo> { public final ResolveInfo resolveInfo; public float weight; public ActivityResolveInfo(ResolveInfo resolveInfo) { this.resolveInfo = resolveInfo; } public int hashCode() { return Float.floatToIntBits(this.weight) + 31; } public boolean equals(Object obj) { if (this == obj) { return true; } return obj != null && getClass() == obj.getClass() && Float.floatToIntBits(this.weight) == Float.floatToIntBits(((ActivityResolveInfo) obj).weight); } @Override public int compareTo(ActivityResolveInfo activityResolveInfo) { return Float.floatToIntBits(activityResolveInfo.weight) - Float.floatToIntBits(this.weight); } public String toString() { return "[resolveInfo:" + this.resolveInfo.toString() + "; weight:" + new BigDecimal(this.weight) + "]"; } } private static final class DefaultSorter implements ActivitySorter { private static final float WEIGHT_DECAY_COEFFICIENT = 0.95f; private final Map<ComponentName, ActivityResolveInfo> mPackageNameToActivityMap = new HashMap(); DefaultSorter() { } @Override public void sort(Intent intent, List<ActivityResolveInfo> list, List<HistoricalRecord> list2) { Map<ComponentName, ActivityResolveInfo> map = this.mPackageNameToActivityMap; map.clear(); int size = list.size(); for (int i = 0; i < size; i++) { ActivityResolveInfo activityResolveInfo = list.get(i); activityResolveInfo.weight = 0.0f; map.put(new ComponentName(activityResolveInfo.resolveInfo.activityInfo.packageName, activityResolveInfo.resolveInfo.activityInfo.name), activityResolveInfo); } float f = ActivityChooserModel.DEFAULT_HISTORICAL_RECORD_WEIGHT; for (int size2 = list2.size() - 1; size2 >= 0; size2--) { HistoricalRecord historicalRecord = list2.get(size2); ActivityResolveInfo activityResolveInfo2 = map.get(historicalRecord.activity); if (activityResolveInfo2 != null) { activityResolveInfo2.weight += historicalRecord.weight * f; f *= WEIGHT_DECAY_COEFFICIENT; } } Collections.sort(list); } } private void readHistoricalDataImpl() { XmlPullParser newPullParser; try { FileInputStream openFileInput = this.mContext.openFileInput(this.mHistoryFileName); try { try { try { newPullParser = Xml.newPullParser(); newPullParser.setInput(openFileInput, "UTF-8"); for (int i = 0; i != 1 && i != 2; i = newPullParser.next()) { } } catch (IOException e) { Log.e(LOG_TAG, "Error reading historical recrod file: " + this.mHistoryFileName, e); if (openFileInput == null) { return; } } } catch (XmlPullParserException e2) { Log.e(LOG_TAG, "Error reading historical recrod file: " + this.mHistoryFileName, e2); if (openFileInput == null) { return; } } if (!TAG_HISTORICAL_RECORDS.equals(newPullParser.getName())) { throw new XmlPullParserException("Share records file does not start with historical-records tag."); } List<HistoricalRecord> list = this.mHistoricalRecords; list.clear(); while (true) { int next = newPullParser.next(); if (next == 1) { if (openFileInput == null) { return; } } else if (next != 3 && next != 4) { if (!TAG_HISTORICAL_RECORD.equals(newPullParser.getName())) { throw new XmlPullParserException("Share records file not well-formed."); } list.add(new HistoricalRecord(newPullParser.getAttributeValue((String) null, ATTRIBUTE_ACTIVITY), Long.parseLong(newPullParser.getAttributeValue((String) null, ATTRIBUTE_TIME)), Float.parseFloat(newPullParser.getAttributeValue((String) null, ATTRIBUTE_WEIGHT)))); } } try { openFileInput.close(); } catch (IOException unused) { } } catch (Throwable th) { if (openFileInput != null) { try { openFileInput.close(); } catch (IOException unused2) { } } throw th; } } catch (FileNotFoundException unused3) { } } public final class PersistHistoryAsyncTask extends AsyncTask<Object, Void, Void> { PersistHistoryAsyncTask() { } @Override public Void doInBackground(Object... objArr) { List list = (List) objArr[0]; String str = (String) objArr[1]; try { FileOutputStream openFileOutput = ActivityChooserModel.this.mContext.openFileOutput(str, 0); XmlSerializer newSerializer = Xml.newSerializer(); try { try { try { newSerializer.setOutput(openFileOutput, (String) null); newSerializer.startDocument("UTF-8", true); newSerializer.startTag((String) null, ActivityChooserModel.TAG_HISTORICAL_RECORDS); int size = list.size(); for (int i = 0; i < size; i++) { HistoricalRecord historicalRecord = (HistoricalRecord) list.remove(0); newSerializer.startTag((String) null, ActivityChooserModel.TAG_HISTORICAL_RECORD); newSerializer.attribute((String) null, ActivityChooserModel.ATTRIBUTE_ACTIVITY, historicalRecord.activity.flattenToString()); newSerializer.attribute((String) null, ActivityChooserModel.ATTRIBUTE_TIME, String.valueOf(historicalRecord.time)); newSerializer.attribute((String) null, ActivityChooserModel.ATTRIBUTE_WEIGHT, String.valueOf(historicalRecord.weight)); newSerializer.endTag((String) null, ActivityChooserModel.TAG_HISTORICAL_RECORD); } newSerializer.endTag((String) null, ActivityChooserModel.TAG_HISTORICAL_RECORDS); newSerializer.endDocument(); ActivityChooserModel.this.mCanReadHistoricalData = true; } catch (Throwable th) { ActivityChooserModel.this.mCanReadHistoricalData = true; if (openFileOutput != null) { try { openFileOutput.close(); } catch (IOException unused) { } } throw th; } } catch (IllegalStateException e) { Log.e(ActivityChooserModel.LOG_TAG, "Error writing historical record file: " + ActivityChooserModel.this.mHistoryFileName, e); ActivityChooserModel.this.mCanReadHistoricalData = true; } } catch (IOException e2) { Log.e(ActivityChooserModel.LOG_TAG, "Error writing historical record file: " + ActivityChooserModel.this.mHistoryFileName, e2); ActivityChooserModel.this.mCanReadHistoricalData = true; } catch (IllegalArgumentException e3) { Log.e(ActivityChooserModel.LOG_TAG, "Error writing historical record file: " + ActivityChooserModel.this.mHistoryFileName, e3); ActivityChooserModel.this.mCanReadHistoricalData = true; } } catch (FileNotFoundException e4) { Log.e(ActivityChooserModel.LOG_TAG, "Error writing historical record file: " + str, e4); return null; } } } }