Project

General

Profile

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

magiccube / src / main / java / org / distorted / main / RubikObjectLibInterface.java @ 84d746d7

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.RubikScreenPlay;
49
import org.distorted.screens.RubikScreenReady;
50
import org.distorted.screens.RubikScreenSolver;
51
import org.distorted.screens.RubikScreenSolving;
52
import org.distorted.screens.ScreenList;
53
import org.distorted.solvers.SolverMain;
54

    
55
import java.lang.ref.WeakReference;
56

    
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

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

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

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

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

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

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

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

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

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

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

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

    
129
      FirebaseAnalytics analytics = act.getAnalytics();
130

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

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

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

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

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

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

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

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

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

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

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

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

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

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

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

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

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

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

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  public void onBeginRotation()
272
    {
273
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
274
      {
275
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
276
      solving.resetElapsed();
277
      RubikActivity act = mAct.get();
278

    
279
      act.runOnUiThread(new Runnable()
280
        {
281
        @Override
282
        public void run()
283
          {
284
          ScreenList.switchScreen( act, ScreenList.SOLV);
285
          }
286
        });
287
      }
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  public void failedToDrag()
293
    {
294
    ScreenList curr = ScreenList.getCurrentScreen();
295

    
296
    if( curr==ScreenList.PLAY )
297
      {
298
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
299
      play.reddenLock(mAct.get());
300
      }
301
    else if( curr==ScreenList.READ )
302
      {
303
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
304
      read.reddenLock(mAct.get());
305
      }
306
    else if( curr==ScreenList.SOLV )
307
      {
308
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
309
      solv.reddenLock(mAct.get());
310
      }
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  public void onSolved()
316
    {
317
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
318
      {
319
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
320
      mNewRecord = solving.getRecord();
321

    
322
      if( mNewRecord< 0 )
323
        {
324
        mNewRecord = -mNewRecord;
325
        mIsNewRecord = false;
326
        }
327
      else
328
        {
329
        mIsNewRecord = true;
330
        }
331
      }
332
    }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  public void onObjectCreated(long time)
337
    {
338

    
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  public void reportProblem(String problem, boolean recordException)
344
    {
345
    if( BuildConfig.DEBUG )
346
      {
347
      android.util.Log.e("libInterface", problem);
348
      }
349
    else
350
      {
351
      if( recordException )
352
        {
353
        Exception ex = new Exception(problem);
354
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
355
        crashlytics.setCustomKey("problem" , problem);
356
        crashlytics.recordException(ex);
357
        }
358
      else
359
        {
360
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
361
        crashlytics.log(problem);
362
        }
363
      }
364
    }
365

    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

    
368
  private void reportUIProblem(int place, long pause, long resume, long time)
369
    {
370
    String error = "UI BLOCK "+place+" blocked for "+time;
371

    
372
    if( BuildConfig.DEBUG )
373
       {
374
       android.util.Log.e("libInterface", error);
375
       }
376
    else
377
      {
378
      Exception ex = new Exception(error);
379
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
380
      crashlytics.setCustomKey("pause" , pause );
381
      crashlytics.setCustomKey("resume", resume );
382
      crashlytics.recordException(ex);
383
      }
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  private void reportTouchProblem(int place, long pause, long resume, long time)
389
    {
390
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
391

    
392
    if( BuildConfig.DEBUG )
393
       {
394
       android.util.Log.e("libInterface", error);
395
       }
396
    else
397
      {
398
      Exception ex = new Exception(error);
399
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
400
      crashlytics.setCustomKey("pause" , pause );
401
      crashlytics.setCustomKey("resume", resume);
402
      crashlytics.recordException(ex);
403
      }
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  private void reportThreadProblem(int place, long pause, long resume, long time)
409
    {
410
    String error = EffectMessageSender.reportState();
411

    
412
    if( BuildConfig.DEBUG )
413
       {
414
       android.util.Log.e("libInterface", error);
415
       }
416
    else
417
      {
418
      Exception ex = new Exception(error);
419
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
420
      crashlytics.setCustomKey("pause" , pause  );
421
      crashlytics.setCustomKey("resume", resume );
422
      crashlytics.recordException(ex);
423
      }
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
429
    {
430
    switch(type)
431
      {
432
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
433
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
434
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
435
      }
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public void onReplaceModeDown(int cubit, int face)
441
    {
442
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
443
    int color = solver.getCurrentColor();
444
    int currObject = RubikObjectList.getCurrObject();
445
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
446
    mLastCubit = cubit;
447
    mLastCubitFace = face;
448
    ObjectControl control = mAct.get().getControl();
449
    control.setTextureMap( cubit, face, color );
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  public void onReplaceModeUp()
455
    {
456
    if( mLastCubitColor>=0 )
457
      {
458
      ObjectControl control = mAct.get().getControl();
459
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
460
      mLastCubitColor = -1;
461
      }
462
    }
463
}
(2-2/4)