Project

General

Profile

Download (15.7 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main / RubikObjectLibInterface.java @ fad10885

1 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 296219b4 Leszek Koltunski
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.main;
11
12
import android.os.Bundle;
13
14
import androidx.annotation.NonNull;
15
16
import com.google.android.play.core.review.ReviewInfo;
17
import com.google.android.play.core.review.ReviewManager;
18
import com.google.android.play.core.review.ReviewManagerFactory;
19
import com.google.android.play.core.tasks.OnCompleteListener;
20
import com.google.android.play.core.tasks.OnFailureListener;
21
import com.google.android.play.core.tasks.Task;
22
import com.google.firebase.analytics.FirebaseAnalytics;
23 95472aca Leszek Koltunski
import com.google.firebase.crashlytics.FirebaseCrashlytics;
24 1cd323dd Leszek Koltunski
25 95472aca Leszek Koltunski
import org.distorted.library.message.EffectMessageSender;
26 8723caee Leszek Koltunski
27 acabdd83 Leszek Koltunski
import org.distorted.external.RubikNetwork;
28 95472aca Leszek Koltunski
import org.distorted.objectlib.BuildConfig;
29
import org.distorted.objectlib.helpers.BlockController;
30 e019c70b Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectLibInterface;
31 5c4ed8ed Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
32 1cd323dd Leszek Koltunski
33
import org.distorted.dialogs.RubikDialogNewRecord;
34
import org.distorted.dialogs.RubikDialogSolved;
35 acabdd83 Leszek Koltunski
import org.distorted.external.RubikScores;
36 d433b50e Leszek Koltunski
import org.distorted.objects.RubikObject;
37
import org.distorted.objects.RubikObjectList;
38 1cd323dd Leszek Koltunski
import org.distorted.screens.RubikScreenPlay;
39 dd1a65c1 Leszek Koltunski
import org.distorted.screens.RubikScreenReady;
40
import org.distorted.screens.RubikScreenSolver;
41 1cd323dd Leszek Koltunski
import org.distorted.screens.RubikScreenSolving;
42
import org.distorted.screens.ScreenList;
43 dd1a65c1 Leszek Koltunski
import org.distorted.solvers.SolverMain;
44 1cd323dd Leszek Koltunski
45 e019c70b Leszek Koltunski
import java.lang.ref.WeakReference;
46
47 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
48
49 e019c70b Leszek Koltunski
public class RubikObjectLibInterface implements ObjectLibInterface
50 1cd323dd Leszek Koltunski
{
51 5c4ed8ed Leszek Koltunski
  private final WeakReference<RubikActivity> mAct;
52 1cd323dd Leszek Koltunski
  private boolean mIsNewRecord;
53
  private long mNewRecord;
54 5c4ed8ed Leszek Koltunski
  private int mLastCubitColor, mLastCubit, mLastCubitFace;
55 1cd323dd Leszek Koltunski
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
58 e019c70b Leszek Koltunski
  RubikObjectLibInterface(RubikActivity act)
59
    {
60
    mAct = new WeakReference<>(act);
61 5c4ed8ed Leszek Koltunski
    mLastCubitColor = -1;
62 e019c70b Leszek Koltunski
    }
63
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
66
  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
67 1cd323dd Leszek Koltunski
    {
68
    long elapsed = System.currentTimeMillis() - timeBegin;
69
    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
70
71
    if( BuildConfig.DEBUG )
72
       {
73 d38a302b Leszek Koltunski
       android.util.Log.d("libInterface", msg);
74 1cd323dd Leszek Koltunski
       }
75
    else
76
      {
77 e019c70b Leszek Koltunski
      FirebaseAnalytics analytics = act.getAnalytics();
78 1cd323dd Leszek Koltunski
79
      if( analytics!=null )
80
        {
81
        Bundle bundle = new Bundle();
82
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
83
        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
84
        }
85
      }
86
    }
87
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90 1fa125c2 Leszek Koltunski
  private void reportRecord(RubikActivity act, long startTime, long endTime, String debug, int scrambleNum)
91 1cd323dd Leszek Koltunski
    {
92 8ab435b9 Leszek Koltunski
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
93
    RubikScores scores  = RubikScores.getInstance();
94 400ff34d Leszek Koltunski
    int object  = RubikObjectList.getCurrObject();
95 d433b50e Leszek Koltunski
    int level   = play.getLevel();
96
    String name = scores.getName();
97
    RubikObject obj = RubikObjectList.getObject(object);
98 84d746d7 Leszek Koltunski
    String objName = obj==null ? "NULL" : obj.getUpperName();
99 d433b50e Leszek Koltunski
100 d38a302b Leszek Koltunski
    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
101 1cd323dd Leszek Koltunski
102
    if( BuildConfig.DEBUG )
103
       {
104 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", debug);
105
       android.util.Log.e("libInterface", name);
106
       android.util.Log.e("libInterface", record);
107 1cd323dd Leszek Koltunski
       }
108
    else
109
      {
110 1fa125c2 Leszek Koltunski
      if( level>=9 && mNewRecord<300*level )
111
        {
112 6eb4c104 Leszek Koltunski
        long timeNow = System.currentTimeMillis();
113
        long elapsed = timeNow - startTime;
114 1fa125c2 Leszek Koltunski
        String suspicious ="start"+startTime+"end"+endTime+"elapsed"+elapsed+"obj"+objName+"level"+level+"record"+mNewRecord+"scrambles"+scrambleNum+debug;
115
        RubikNetwork network = RubikNetwork.getInstance();
116 e4854e54 Leszek Koltunski
        network.suspicious(suspicious,act);
117 1fa125c2 Leszek Koltunski
        }
118
119 e019c70b Leszek Koltunski
      FirebaseAnalytics analytics = act.getAnalytics();
120 1cd323dd Leszek Koltunski
121
      if( analytics!=null )
122
        {
123
        Bundle bundle = new Bundle();
124
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
125
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
126
        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
127
        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
128
        }
129
      }
130
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134 e019c70b Leszek Koltunski
  private void requestReview(RubikActivity act)
135 1cd323dd Leszek Koltunski
    {
136
    final RubikScores scores = RubikScores.getInstance();
137
    int numWins = scores.incrementNumWins();
138 53b4c7ad Leszek Koltunski
    int numRuns = scores.getNumRuns();
139 1cd323dd Leszek Koltunski
140 53b4c7ad Leszek Koltunski
    if( numRuns==3 || numRuns==6 || numWins==7 || numWins==30 || numWins==50 || numWins==80 || numWins==100)
141 1cd323dd Leszek Koltunski
      {
142
      final long timeBegin = System.currentTimeMillis();
143
      final ReviewManager manager = ReviewManagerFactory.create(act);
144
      Task<ReviewInfo> request = manager.requestReviewFlow();
145
146
      request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
147
        {
148
        @Override
149
        public void onComplete (@NonNull Task<ReviewInfo> task)
150
          {
151
          if (task.isSuccessful())
152
            {
153
            final String name = scores.getName();
154
            ReviewInfo reviewInfo = task.getResult();
155
            Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
156
157
            flow.addOnFailureListener(new OnFailureListener()
158
              {
159
              @Override
160
              public void onFailure(Exception e)
161
                {
162
                analyticsReport(act,"Failed", name, timeBegin);
163
                }
164
              });
165
166
            flow.addOnCompleteListener(new OnCompleteListener<Void>()
167
              {
168
              @Override
169
              public void onComplete(@NonNull Task<Void> task)
170
                {
171
                analyticsReport(act,"Complete", name, timeBegin);
172
                }
173
              });
174
            }
175
          else
176
            {
177
            String name = scores.getName();
178
            analyticsReport(act,"Not Successful", name, timeBegin);
179
            }
180
          }
181
        });
182
      }
183
    }
184
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
187 1fa125c2 Leszek Koltunski
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum)
188 e019c70b Leszek Koltunski
    {
189
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
190
      {
191
      RubikActivity act = mAct.get();
192
      Bundle bundle = new Bundle();
193
      bundle.putLong("time", mNewRecord );
194
195 1fa125c2 Leszek Koltunski
      reportRecord(act,startTime,endTime,debug,scrambleNum);
196 e019c70b Leszek Koltunski
      requestReview(act);
197
198
      if( mIsNewRecord )
199
        {
200
        RubikDialogNewRecord dialog = new RubikDialogNewRecord();
201
        dialog.setArguments(bundle);
202
        dialog.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
203
        }
204
      else
205
        {
206
        RubikDialogSolved dialog = new RubikDialogSolved();
207
        dialog.setArguments(bundle);
208
        dialog.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
209
        }
210
211
      act.runOnUiThread(new Runnable()
212
        {
213
        @Override
214
        public void run()
215
          {
216
          ScreenList.switchScreen( act, ScreenList.DONE);
217
          }
218
        });
219
      }
220
    }
221 1cd323dd Leszek Koltunski
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223
224 e019c70b Leszek Koltunski
  public void onScrambleEffectFinished()
225
    {
226 dd874ae8 Leszek Koltunski
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
227 1cd323dd Leszek Koltunski
228 dd874ae8 Leszek Koltunski
    if( play.shouldReactToEndOfScrambling() )
229 e019c70b Leszek Koltunski
      {
230 dd874ae8 Leszek Koltunski
      RubikActivity act = mAct.get();
231
      RubikScores.getInstance().incrementNumPlays();
232
233
      act.runOnUiThread(new Runnable()
234
        {
235
        @Override
236
        public void run()
237 e019c70b Leszek Koltunski
        {
238
        ScreenList.switchScreen( act, ScreenList.READ);
239
        }
240 dd874ae8 Leszek Koltunski
        });
241
      }
242 e019c70b Leszek Koltunski
    }
243 1cd323dd Leszek Koltunski
244 e019c70b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246
  public void onFinishRotation(int axis, int row, int angle)
247
    {
248
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
249
      {
250
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
251
      solv.addMove(mAct.get(), axis, row, angle);
252
      }
253
    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
254
      {
255
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
256
      play.addMove(mAct.get(), axis, row, angle);
257
      }
258
    }
259 1cd323dd Leszek Koltunski
260 dd1a65c1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
261
262 e019c70b Leszek Koltunski
  public void onBeginRotation()
263
    {
264
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
265
      {
266
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
267
      solving.resetElapsed();
268
      RubikActivity act = mAct.get();
269
270
      act.runOnUiThread(new Runnable()
271
        {
272
        @Override
273
        public void run()
274
          {
275
          ScreenList.switchScreen( act, ScreenList.SOLV);
276
          }
277
        });
278
      }
279
    }
280 dd1a65c1 Leszek Koltunski
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283 e019c70b Leszek Koltunski
  public void failedToDrag()
284
    {
285
    ScreenList curr = ScreenList.getCurrentScreen();
286
287
    if( curr==ScreenList.PLAY )
288
      {
289
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
290
      play.reddenLock(mAct.get());
291
      }
292
    else if( curr==ScreenList.READ )
293
      {
294
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
295
      read.reddenLock(mAct.get());
296
      }
297
    else if( curr==ScreenList.SOLV )
298
      {
299
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
300
      solv.reddenLock(mAct.get());
301
      }
302
    }
303 dd1a65c1 Leszek Koltunski
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306 e019c70b Leszek Koltunski
  public void onSolved()
307
    {
308
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
309 dd1a65c1 Leszek Koltunski
      {
310 e019c70b Leszek Koltunski
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
311
      mNewRecord = solving.getRecord();
312 dd1a65c1 Leszek Koltunski
313 e019c70b Leszek Koltunski
      if( mNewRecord< 0 )
314 dd1a65c1 Leszek Koltunski
        {
315 e019c70b Leszek Koltunski
        mNewRecord = -mNewRecord;
316
        mIsNewRecord = false;
317 dd1a65c1 Leszek Koltunski
        }
318 e019c70b Leszek Koltunski
      else
319 dd1a65c1 Leszek Koltunski
        {
320 e019c70b Leszek Koltunski
        mIsNewRecord = true;
321 dd1a65c1 Leszek Koltunski
        }
322
      }
323 e019c70b Leszek Koltunski
    }
324 dd1a65c1 Leszek Koltunski
325 e709e44d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
326
327
  public void onObjectCreated(long time)
328
    {
329
330
    }
331
332 95472aca Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
333
334 eb647d5e Leszek Koltunski
  public void reportProblem(String problem, boolean recordException)
335 95472aca Leszek Koltunski
    {
336
    if( BuildConfig.DEBUG )
337
      {
338 d38a302b Leszek Koltunski
      android.util.Log.e("libInterface", problem);
339 95472aca Leszek Koltunski
      }
340
    else
341
      {
342 eb647d5e Leszek Koltunski
      if( recordException )
343
        {
344
        Exception ex = new Exception(problem);
345
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
346
        crashlytics.setCustomKey("problem" , problem);
347
        crashlytics.recordException(ex);
348
        }
349
      else
350
        {
351
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
352
        crashlytics.log(problem);
353
        }
354 95472aca Leszek Koltunski
      }
355
    }
356
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358
359
  private void reportUIProblem(int place, long pause, long resume, long time)
360
    {
361
    String error = "UI BLOCK "+place+" blocked for "+time;
362
363
    if( BuildConfig.DEBUG )
364
       {
365 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
366 95472aca Leszek Koltunski
       }
367
    else
368
      {
369
      Exception ex = new Exception(error);
370
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
371
      crashlytics.setCustomKey("pause" , pause );
372
      crashlytics.setCustomKey("resume", resume );
373
      crashlytics.recordException(ex);
374
      }
375
    }
376
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378
379
  private void reportTouchProblem(int place, long pause, long resume, long time)
380
    {
381
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
382
383
    if( BuildConfig.DEBUG )
384
       {
385 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
386 95472aca Leszek Koltunski
       }
387
    else
388
      {
389
      Exception ex = new Exception(error);
390
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
391
      crashlytics.setCustomKey("pause" , pause );
392
      crashlytics.setCustomKey("resume", resume);
393
      crashlytics.recordException(ex);
394
      }
395
    }
396
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398
399
  private void reportThreadProblem(int place, long pause, long resume, long time)
400
    {
401
    String error = EffectMessageSender.reportState();
402
403
    if( BuildConfig.DEBUG )
404
       {
405 d38a302b Leszek Koltunski
       android.util.Log.e("libInterface", error);
406 95472aca Leszek Koltunski
       }
407
    else
408
      {
409
      Exception ex = new Exception(error);
410
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
411
      crashlytics.setCustomKey("pause" , pause  );
412
      crashlytics.setCustomKey("resume", resume );
413
      crashlytics.recordException(ex);
414
      }
415
    }
416
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
419
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
420
    {
421
    switch(type)
422
      {
423
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
424
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
425
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
426
      }
427
    }
428
429 c020555e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
430
431
  public void reportJSONError(String error, int ordinal)
432
    {
433
    RubikObject object = RubikObjectList.getObject(ordinal);
434
    String name = object==null ? "NULL" : object.getUpperName();
435
436
    if( BuildConfig.DEBUG )
437
       {
438
       android.util.Log.e("libInterface", "name="+name+" JSON error: "+error);
439
       }
440
    else
441
      {
442
      Exception ex = new Exception(error);
443
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
444
      crashlytics.setCustomKey("name" , name );
445
      crashlytics.setCustomKey("JSONerror", error );
446
      crashlytics.recordException(ex);
447
      }
448
    }
449
450 1cd323dd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
451
452 5c4ed8ed Leszek Koltunski
  public void onReplaceModeDown(int cubit, int face)
453 e019c70b Leszek Koltunski
    {
454
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
455 5c4ed8ed Leszek Koltunski
    int color = solver.getCurrentColor();
456 400ff34d Leszek Koltunski
    int currObject = RubikObjectList.getCurrObject();
457 5c4ed8ed Leszek Koltunski
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
458
    mLastCubit = cubit;
459
    mLastCubitFace = face;
460
    ObjectControl control = mAct.get().getControl();
461
    control.setTextureMap( cubit, face, color );
462 e019c70b Leszek Koltunski
    }
463 1cd323dd Leszek Koltunski
464 e019c70b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
465
466 5c4ed8ed Leszek Koltunski
  public void onReplaceModeUp()
467 e019c70b Leszek Koltunski
    {
468 5c4ed8ed Leszek Koltunski
    if( mLastCubitColor>=0 )
469
      {
470
      ObjectControl control = mAct.get().getControl();
471
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
472
      mLastCubitColor = -1;
473
      }
474 e019c70b Leszek Koltunski
    }
475 1cd323dd Leszek Koltunski
}