Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.main;
21

    
22
import android.os.Bundle;
23

    
24
import androidx.annotation.NonNull;
25

    
26
import com.google.android.play.core.review.ReviewInfo;
27
import com.google.android.play.core.review.ReviewManager;
28
import com.google.android.play.core.review.ReviewManagerFactory;
29
import com.google.android.play.core.tasks.OnCompleteListener;
30
import com.google.android.play.core.tasks.OnFailureListener;
31
import com.google.android.play.core.tasks.Task;
32
import com.google.firebase.analytics.FirebaseAnalytics;
33
import com.google.firebase.crashlytics.FirebaseCrashlytics;
34

    
35
import org.distorted.library.message.EffectMessageSender;
36

    
37
import org.distorted.external.RubikNetwork;
38
import org.distorted.objectlib.BuildConfig;
39
import org.distorted.objectlib.helpers.BlockController;
40
import org.distorted.objectlib.helpers.ObjectLibInterface;
41
import org.distorted.objectlib.main.ObjectControl;
42

    
43
import org.distorted.dialogs.RubikDialogNewRecord;
44
import org.distorted.dialogs.RubikDialogSolved;
45
import org.distorted.external.RubikScores;
46
import org.distorted.objects.RubikObject;
47
import org.distorted.objects.RubikObjectList;
48
import org.distorted.screens.RubikScreenFreePlay;
49
import org.distorted.screens.RubikScreenPlay;
50
import org.distorted.screens.RubikScreenReady;
51
import org.distorted.screens.RubikScreenSolver;
52
import org.distorted.screens.RubikScreenSolving;
53
import org.distorted.screens.ScreenList;
54
import org.distorted.solvers.SolverMain;
55

    
56
import java.lang.ref.WeakReference;
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
public class RubikObjectLibInterface implements ObjectLibInterface
61
{
62
  private final WeakReference<RubikActivity> mAct;
63
  private boolean mIsNewRecord;
64
  private long mNewRecord;
65
  private int mLastCubitColor, mLastCubit, mLastCubitFace;
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  RubikObjectLibInterface(RubikActivity act)
70
    {
71
    mAct = new WeakReference<>(act);
72
    mLastCubitColor = -1;
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
78
    {
79
    long elapsed = System.currentTimeMillis() - timeBegin;
80
    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
81

    
82
    if( BuildConfig.DEBUG )
83
       {
84
       android.util.Log.d("libInterface", msg);
85
       }
86
    else
87
      {
88
      FirebaseAnalytics analytics = act.getAnalytics();
89

    
90
      if( analytics!=null )
91
        {
92
        Bundle bundle = new Bundle();
93
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
94
        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
95
        }
96
      }
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private void reportRecord(RubikActivity act, long startTime, long endTime, String debug, int scrambleNum)
102
    {
103
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
104
    RubikScores scores  = RubikScores.getInstance();
105
    int object  = RubikObjectList.getCurrObject();
106
    int level   = play.getLevel();
107
    String name = scores.getName();
108
    RubikObject obj = RubikObjectList.getObject(object);
109
    String objName = obj==null ? "NULL" : obj.getUpperName();
110

    
111
    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
112

    
113
    if( BuildConfig.DEBUG )
114
       {
115
       android.util.Log.e("libInterface", debug);
116
       android.util.Log.e("libInterface", name);
117
       android.util.Log.e("libInterface", record);
118
       }
119
    else
120
      {
121
      if( level>=9 && mNewRecord<300*level )
122
        {
123
        long timeNow = System.currentTimeMillis();
124
        long elapsed = timeNow - startTime;
125
        String suspicious ="start"+startTime+"end"+endTime+"elapsed"+elapsed+"obj"+objName+"level"+level+"record"+mNewRecord+"scrambles"+scrambleNum+debug;
126
        RubikNetwork network = RubikNetwork.getInstance();
127
        network.suspicious(suspicious,act);
128
        }
129

    
130
      FirebaseAnalytics analytics = act.getAnalytics();
131

    
132
      if( analytics!=null )
133
        {
134
        Bundle bundle = new Bundle();
135
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
136
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
137
        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
138
        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
139
        }
140
      }
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  private void requestReview(RubikActivity act)
146
    {
147
    final RubikScores scores = RubikScores.getInstance();
148
    int numWins = scores.incrementNumWins();
149

    
150
    if( numWins==7 || numWins==30 || numWins==100 || numWins==200)
151
      {
152
      final long timeBegin = System.currentTimeMillis();
153
      final ReviewManager manager = ReviewManagerFactory.create(act);
154
      Task<ReviewInfo> request = manager.requestReviewFlow();
155

    
156
      request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
157
        {
158
        @Override
159
        public void onComplete (@NonNull Task<ReviewInfo> task)
160
          {
161
          if (task.isSuccessful())
162
            {
163
            final String name = scores.getName();
164
            ReviewInfo reviewInfo = task.getResult();
165
            Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
166

    
167
            flow.addOnFailureListener(new OnFailureListener()
168
              {
169
              @Override
170
              public void onFailure(Exception e)
171
                {
172
                analyticsReport(act,"Failed", name, timeBegin);
173
                }
174
              });
175

    
176
            flow.addOnCompleteListener(new OnCompleteListener<Void>()
177
              {
178
              @Override
179
              public void onComplete(@NonNull Task<Void> task)
180
                {
181
                analyticsReport(act,"Complete", name, timeBegin);
182
                }
183
              });
184
            }
185
          else
186
            {
187
            String name = scores.getName();
188
            analyticsReport(act,"Not Successful", name, timeBegin);
189
            }
190
          }
191
        });
192
      }
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum)
198
    {
199
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
200
      {
201
      RubikActivity act = mAct.get();
202
      Bundle bundle = new Bundle();
203
      bundle.putLong("time", mNewRecord );
204

    
205
      reportRecord(act,startTime,endTime,debug,scrambleNum);
206
      requestReview(act);
207

    
208
      if( mIsNewRecord )
209
        {
210
        RubikDialogNewRecord dialog = new RubikDialogNewRecord();
211
        dialog.setArguments(bundle);
212
        dialog.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
213
        }
214
      else
215
        {
216
        RubikDialogSolved dialog = new RubikDialogSolved();
217
        dialog.setArguments(bundle);
218
        dialog.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
219
        }
220

    
221
      act.runOnUiThread(new Runnable()
222
        {
223
        @Override
224
        public void run()
225
          {
226
          ScreenList.switchScreen( act, ScreenList.DONE);
227
          }
228
        });
229
      }
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  public void onScrambleEffectFinished()
235
    {
236
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
237

    
238
    if( play.shouldReactToEndOfScrambling() )
239
      {
240
      RubikActivity act = mAct.get();
241
      RubikScores.getInstance().incrementNumPlays();
242

    
243
      act.runOnUiThread(new Runnable()
244
        {
245
        @Override
246
        public void run()
247
        {
248
        ScreenList.switchScreen( act, ScreenList.READ);
249
        }
250
        });
251
      }
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  public void onFinishRotation(int axis, int row, int angle)
257
    {
258
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
259
      {
260
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
261
      solv.addMove(mAct.get(), axis, row, angle);
262
      }
263
    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
264
      {
265
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
266
      play.addMove(mAct.get(), axis, row, angle);
267
      }
268
    if( ScreenList.getCurrentScreen()== ScreenList.FREE )
269
      {
270
      RubikScreenFreePlay free = (RubikScreenFreePlay) ScreenList.FREE.getScreenClass();
271
      free.addMove(mAct.get(), axis, row, angle);
272
      }
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  public void onBeginRotation()
278
    {
279
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
280
      {
281
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
282
      solving.resetElapsed();
283
      RubikActivity act = mAct.get();
284

    
285
      act.runOnUiThread(new Runnable()
286
        {
287
        @Override
288
        public void run()
289
          {
290
          ScreenList.switchScreen( act, ScreenList.SOLV);
291
          }
292
        });
293
      }
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  public void failedToDrag()
299
    {
300
    ScreenList curr = ScreenList.getCurrentScreen();
301

    
302
    if( curr==ScreenList.PLAY )
303
      {
304
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
305
      play.reddenLock(mAct.get());
306
      }
307
    else if( curr==ScreenList.READ )
308
      {
309
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
310
      read.reddenLock(mAct.get());
311
      }
312
    else if( curr==ScreenList.SOLV )
313
      {
314
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
315
      solv.reddenLock(mAct.get());
316
      }
317
    else if( curr==ScreenList.FREE )
318
      {
319
      RubikScreenFreePlay free = (RubikScreenFreePlay) ScreenList.FREE.getScreenClass();
320
      free.reddenLock(mAct.get());
321
      }
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  public void onSolved()
327
    {
328
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
329
      {
330
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
331
      mNewRecord = solving.getRecord();
332

    
333
      if( mNewRecord< 0 )
334
        {
335
        mNewRecord = -mNewRecord;
336
        mIsNewRecord = false;
337
        }
338
      else
339
        {
340
        mIsNewRecord = true;
341
        }
342
      }
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  public void onObjectCreated(long time)
348
    {
349

    
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  public void reportProblem(String problem, boolean recordException)
355
    {
356
    if( BuildConfig.DEBUG )
357
      {
358
      android.util.Log.e("libInterface", problem);
359
      }
360
    else
361
      {
362
      if( recordException )
363
        {
364
        Exception ex = new Exception(problem);
365
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
366
        crashlytics.setCustomKey("problem" , problem);
367
        crashlytics.recordException(ex);
368
        }
369
      else
370
        {
371
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
372
        crashlytics.log(problem);
373
        }
374
      }
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  private void reportUIProblem(int place, long pause, long resume, long time)
380
    {
381
    String error = "UI BLOCK "+place+" blocked for "+time;
382

    
383
    if( BuildConfig.DEBUG )
384
       {
385
       android.util.Log.e("libInterface", error);
386
       }
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 reportTouchProblem(int place, long pause, long resume, long time)
400
    {
401
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
402

    
403
    if( BuildConfig.DEBUG )
404
       {
405
       android.util.Log.e("libInterface", error);
406
       }
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
  private void reportThreadProblem(int place, long pause, long resume, long time)
420
    {
421
    String error = EffectMessageSender.reportState();
422

    
423
    if( BuildConfig.DEBUG )
424
       {
425
       android.util.Log.e("libInterface", error);
426
       }
427
    else
428
      {
429
      Exception ex = new Exception(error);
430
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
431
      crashlytics.setCustomKey("pause" , pause  );
432
      crashlytics.setCustomKey("resume", resume );
433
      crashlytics.recordException(ex);
434
      }
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
440
    {
441
    switch(type)
442
      {
443
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
444
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
445
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
446
      }
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450

    
451
  public void onReplaceModeDown(int cubit, int face)
452
    {
453
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
454
    int color = solver.getCurrentColor();
455
    int currObject = RubikObjectList.getCurrObject();
456
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
457
    mLastCubit = cubit;
458
    mLastCubitFace = face;
459
    ObjectControl control = mAct.get().getControl();
460
    control.setTextureMap( cubit, face, color );
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public void onReplaceModeUp()
466
    {
467
    if( mLastCubitColor>=0 )
468
      {
469
      ObjectControl control = mAct.get().getControl();
470
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
471
      mLastCubitColor = -1;
472
      }
473
    }
474
}
(2-2/4)