Project

General

Profile

« Previous | Next » 

Revision a59f38d6

Added by Leszek Koltunski over 2 years ago

Add Firebase Cloud Messaging and Firebase In-App Messaging

View differences:

build.gradle
37 37
    api project(':distorted-objectlib')
38 38
    api project(':distorted-flags')
39 39

  
40
    implementation 'com.google.firebase:firebase-analytics:21.0.0'
41
    implementation 'com.google.firebase:firebase-crashlytics:18.2.11'
40
    implementation platform('com.google.firebase:firebase-bom:30.2.0')
41
    implementation 'com.google.firebase:firebase-messaging'
42
    implementation 'com.google.firebase:firebase-analytics'
43
    implementation 'com.google.firebase:firebase-crashlytics'
44
    implementation 'com.google.firebase:firebase-inappmessaging-display'
42 45
    implementation 'com.google.android.play:core:1.10.3'
43 46
    implementation 'androidx.appcompat:appcompat:1.4.2'
47
    implementation "androidx.work:work-runtime:2.7.1"
44 48
    implementation 'com.google.android.material:material:1.6.1'
45 49
    implementation project(path: ':distorted-puzzle-jsons')
46 50
    implementation project(path: ':distorted-puzzle-dmesh')
src/main/AndroidManifest.xml
32 32
        <activity android:name="org.distorted.config.ConfigActivity" android:exported="false" android:screenOrientation="portrait"/>
33 33
        <activity android:name="org.distorted.bandaged.BandagedCreatorActivity" android:exported="false" android:screenOrientation="portrait"/>
34 34
        <activity android:name="org.distorted.bandaged.BandagedPlayActivity" android:exported="false" android:screenOrientation="portrait"/>
35

  
36
        <service
37
            android:name="org.distorted.messaging.RubikMessagingService"
38
            android:exported="false">
39
            <intent-filter>
40
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
41
            </intent-filter>
42
        </service>
35 43
    </application>
36 44
</manifest>
src/main/java/org/distorted/external/RubikNetwork.java
116 116
    "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff"
117 117
    };
118 118

  
119
  private static final String SERVER="https://distorted.org/magic/cgi-bin/";
120

  
119 121
  private static String[][][] mCountry;
120 122
  private static String[][][] mName;
121 123
  private static float[][][] mTime;
......
440 442
  private String constructSuspiciousURL(String suspURL)
441 443
    {
442 444
    RubikScores scores = RubikScores.getInstance();
443
    int deviceID= scores.getDeviceID();
444
    String suspicious = URLencode(suspURL);
445
    int deviceID       = scores.getDeviceID();
446
    String suspicious  = URLencode(suspURL);
445 447

  
446
    String url="https://distorted.org/magic/cgi-bin/suspicious.cgi";
447
    url += "?i="+deviceID+"&d="+suspicious;
448
    return SERVER+"suspicious.cgi?i="+deviceID+"&d="+suspicious;
449
    }
448 450

  
449
    return url;
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

  
453
  private String constructTokenURL(String token)
454
    {
455
    RubikScores scores = RubikScores.getInstance();
456
    String name = URLencode(scores.getName());
457
    int deviceID= scores.getDeviceID();
458
    String country = scores.getCountry();
459
    String version = mVersion==null ? "null" : mVersion;
460
    String tkn = URLencode(token);
461

  
462
    return SERVER+"token.cgi?n="+name+"&i="+deviceID+"&e="+version+"&c="+country+"&t="+tkn;
450 463
    }
451 464

  
452 465
///////////////////////////////////////////////////////////////////////////////////////////////////
......
466 479
    renderer = URLencode(renderer);
467 480
    version  = URLencode(version);
468 481

  
469
    String url="https://distorted.org/magic/cgi-bin/debugs.cgi";
482
    String url=SERVER+"debugs.cgi";
470 483
    url += "?n="+name+"&r="+numRuns+"&p="+numPlay+"&c="+country+"&e="+mVersion+"d";
471 484
    url += "&d="+renderer+"&v="+version+"&a="+objectAPI+"&b="+tutorialAPI;
