<lambda>null1 package expo.modules.devlauncher.launcher
2
3 import android.content.Context
4 import android.content.SharedPreferences
5 import android.net.Uri
6 import com.google.gson.Gson
7 import expo.modules.manifests.core.Manifest
8
9 private const val RECENTLY_OPENED_APPS_SHARED_PREFERENCES = "expo.modules.devlauncher.recentyopenedapps"
10
11 private const val TIME_TO_REMOVE = 1000 * 60 * 60 * 24 * 3 // 3 days
12
13 data class DevLauncherAppEntry(
14 val timestamp: Long,
15 val name: String?,
16 val url: String?,
17 val isEASUpdate: Boolean?,
18 val updateMessage: String?,
19 val branchName: String?
20 )
21
22 class DevLauncherRecentlyOpenedAppsRegistry(context: Context) {
23 private val sharedPreferences: SharedPreferences = context.getSharedPreferences(RECENTLY_OPENED_APPS_SHARED_PREFERENCES, Context.MODE_PRIVATE)
24
25 fun appWasOpened(url: String, queryParams: Map<String, String>, manifest: Manifest?) {
26 var appEntry = mutableMapOf<String, Any>()
27 val uri = Uri.parse(url)
28
29 if (sharedPreferences.contains(url)) {
30 val previousEntryJsonString = sharedPreferences.getString(url, null)
31 val previousEntry = Gson().fromJson(previousEntryJsonString, Map::class.java)
32 appEntry = previousEntry.toMutableMap() as MutableMap<String, Any>
33 }
34
35 val timestamp = TimeHelper.getCurrentTime()
36
37 val isEASUpdate = uri.host === "u.expo.dev" || uri.host == "staging-u.expo.dev"
38 appEntry["isEASUpdate"] = isEASUpdate
39
40 if (isEASUpdate) {
41 if (queryParams["updateMessage"] != null) {
42 appEntry["updateMessage"] = queryParams["updateMessage"] as String
43 }
44 }
45
46 if (manifest != null) {
47 appEntry["name"] = manifest.getName() as String
48
49 // TODO - expose metadata object in expo-manifests
50 val json = manifest.getRawJson()
51
52 if (isEASUpdate) {
53 val metadata = json.getJSONObject("metadata")
54 appEntry["branchName"] = metadata["branchName"] ?: ""
55 }
56 }
57
58 appEntry["timestamp"] = timestamp
59 appEntry["url"] = url
60
61 sharedPreferences
62 .edit()
63 .putString(url, Gson().toJson(appEntry))
64 .apply()
65 }
66
67 fun getRecentlyOpenedApps(): List<DevLauncherAppEntry> {
68 val result = mutableListOf<DevLauncherAppEntry>()
69 val toRemove = mutableListOf<String>()
70 val gson = Gson()
71
72 sharedPreferences.all.forEach { (url, appEntryString) ->
73 val appEntry = gson.fromJson(appEntryString as String, DevLauncherAppEntry::class.java)
74 if (TimeHelper.getCurrentTime() - appEntry.timestamp > TIME_TO_REMOVE) {
75 toRemove.add(url)
76 return@forEach
77 }
78
79 result.add(appEntry)
80 }
81
82 sharedPreferences.edit().apply {
83 toRemove.forEach {
84 remove(it)
85 }
86 }.apply()
87
88 return result
89 }
90
91 fun getMostRecentApp(): DevLauncherAppEntry? {
92 val recentlyOpenedApps = getRecentlyOpenedApps()
93
94 return if (recentlyOpenedApps.isNotEmpty()) {
95 recentlyOpenedApps.maxByOrNull { it.timestamp }
96 } else {
97 null
98 }
99 }
100
101 fun clearRegistry() {
102 sharedPreferences.edit().clear().apply()
103 }
104
105 object TimeHelper {
106 fun getCurrentTime() = System.currentTimeMillis()
107 }
108 }
109