Skip to content

Commit a03b49e

Browse files
committed
fix: parse cache dir migration routine on SDK initialization (only once) (#1168)
1 parent 4d3640b commit a03b49e

File tree

1 file changed

+74
-53
lines changed

1 file changed

+74
-53
lines changed

parse/src/main/java/com/parse/Parse.java

Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
import android.content.pm.PackageManager;
1313
import android.content.pm.ResolveInfo;
1414
import android.util.Log;
15+
1516
import androidx.annotation.NonNull;
1617
import androidx.annotation.Nullable;
18+
1719
import com.parse.boltsinternal.Continuation;
1820
import com.parse.boltsinternal.Task;
21+
1922
import java.io.File;
2023
import java.io.FileOutputStream;
2124
import java.io.IOException;
@@ -26,6 +29,7 @@
2629
import java.util.List;
2730
import java.util.Set;
2831
import java.util.concurrent.Callable;
32+
2933
import okhttp3.OkHttpClient;
3034

3135
/**
@@ -75,7 +79,7 @@ private Parse() {
7579
* }
7680
* }
7781
* </pre>
78-
*
82+
* <p>
7983
* See <a
8084
* href="https://github.com/parse-community/Parse-SDK-Android/issues/279">https://github.com/parse-community/Parse-SDK-Android/issues/279</a>
8185
* for a discussion on performance of local datastore, and if it is right for your project.
@@ -85,8 +89,8 @@ private Parse() {
8589
public static void enableLocalDatastore(Context context) {
8690
if (isInitialized()) {
8791
throw new IllegalStateException(
88-
"`Parse#enableLocalDatastore(Context)` must be invoked "
89-
+ "before `Parse#initialize(Context)`");
92+
"`Parse#enableLocalDatastore(Context)` must be invoked "
93+
+ "before `Parse#initialize(Context)`");
9094
}
9195
isLocalDatastoreEnabled = true;
9296
}
@@ -113,7 +117,7 @@ public static boolean isLocalDatastoreEnabled() {
113117

114118
/**
115119
* @return {@code True} if {@link Configuration.Builder#allowCustomObjectId()} has been called,
116-
* otherwise {@code false}.
120+
* otherwise {@code false}.
117121
*/
118122
public static boolean isAllowCustomObjectId() {
119123
return allowCustomObjectId;
@@ -145,6 +149,9 @@ static void initialize(Configuration configuration, ParsePlugins parsePlugins) {
145149
PLog.w(TAG, "Parse is already initialized");
146150
return;
147151
}
152+
// Perform old dir migration on initialize.
153+
new ParseCacheDirMigrationUtils(configuration.context).runMigrations();
154+
148155
// NOTE (richardross): We will need this here, as ParsePlugins uses the return value of
149156
// isLocalDataStoreEnabled() to perform additional behavior.
150157
isLocalDatastoreEnabled = configuration.localDataStoreEnabled;
@@ -176,32 +183,32 @@ static void initialize(Configuration configuration, ParsePlugins parsePlugins) {
176183
checkCacheApplicationId();
177184
final Context context = configuration.context;
178185
Task.callInBackground(
179-
(Callable<Void>)
180-
() -> {
181-
getEventuallyQueue(context);
182-
return null;
183-
});
186+
(Callable<Void>)
187+
() -> {
188+
getEventuallyQueue(context);
189+
return null;
190+
});
184191

185192
ParseFieldOperations.registerDefaultDecoders();
186193

187194
if (!allParsePushIntentReceiversInternal()) {
188195
throw new SecurityException(
189-
"To prevent external tampering to your app's notifications, "
190-
+ "all receivers registered to handle the following actions must have "
191-
+ "their exported attributes set to false: com.parse.push.intent.RECEIVE, "
192-
+ "com.parse.push.intent.OPEN, com.parse.push.intent.DELETE");
196+
"To prevent external tampering to your app's notifications, "
197+
+ "all receivers registered to handle the following actions must have "
198+
+ "their exported attributes set to false: com.parse.push.intent.RECEIVE, "
199+
+ "com.parse.push.intent.OPEN, com.parse.push.intent.DELETE");
193200
}
194201

195202
ParseUser.getCurrentUserAsync()
196-
.makeVoid()
197-
.continueWith(
198-
(Continuation<Void, Void>)
199-
task -> {
200-
// Prime config in the background
201-
ParseConfig.getCurrentConfig();
202-
return null;
203-
},
204-
Task.BACKGROUND_EXECUTOR);
203+
.makeVoid()
204+
.continueWith(
205+
(Continuation<Void, Void>)
206+
task -> {
207+
// Prime config in the background
208+
ParseConfig.getCurrentConfig();
209+
return null;
210+
},
211+
Task.BACKGROUND_EXECUTOR);
205212

206213
dispatchOnParseInitialized();
207214

@@ -213,8 +220,11 @@ static void initialize(Configuration configuration, ParsePlugins parsePlugins) {
213220

214221
// region Server URL
215222

216-
/** Returns the current server URL. */
217-
public static @Nullable String getServer() {
223+
/**
224+
* Returns the current server URL.
225+
*/
226+
public static @Nullable
227+
String getServer() {
218228
URL server = ParseRESTCommand.server;
219229
return server == null ? null : server.toString();
220230
}
@@ -248,7 +258,8 @@ public static void setServer(@NonNull String server) {
248258
* @param server The server URL to validate.
249259
* @return The validated server URL.
250260
*/
251-
private static @Nullable String validateServerUrl(@Nullable String server) {
261+
private static @Nullable
262+
String validateServerUrl(@Nullable String server) {
252263

253264
// Add an extra trailing slash so that Parse REST commands include
254265
// the path as part of the server URL (i.e. http://api.myhost.com/parse)
@@ -285,7 +296,9 @@ public static void destroy() {
285296
allowCustomObjectId = false;
286297
}
287298

288-
/** @return {@code True} if {@link #initialize} has been called, otherwise {@code false}. */
299+
/**
300+
* @return {@code True} if {@link #initialize} has been called, otherwise {@code false}.
301+
*/
289302
static boolean isInitialized() {
290303
return ParsePlugins.get() != null;
291304
}
@@ -308,10 +321,10 @@ public static Context getApplicationContext() {
308321
*/
309322
private static boolean allParsePushIntentReceiversInternal() {
310323
List<ResolveInfo> intentReceivers =
311-
ManifestInfo.getIntentReceivers(
312-
ParsePushBroadcastReceiver.ACTION_PUSH_RECEIVE,
313-
ParsePushBroadcastReceiver.ACTION_PUSH_DELETE,
314-
ParsePushBroadcastReceiver.ACTION_PUSH_OPEN);
324+
ManifestInfo.getIntentReceivers(
325+
ParsePushBroadcastReceiver.ACTION_PUSH_RECEIVE,
326+
ParsePushBroadcastReceiver.ACTION_PUSH_DELETE,
327+
ParsePushBroadcastReceiver.ACTION_PUSH_OPEN);
315328

316329
for (ResolveInfo resolveInfo : intentReceivers) {
317330
if (resolveInfo.activityInfo.exported) {
@@ -414,15 +427,15 @@ private static ParseEventuallyQueue getEventuallyQueue(Context context) {
414427
synchronized (MUTEX) {
415428
boolean isLocalDatastoreEnabled = Parse.isLocalDatastoreEnabled();
416429
if (eventuallyQueue == null
417-
|| (isLocalDatastoreEnabled && eventuallyQueue instanceof ParseCommandCache)
418-
|| (!isLocalDatastoreEnabled
419-
&& eventuallyQueue instanceof ParsePinningEventuallyQueue)) {
430+
|| (isLocalDatastoreEnabled && eventuallyQueue instanceof ParseCommandCache)
431+
|| (!isLocalDatastoreEnabled
432+
&& eventuallyQueue instanceof ParsePinningEventuallyQueue)) {
420433
checkContext();
421434
ParseHttpClient httpClient = ParsePlugins.get().restClient();
422435
eventuallyQueue =
423-
isLocalDatastoreEnabled
424-
? new ParsePinningEventuallyQueue(context, httpClient)
425-
: new ParseCommandCache(context, httpClient);
436+
isLocalDatastoreEnabled
437+
? new ParsePinningEventuallyQueue(context, httpClient)
438+
: new ParseCommandCache(context, httpClient);
426439

427440
// We still need to clear out the old command cache even if we're using Pinning in
428441
// case
@@ -436,33 +449,35 @@ private static ParseEventuallyQueue getEventuallyQueue(Context context) {
436449
}
437450
}
438451

439-
/** Used by Parse LiveQuery */
452+
/**
453+
* Used by Parse LiveQuery
454+
*/
440455
public static void checkInit() {
441456
if (ParsePlugins.get() == null) {
442457
throw new RuntimeException(
443-
"You must call Parse.initialize(Context)" + " before using the Parse library.");
458+
"You must call Parse.initialize(Context)" + " before using the Parse library.");
444459
}
445460

446461
if (ParsePlugins.get().applicationId() == null) {
447462
throw new RuntimeException(
448-
"applicationId is null. "
449-
+ "You must call Parse.initialize(Context)"
450-
+ " before using the Parse library.");
463+
"applicationId is null. "
464+
+ "You must call Parse.initialize(Context)"
465+
+ " before using the Parse library.");
451466
}
452467
}
453468

454469
static void checkContext() {
455470
if (ParsePlugins.get().applicationContext() == null) {
456471
throw new RuntimeException(
457-
"applicationContext is null. "
458-
+ "You must call Parse.initialize(Context)"
459-
+ " before using the Parse library.");
472+
"applicationContext is null. "
473+
+ "You must call Parse.initialize(Context)"
474+
+ " before using the Parse library.");
460475
}
461476
}
462477

463478
static boolean hasPermission(String permission) {
464479
return (getApplicationContext().checkCallingOrSelfPermission(permission)
465-
== PackageManager.PERMISSION_GRANTED);
480+
== PackageManager.PERMISSION_GRANTED);
466481
}
467482

468483
// endregion
@@ -472,10 +487,10 @@ static boolean hasPermission(String permission) {
472487
static void requirePermission(String permission) {
473488
if (!hasPermission(permission)) {
474489
throw new IllegalStateException(
475-
"To use this functionality, add this to your AndroidManifest.xml:\n"
476-
+ "<uses-permission android:name=\""
477-
+ permission
478-
+ "\" />");
490+
"To use this functionality, add this to your AndroidManifest.xml:\n"
491+
+ "<uses-permission android:name=\""
492+
+ permission
493+
+ "\" />");
479494
}
480495
}
481496

@@ -489,7 +504,7 @@ static void requirePermission(String permission) {
489504
static void registerParseCallbacks(ParseCallbacks listener) {
490505
if (isInitialized()) {
491506
throw new IllegalStateException(
492-
"You must register callbacks before Parse.initialize(Context)");
507+
"You must register callbacks before Parse.initialize(Context)");
493508
}
494509

495510
synchronized (MUTEX_CALLBACKS) {
@@ -537,7 +552,9 @@ private static ParseCallbacks[] collectParseCallbacks() {
537552
return callbacks;
538553
}
539554

540-
/** Returns the level of logging that will be displayed. */
555+
/**
556+
* Returns the level of logging that will be displayed.
557+
*/
541558
public static int getLogLevel() {
542559
return PLog.getLogLevel();
543560
}
@@ -569,7 +586,9 @@ interface ParseCallbacks {
569586
void onParseInitialized();
570587
}
571588

572-
/** Represents an opaque configuration for the {@code Parse} SDK configuration. */
589+
/**
590+
* Represents an opaque configuration for the {@code Parse} SDK configuration.
591+
*/
573592
public static final class Configuration {
574593
final Context context;
575594
final String applicationId;
@@ -591,7 +610,9 @@ private Configuration(Builder builder) {
591610
this.maxRetries = builder.maxRetries;
592611
}
593612

594-
/** Allows for simple constructing of a {@code Configuration} object. */
613+
/**
614+
* Allows for simple constructing of a {@code Configuration} object.
615+
*/
595616
public static final class Builder {
596617
private final Context context;
597618
private String applicationId;

0 commit comments

Comments
 (0)