472 485

  
......
483 496
    int numPlay = scores.getNumPlays();
484 497
    String country = scores.getCountry();
485 498

  
486
    String url="https://distorted.org/magic/cgi-bin/download.cgi";
487
    url += "?n="+name+"&r="+numRuns+"&p="+numPlay+"&c="+country+"&e="+mVersion;
488

  
489
    return url;
499
    return SERVER+"download.cgi?n="+name+"&r="+numRuns+"&p="+numPlay+"&c="+country+"&e="+mVersion;
490 500
    }
491 501

  
492 502
///////////////////////////////////////////////////////////////////////////////////////////////////
......
511 521
    renderer = parseRenderer(type,renderer);
512 522
    version  = parseVersion(type,version);
513 523

  
514
    String url1="https://distorted.org/magic/cgi-bin/submit.cgi";
524
    String url1=SERVER+"submit.cgi";
515 525
    String url2 = "n="+name+"&v="+veri+"&r="+numRuns+"&p="+numPlay+"&i="+deviceID+"&e="+mVersion;
516 526
    url2 += "&d="+renderer+"&s="+version+reclist+"&c="+country+"&f="+epoch;
517 527
    String hash = computeHash( url2, salt.getBytes() );
......
670 680
      }
671 681
    }
672 682

  
683
///////////////////////////////////////////////////////////////////////////////////////////////////
684

  
685
  private void tokenThread(String token)
686
    {
687
    String url = constructTokenURL(token);
688

  
689
    try
690
      {
691
      java.net.URL connectURL = new URL(url);
692
      HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection();
693

  
694
      conn.setDoInput(true);
695
      conn.setDoOutput(true);
696
      conn.setUseCaches(false);
697
      conn.setRequestMethod("GET");
698
      conn.connect();
699
      conn.getOutputStream().flush();
700
      conn.getInputStream();
701
      conn.disconnect();
702
      }
703
    catch( final Exception e )
704
      {
705
      // ignore
706
      }
707
    }
708

  
673 709
///////////////////////////////////////////////////////////////////////////////////////////////////
674 710

  
675 711
  private Bitmap downloadIcon(String url)
......
900 936
    thread.start();
901 937
    }
902 938

  
939
///////////////////////////////////////////////////////////////////////////////////////////////////
940

  
941
  public void token(final String token)
942
    {
943
    initializeStatics();
944

  
945
    Thread thread = new Thread()
946
      {
947
      public void run()
948
        {
949
        tokenThread(token);
950
        }
951
      };
952

  
953
    thread.start();
954
    }
955

  
903 956
///////////////////////////////////////////////////////////////////////////////////////////////////
904 957
// Yes it can happen that the second Updatee registers before we sent an update to the first one
905 958
// and, as a result, the update never gets sent to the first one. This is not a problem (now, when
src/main/java/org/distorted/main/RubikActivity.java
41 41
import androidx.appcompat.app.AppCompatActivity;
42 42

  
43 43
import com.google.firebase.analytics.FirebaseAnalytics;
44
import com.google.firebase.inappmessaging.FirebaseInAppMessaging;
44 45

  
45 46
import org.distorted.config.ConfigActivity;
46 47
import org.distorted.bandaged.BandagedCreatorActivity;
47 48
import org.distorted.library.main.DistortedLibrary;
48 49

  
50
import org.distorted.messaging.RubikInAppMessanging;
49 51
import org.distorted.objectlib.main.ObjectControl;
50 52
import org.distorted.objectlib.main.TwistyObject;
51 53
import org.distorted.objectlib.effects.BaseEffect;
......
134 136
      hideNavigationBar();
135 137
      cutoutHack();
136 138
      computeBarHeights();
139

  
140
      RubikInAppMessanging listener = new RubikInAppMessanging();
141
      FirebaseInAppMessaging.getInstance().addClickListener(listener);
137 142
      }
