@@ -58,7 +58,16 @@ class OneSignalStateSynchronizer {
5858 private static final String [] LOCATION_FIELDS = new String [] { "lat" , "long" , "loc_acc" , "loc_type" };
5959 private static final Set <String > LOCATION_FIELDS_SET = new HashSet <String >(Arrays .asList (LOCATION_FIELDS ));
6060
61+ // Object to synchronize to prevent concurrent modifications on syncValues and dependValues
62+ private static final Object syncLock = new Object () {};
63+
6164 static private JSONObject generateJsonDiff (JSONObject cur , JSONObject changedTo , JSONObject baseOutput , Set <String > includeFields ) {
65+ synchronized (syncLock ) {
66+ return synchronizedGenerateJsonDiff (cur , changedTo , baseOutput , includeFields );
67+ }
68+ }
69+
70+ static private JSONObject synchronizedGenerateJsonDiff (JSONObject cur , JSONObject changedTo , JSONObject baseOutput , Set <String > includeFields ) {
6271 Iterator <String > keys = changedTo .keys ();
6372 String key ;
6473 Object value ;
@@ -69,51 +78,49 @@ static private JSONObject generateJsonDiff(JSONObject cur, JSONObject changedTo,
6978 else
7079 output = new JSONObject ();
7180
72- synchronized (cur ) {
73- while (keys .hasNext ()) {
74- try {
75- key = keys .next ();
76- value = changedTo .get (key );
77-
78- if (cur .has (key )) {
79- if (value instanceof JSONObject ) {
80- JSONObject curValue = cur .getJSONObject (key );
81- JSONObject outValue = null ;
82- if (baseOutput != null && baseOutput .has (key ))
83- outValue = baseOutput .getJSONObject (key );
84- JSONObject returnedJson = generateJsonDiff (curValue , (JSONObject ) value , outValue , includeFields );
85- String returnedJsonStr = returnedJson .toString ();
86- if (!returnedJsonStr .equals ("{}" ))
87- output .put (key , new JSONObject (returnedJsonStr ));
88- }
89- else if (value instanceof JSONArray )
90- handleJsonArray (key , (JSONArray ) value , cur .getJSONArray (key ), output );
91- else if (includeFields != null && includeFields .contains (key ))
92- output .put (key , value );
93- else {
94- Object curValue = cur .get (key );
95- if (!value .equals (curValue )) {
96- // Work around for JSON serializer turning doubles/floats into ints since it drops ending 0's
97- if (curValue instanceof Integer && !"" .equals (value )) {
98- if ( ((Number )curValue ).doubleValue () != ((Number )value ).doubleValue ())
99- output .put (key , value );
100- }
101- else
81+ while (keys .hasNext ()) {
82+ try {
83+ key = keys .next ();
84+ value = changedTo .get (key );
85+
86+ if (cur .has (key )) {
87+ if (value instanceof JSONObject ) {
88+ JSONObject curValue = cur .getJSONObject (key );
89+ JSONObject outValue = null ;
90+ if (baseOutput != null && baseOutput .has (key ))
91+ outValue = baseOutput .getJSONObject (key );
92+ JSONObject returnedJson = synchronizedGenerateJsonDiff (curValue , (JSONObject ) value , outValue , includeFields );
93+ String returnedJsonStr = returnedJson .toString ();
94+ if (!returnedJsonStr .equals ("{}" ))
95+ output .put (key , new JSONObject (returnedJsonStr ));
96+ }
97+ else if (value instanceof JSONArray )
98+ handleJsonArray (key , (JSONArray ) value , cur .getJSONArray (key ), output );
99+ else if (includeFields != null && includeFields .contains (key ))
100+ output .put (key , value );
101+ else {
102+ Object curValue = cur .get (key );
103+ if (!value .equals (curValue )) {
104+ // Work around for JSON serializer turning doubles/floats into ints since it drops ending 0's
105+ if (curValue instanceof Integer && !"" .equals (value )) {
106+ if ( ((Number )curValue ).doubleValue () != ((Number )value ).doubleValue ())
102107 output .put (key , value );
103108 }
109+ else
110+ output .put (key , value );
104111 }
105112 }
106- else {
107- if (value instanceof JSONObject )
108- output .put (key , new JSONObject (value .toString ()));
109- else if (value instanceof JSONArray )
110- handleJsonArray (key , (JSONArray ) value , null , output );
111- else
112- output .put (key , value );
113- }
114- } catch (JSONException e ) {
115- e .printStackTrace ();
116113 }
114+ else {
115+ if (value instanceof JSONObject )
116+ output .put (key , new JSONObject (value .toString ()));
117+ else if (value instanceof JSONArray )
118+ handleJsonArray (key , (JSONArray ) value , null , output );
119+ else
120+ output .put (key , value );
121+ }
122+ } catch (JSONException e ) {
123+ e .printStackTrace ();
117124 }
118125 }
119126
@@ -167,7 +174,7 @@ private static JSONObject getTagsWithoutDeletedKeys(JSONObject jsonObject) {
167174 if (jsonObject .has ("tags" )) {
168175 JSONObject toReturn = new JSONObject ();
169176
170- synchronized (jsonObject ) {
177+ synchronized (syncLock ) {
171178 JSONObject keyValues = jsonObject .optJSONObject ("tags" );
172179
173180 Iterator <String > keys = keyValues .keys ();
@@ -335,14 +342,16 @@ private void loadState() {
335342 }
336343
337344 private void persistState () {
338- modifySyncValuesJsonArray ("pkgs" );
345+ synchronized (syncLock ) {
346+ modifySyncValuesJsonArray ("pkgs" );
339347
340- final SharedPreferences prefs = OneSignal .getGcmPreferences (appContext );
341- SharedPreferences .Editor editor = prefs .edit ();
348+ final SharedPreferences prefs = OneSignal .getGcmPreferences (appContext );
349+ SharedPreferences .Editor editor = prefs .edit ();
342350
343- editor .putString ("ONESIGNAL_USERSTATE_SYNCVALYES_" + persistKey , syncValues .toString ());
344- editor .putString ("ONESIGNAL_USERSTATE_DEPENDVALYES_" + persistKey , dependValues .toString ());
345- editor .commit ();
351+ editor .putString ("ONESIGNAL_USERSTATE_SYNCVALYES_" + persistKey , syncValues .toString ());
352+ editor .putString ("ONESIGNAL_USERSTATE_DEPENDVALYES_" + persistKey , dependValues .toString ());
353+ editor .commit ();
354+ }
346355 }
347356
348357 private void modifySyncValuesJsonArray (String baseKey ) {
@@ -380,24 +389,26 @@ private void persistStateAfterSync(JSONObject inDependValues, JSONObject inSyncV
380389 if (inSyncValues != null ) {
381390 OneSignalStateSynchronizer .generateJsonDiff (syncValues , inSyncValues , syncValues , null );
382391
383- if (inSyncValues .has ("tags" )) {
384- JSONObject newTags = new JSONObject ();
385- JSONObject curTags = inSyncValues .optJSONObject ("tags" );
386- Iterator <String > keys = curTags .keys ();
387- String key ;
388-
389- try {
390- while (keys .hasNext ()) {
391- key = keys .next ();
392- if (!"" .equals (curTags .optString (key )))
393- newTags .put (key , curTags .optString (key ));
394- }
392+ synchronized (syncLock ) {
393+ if (inSyncValues .has ("tags" )) {
394+ JSONObject newTags = new JSONObject ();
395+ JSONObject curTags = inSyncValues .optJSONObject ("tags" );
396+ Iterator <String > keys = curTags .keys ();
397+ String key ;
398+
399+ try {
400+ while (keys .hasNext ()) {
401+ key = keys .next ();
402+ if (!"" .equals (curTags .optString (key )))
403+ newTags .put (key , curTags .optString (key ));
404+ }
395405
396- if (newTags .toString ().equals ("{}" ))
397- syncValues .remove ("tags" );
398- else
399- syncValues .put ("tags" , newTags );
400- } catch (Throwable t ) {}
406+ if (newTags .toString ().equals ("{}" ))
407+ syncValues .remove ("tags" );
408+ else
409+ syncValues .put ("tags" , newTags );
410+ } catch (Throwable t ) {}
411+ }
401412 }
402413 }
403414
0 commit comments