1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
package com.android.launcher3.allapps;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Process;
import com.android.launcher3.AppInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ComponentKeyMapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class PredictiveAppsProvider {
private static final int NUM_PREDICTIVE_APPS_TO_HOLD = 9; // since we can't have more than 9 columns
private static final String PREDICTIVE_APPS_KEY = "predictive_apps";
private static final String TOP_PREDICTIVE_APPS_KEY = "top_predictive_apps";
private SharedPreferences mPrefs;
public PredictiveAppsProvider(Context context) {
this.mPrefs = Utilities.getPrefs(context.getApplicationContext());
}
public void updateComponentCount(ComponentName component) {
String key = buildComponentString(component);
long current = mPrefs.getLong(key, 0);
mPrefs.edit().putLong(key, current + 1).apply();
// ensure that the set of predictive apps contains this one
Set<String> predictiveApps =
mPrefs.getStringSet(PREDICTIVE_APPS_KEY, new HashSet<>());
if (!predictiveApps.contains(key)) {
predictiveApps.add(key);
mPrefs.edit().putStringSet(PREDICTIVE_APPS_KEY, predictiveApps).apply();
}
}
public void updateTopPredictedApps() {
new Thread(() -> {
List< PredictedApp > allPredictions = new ArrayList<>();
Set<String> predictiveAppsSet =
mPrefs.getStringSet(PREDICTIVE_APPS_KEY, new HashSet<>());
for (String s : predictiveAppsSet) {
allPredictions.add(new PredictedApp(buildComponentFromString(s),
mPrefs.getLong(s, 0)));
}
Collections.sort(allPredictions, (result1, result2) ->
Long.valueOf(result2.count).compareTo(result1.count));
if (allPredictions.size() > NUM_PREDICTIVE_APPS_TO_HOLD) {
allPredictions = allPredictions.subList(0, NUM_PREDICTIVE_APPS_TO_HOLD);
}
mPrefs.edit().putString(TOP_PREDICTIVE_APPS_KEY,
buildStringFromAppList(allPredictions)).apply();
}).start();
}
public List<ComponentKeyMapper<AppInfo>> getPredictions() {
String predictions = mPrefs.getString(TOP_PREDICTIVE_APPS_KEY, "");
if (predictions.isEmpty()) {
return new ArrayList<>();
}
String[] topPredictions = predictions.split(" ");
List<ComponentKeyMapper<AppInfo>> keys = new ArrayList<>();
for (int i = 0; i < topPredictions.length - 1; i++) {
keys.add(buildComponentKey(topPredictions[i] + " " + topPredictions[i + 1]));
}
return keys;
}
private String buildStringFromAppList(List<PredictedApp> apps) {
StringBuilder string = new StringBuilder();
for (PredictedApp app : apps) {
string.append(buildComponentString(app.component)).append(" ");
}
try {
return string.substring(0, string.length() - 1);
} catch (StringIndexOutOfBoundsException e) {
return "";
}
}
private String buildComponentString(ComponentName component) {
return component.getPackageName() + " " + component.getClassName();
}
private ComponentName buildComponentFromString(String key) {
String[] arr = key.split(" ");
return new ComponentName(arr[0], arr[1]);
}
private ComponentKeyMapper<AppInfo> buildComponentKey(String key) {
return buildComponentKey(buildComponentFromString(key));
}
private ComponentKeyMapper<AppInfo> buildComponentKey(ComponentName component) {
return new ComponentKeyMapper<>(new ComponentKey(component, Process.myUserHandle()));
}
private class PredictedApp {
public ComponentName component;
public long count;
public PredictedApp(ComponentName component, long count) {
this.component = component;
this.count = count;
}
}
}
|