138 143

  
139 144
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/messaging/RubikInAppMessanging.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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.messaging;
21

  
22
import com.google.firebase.inappmessaging.FirebaseInAppMessagingClickListener;
23
import com.google.firebase.inappmessaging.model.Action;
24
import com.google.firebase.inappmessaging.model.CampaignMetadata;
25
import com.google.firebase.inappmessaging.model.InAppMessage;
26

  
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

  
29
public class RubikInAppMessanging implements FirebaseInAppMessagingClickListener
30
{
31
    @Override
32
    public void messageClicked(InAppMessage inAppMessage, Action action)
33
      {
34
      // Determine which URL the user clicked
35
      String url = action.getActionUrl();
36

  
37
android.util.Log.e("D", "In App Messaging: url="+url);
38

  
39
      // Get general information about the campaign
40
      CampaignMetadata metadata = inAppMessage.getCampaignMetadata();
41

  
42
if( metadata!=null )
43
  {
44
  String id = metadata.getCampaignId();
45
  String name = metadata.getCampaignName();
46
  boolean test = metadata.getIsTestMessage();
47
  android.util.Log.e("D", "In App Messaging: id="+id+" name="+name+" test="+test);
48
  }
49

  
50
      }
51
}
src/main/java/org/distorted/messaging/RubikMessagingService.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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.messaging;
21

  
22
import android.content.Context;
23
import android.util.Log;
24

  
25
import androidx.annotation.NonNull;
26

  
27
import androidx.work.OneTimeWorkRequest;
28
import androidx.work.WorkManager;
29
import androidx.work.Worker;
30
import androidx.work.WorkerParameters;
31

  
32
import com.google.firebase.messaging.FirebaseMessagingService;
33
import com.google.firebase.messaging.RemoteMessage;
34

  
35
import org.distorted.external.RubikNetwork;
36

  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

  
39
public class RubikMessagingService extends FirebaseMessagingService
40
{
41
  private static final String TAG = "RubikMessagingService";
42

  
43
  public static class RubikWorker extends Worker
44
    {
45
    public RubikWorker(@NonNull Context context, @NonNull WorkerParameters workerParams)
46
      {
47
      super(context, workerParams);
48
      }
49

  
50
    @NonNull
51
    @Override
52
    public Result doWork()
53
      {
54
      return Result.success();
55
      }
56
    }
57

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

  
60
  @Override
61
  public void onMessageReceived(RemoteMessage remoteMessage)
62
    {
63
    Log.e(TAG, "From: " + remoteMessage.getFrom());
64

  
65
    if (remoteMessage.getData().size() > 0)
66
      {
67
      Log.e(TAG, "Message data payload: " + remoteMessage.getData());
68

  
69
      if (/* Check if data needs to be processed by long running job */ true)
70
        {
71
        scheduleJob();
72
        }
73
      else
74
        {
75
        handleNow();
76
        }
77
      }
78

  
79
    if (remoteMessage.getNotification() != null)
80
      {
81
      Log.e(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
82
      }
83
    }
84

  
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

  
87
  @Override
88
  public void onNewToken(@NonNull String token)
89
    {
90
    RubikNetwork network = RubikNetwork.getInstance();
91
    network.token(token);
92
    }
93

  
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

  
96
  private void scheduleJob()
97
    {
98
    OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(RubikWorker.class).build();
99
    WorkManager.getInstance(this).beginWith(work).enqueue();
100
    }
101

  
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

  
104
  private void handleNow()
105
    {
106

  
107
    }
108
}
src/main/java/org/distorted/solvers/cube3/SolverCoordCube.java
36 36
	static final short N_URtoUL   = 1320;  // 12!/(12-3)! permutation of UR,UF,UL edges
37 37
	static final short N_UBtoDF   = 1320;  // 12!/(12-3)! permutation of UB,DR,DF edges
38 38
	static final short N_URtoDF   = 20160; // 8!/(8-6)! permutation of UR,UF,UL,UB,DR,DF edges in phase2
39
	static final int N_URFtoDLB   = 40320; // 8! permutations of the corners
40
	static final int N_URtoBR     = 479001600;// 8! permutations of the corners
41 39
	static final short N_MOVE     = 18;
42 40

  
43 41
	// All coordinates are 0 for a solved cube except for UBtoDF, which is 114

Also available in: Unified diff