Skip to content

Commit ce05247

Browse files
Update TrialManager.kt
1 parent 81c5649 commit ce05247

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

app/src/main/kotlin/com/google/ai/sample/TrialManager.kt

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,52 +83,69 @@ object TrialManager {
8383

8484
fun getTrialState(context: Context, currentUtcTimeMs: Long?): TrialState {
8585
Log.d(TAG, "getTrialState called with currentUtcTimeMs: $currentUtcTimeMs")
86-
if (isPurchased(context)) {
86+
val prefs = getSharedPreferences(context) // Get prefs instance early
87+
88+
if (isPurchased(context)) { // isPurchased uses its own prefs instance, which is fine
8789
Log.d(TAG, "getTrialState: App is purchased. Returning TrialState.PURCHASED")
8890
return TrialState.PURCHASED
8991
}
9092

91-
val prefs = getSharedPreferences(context)
9293
val isAwaitingFirstInternetTime = prefs.getBoolean(KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME, true)
93-
val trialUtcEndTime = getTrialUtcEndTime(context)
94+
val trialUtcEndTime = getTrialUtcEndTime(context) // getTrialUtcEndTime uses its own prefs instance
9495
val confirmedExpired = prefs.getBoolean(KEY_TRIAL_CONFIRMED_EXPIRED, false)
9596
Log.d(TAG, "getTrialState: isAwaitingFirstInternetTime: $isAwaitingFirstInternetTime, trialUtcEndTime: $trialUtcEndTime, confirmedExpired: $confirmedExpired")
9697

9798
if (confirmedExpired) {
98-
Log.d(TAG, "getTrialState: Trial previously confirmed expired. Returning EXPIRED_INTERNET_TIME_CONFIRMED.")
99+
Log.d(TAG, "getTrialState: Trial previously confirmed expired (flag was true). Returning EXPIRED_INTERNET_TIME_CONFIRMED.")
99100
return TrialState.EXPIRED_INTERNET_TIME_CONFIRMED
100101
}
101102

102103
if (currentUtcTimeMs == null) {
103104
Log.d(TAG, "getTrialState: currentUtcTimeMs is null.")
105+
// If confirmedExpired was false, and currentUtcTimeMs is null, we cannot confirm expiry.
106+
// We rely on isAwaitingFirstInternetTime and trialUtcEndTime to determine initial/pending states.
104107
return if (trialUtcEndTime == null && isAwaitingFirstInternetTime) {
105-
Log.d(TAG, "getTrialState: Returning NOT_YET_STARTED_AWAITING_INTERNET (no end time, awaiting internet)")
108+
Log.d(TAG, "getTrialState: Returning NOT_YET_STARTED_AWAITING_INTERNET (no end time, awaiting internet, not confirmed expired)")
106109
TrialState.NOT_YET_STARTED_AWAITING_INTERNET
107110
} else {
108-
Log.d(TAG, "getTrialState: Returning INTERNET_UNAVAILABLE_CANNOT_VERIFY (end time might exist or not awaiting, but no current time)")
111+
// This path means either trial has started (endTime exists) or it's not awaiting first internet,
112+
// but we don't have current time to check. Or, endTime is null but we are not awaiting (inconsistent state).
113+
Log.d(TAG, "getTrialState: Returning INTERNET_UNAVAILABLE_CANNOT_VERIFY (end time might exist or not awaiting, but no current time, not confirmed expired)")
109114
TrialState.INTERNET_UNAVAILABLE_CANNOT_VERIFY
110115
}
111116
}
112117

118+
// currentUtcTimeMs is NOT null from this point onwards
113119
Log.d(TAG, "getTrialState: currentUtcTimeMs is $currentUtcTimeMs. Evaluating state based on time.")
114120
return when {
115121
trialUtcEndTime == null && isAwaitingFirstInternetTime -> {
122+
// This case implies startTrialIfNecessaryWithInternetTime hasn't run yet with a valid internet time.
123+
// Since currentUtcTimeMs is available now, TrialTimerService should call startTrialIfNecessaryWithInternetTime.
124+
// For now, we report it as NOT_YET_STARTED.
116125
Log.d(TAG, "getTrialState: Case 1: trialUtcEndTime is null AND isAwaitingFirstInternetTime is true. Returning NOT_YET_STARTED_AWAITING_INTERNET")
117126
TrialState.NOT_YET_STARTED_AWAITING_INTERNET
118127
}
119128
trialUtcEndTime == null && !isAwaitingFirstInternetTime -> {
129+
// This is an inconsistent state: trial supposedly started (not awaiting), but no end time.
130+
// This might happen if saveTrialUtcEndTime failed or was cleared erroneously.
120131
Log.e(TAG, "CRITICAL INCONSISTENCY: Trial marked as started (not awaiting internet), but no trial end time found. Check save/load logic. Returning INTERNET_UNAVAILABLE_CANNOT_VERIFY.")
132+
// Cannot confirm active or expired without an end time.
121133
TrialState.INTERNET_UNAVAILABLE_CANNOT_VERIFY
122134
}
123135
trialUtcEndTime != null && currentUtcTimeMs < trialUtcEndTime -> {
124136
Log.d(TAG, "getTrialState: Case 2: trialUtcEndTime ($trialUtcEndTime) > currentUtcTimeMs ($currentUtcTimeMs). Returning ACTIVE_INTERNET_TIME_CONFIRMED")
125137
TrialState.ACTIVE_INTERNET_TIME_CONFIRMED
126138
}
127139
trialUtcEndTime != null && currentUtcTimeMs >= trialUtcEndTime -> {
128-
Log.d(TAG, "getTrialState: Case 3: trialUtcEndTime ($trialUtcEndTime) <= currentUtcTimeMs ($currentUtcTimeMs). Returning EXPIRED_INTERNET_TIME_CONFIRMED")
140+
Log.i(TAG, "getTrialState: Case 3: trialUtcEndTime ($trialUtcEndTime) <= currentUtcTimeMs ($currentUtcTimeMs). Trial EXPIRED. Setting KEY_TRIAL_CONFIRMED_EXPIRED=true.")
141+
// --- MODIFICATION START ---
142+
// Persist that the trial has been confirmed expired with internet time.
143+
prefs.edit().putBoolean(KEY_TRIAL_CONFIRMED_EXPIRED, true).apply()
144+
// --- MODIFICATION END ---
129145
TrialState.EXPIRED_INTERNET_TIME_CONFIRMED
130146
}
131147
else -> {
148+
// Fallback for any unhandled scenarios, though ideally all paths should be covered.
132149
Log.e(TAG, "Unhandled case in getTrialState. isAwaiting: $isAwaitingFirstInternetTime, endTime: $trialUtcEndTime, currentTime: $currentUtcTimeMs. Defaulting to NOT_YET_STARTED_AWAITING_INTERNET.")
133150
TrialState.NOT_YET_STARTED_AWAITING_INTERNET
134151
}
@@ -138,13 +155,16 @@ object TrialManager {
138155
fun markAsPurchased(context: Context) {
139156
Log.d(TAG, "markAsPurchased called")
140157
val editor = getSharedPreferences(context).edit()
141-
Log.d(TAG, "Removing trial-related keys: KEY_TRIAL_END_TIME_UNENCRYPTED, KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME")
158+
Log.d(TAG, "Removing trial-related keys: KEY_TRIAL_END_TIME_UNENCRYPTED, KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME, KEY_TRIAL_CONFIRMED_EXPIRED")
142159
editor.remove(KEY_TRIAL_END_TIME_UNENCRYPTED)
143160
editor.remove(KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME)
161+
// --- MODIFICATION START ---
162+
editor.remove(KEY_TRIAL_CONFIRMED_EXPIRED) // Ensure this flag is cleared on purchase
163+
// --- MODIFICATION END ---
144164
Log.d(TAG, "Setting KEY_PURCHASED_FLAG to true")
145165
editor.putBoolean(KEY_PURCHASED_FLAG, true)
146166
editor.apply()
147-
Log.i(TAG, "App marked as purchased. Trial data (including unencrypted end time) cleared.")
167+
Log.i(TAG, "App marked as purchased. Trial data (including unencrypted end time and confirmed expired flag) cleared.")
148168
}
149169

150170
private fun isPurchased(context: Context): Boolean {
@@ -160,14 +180,16 @@ object TrialManager {
160180
val awaitingFlagExists = prefs.contains(KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME)
161181
val purchasedFlagExists = prefs.contains(KEY_PURCHASED_FLAG)
162182
val endTimeExists = prefs.contains(KEY_TRIAL_END_TIME_UNENCRYPTED)
183+
// We don't need to check for KEY_TRIAL_CONFIRMED_EXPIRED here, as it's set only after expiry.
184+
// Its absence is normal for a new or active trial.
163185
Log.d(TAG, "Checking for existing flags: awaitingFlagExists=$awaitingFlagExists, purchasedFlagExists=$purchasedFlagExists, endTimeExists=$endTimeExists")
164186

165187
if (!awaitingFlagExists && !purchasedFlagExists && !endTimeExists) {
166-
Log.d(TAG, "No trial-related flags found. Initializing KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME to true.")
188+
Log.d(TAG, "No core trial-related flags found. Initializing KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME to true.")
167189
prefs.edit().putBoolean(KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME, true).apply()
168190
Log.d(TAG, "Initialized KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME to true for a fresh state (unencrypted storage)." )
169191
} else {
170-
Log.d(TAG, "One or more trial-related flags already exist. No initialization needed.")
192+
Log.d(TAG, "One or more core trial-related flags already exist. No initialization needed for KEY_TRIAL_AWAITING_FIRST_INTERNET_TIME.")
171193
}
172194
}
173195
}

0 commit comments

Comments
 (0)