Start migration to WorkManager

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2018-08-10 02:09:41 +02:00
Родитель 6c1ec00693
Коммит 6bc78aae90
5 изменённых файлов: 184 добавлений и 136 удалений

Просмотреть файл

@ -66,6 +66,7 @@ android {
ext {
supportLibraryVersion = '27.1.1'
workVersion = "1.0.0-alpha06"
}
@ -84,6 +85,9 @@ dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation "com.android.support:support-emoji-bundled:${supportLibraryVersion}"
implementation "com.android.support:palette-v7:${supportLibraryVersion}"
implementation "android.arch.work:work-runtime:${workVersion}"
implementation "android.arch.work:work-firebase:${workVersion}"
androidTestImplementation "android.arch.work:work-testing:${workVersion}"
implementation "android.arch.lifecycle:extensions:1.1.1"

Просмотреть файл

@ -22,13 +22,15 @@ package com.nextcloud.talk.services.firebase;
import android.annotation.SuppressLint;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.nextcloud.talk.jobs.NotificationJob;
import com.nextcloud.talk.jobs.NotificationWorker;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
public class MagicFirebaseMessagingService extends FirebaseMessagingService {
@SuppressLint("LongLogTag")
@ -39,17 +41,15 @@ public class MagicFirebaseMessagingService extends FirebaseMessagingService {
}
if (remoteMessage.getData() != null) {
PersistableBundleCompat persistableBundleCompat = new PersistableBundleCompat();
persistableBundleCompat.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, remoteMessage.getData().get
("subject"));
persistableBundleCompat.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, remoteMessage.getData().get
("signature"));
new JobRequest.Builder(NotificationJob.TAG)
.addExtras(persistableBundleCompat)
.setUpdateCurrent(false)
.startNow()
.build()
.schedule();
Data messageData = new Data.Builder()
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, remoteMessage.getData().get("subject"))
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, remoteMessage.getData().get("signature"))
.build();
OneTimeWorkRequest mathWork = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setInputData(messageData)
.build();
WorkManager.getInstance().enqueue(mathWork);
}
}
}

Просмотреть файл

@ -40,8 +40,6 @@ import android.util.Base64;
import android.util.Log;
import com.bluelinelabs.logansquare.LoganSquare;
import com.evernote.android.job.Job;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.nextcloud.talk.R;
import com.nextcloud.talk.activities.MagicCallActivity;
import com.nextcloud.talk.activities.MainActivity;
@ -79,14 +77,16 @@ import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.inject.Inject;
import androidx.work.Data;
import androidx.work.Worker;
import autodagger.AutoInjector;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
@AutoInjector(NextcloudTalkApplication.class)
public class NotificationJob extends Job {
public static final String TAG = "NotificationJob";
public class NotificationWorker extends Worker {
public static final String TAG = "NotificationWorker";
@Inject
UserUtils userUtils;
@ -102,119 +102,6 @@ public class NotificationJob extends Job {
private SignatureVerification signatureVerification;
private String conversationType = "";
@NonNull
@Override
protected Result onRunJob(Params params) {
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
context = getContext();
PersistableBundleCompat persistableBundleCompat = getParams().getExtras();
String subject = persistableBundleCompat.getString(BundleKeys.KEY_NOTIFICATION_SUBJECT, "");
String signature = persistableBundleCompat.getString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, "");
if (!TextUtils.isEmpty(subject) && !TextUtils.isEmpty(signature)) {
try {
byte[] base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT);
byte[] base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT);
PushUtils pushUtils = new PushUtils();
PrivateKey privateKey = (PrivateKey) pushUtils.readKeyFromFile(false);
try {
signatureVerification = pushUtils.verifySignature(base64DecodedSignature,
base64DecodedSubject);
if (signatureVerification.isSignatureValid()) {
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedSubject = cipher.doFinal(base64DecodedSubject);
decryptedPushMessage = LoganSquare.parse(new String(decryptedSubject),
DecryptedPushMessage.class);
boolean hasChatSupport = signatureVerification.getUserEntity().hasSpreedCapabilityWithName
("chat-v2");
boolean isInTheSameRoomAsNotification = (ApplicationWideCurrentRoomHolder.getInstance().
getCurrentRoomId().equals(decryptedPushMessage.getId()) ||
ApplicationWideCurrentRoomHolder.getInstance()
.getCurrentRoomToken().equals(decryptedPushMessage.getId())) &&
signatureVerification.getUserEntity().equals(ApplicationWideCurrentRoomHolder
.getInstance().getUserInRoom());
boolean shouldShowNotification = decryptedPushMessage.getApp().equals("spreed") &&
!decryptedPushMessage.getType().equals("room") &&
(!isInTheSameRoomAsNotification ||
!ApplicationWideStateHolder.getInstance().isInForeground() ||
decryptedPushMessage.getType().equals("call"));
if (shouldShowNotification) {
Intent intent;
Bundle bundle = new Bundle();
boolean startACall = decryptedPushMessage.getType().equals("call") || !hasChatSupport;
if (startACall) {
intent = new Intent(context, MagicCallActivity.class);
} else {
intent = new Intent(context, MainActivity.class);
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (!signatureVerification.getUserEntity().hasSpreedCapabilityWithName
("no-ping")) {
bundle.putString(BundleKeys.KEY_ROOM_ID, decryptedPushMessage.getId());
} else {
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, decryptedPushMessage.getId());
}
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(signatureVerification
.getUserEntity()));
bundle.putBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL,
startACall);
intent.putExtras(bundle);
switch (decryptedPushMessage.getType()) {
case "call":
if (!bundle.containsKey(BundleKeys.KEY_ROOM_TOKEN)) {
context.startActivity(intent);
} else {
showNotificationForCallWithNoPing(intent);
}
break;
case "room":
// do absolutely nothing, we won't even come to this point
break;
case "chat":
if (decryptedPushMessage.getNotificationId() != Long.MIN_VALUE) {
showMessageNotificationWithObjectData(intent);
} else {
showNotification(intent);
}
break;
default:
break;
}
}
}
} catch (NoSuchAlgorithmException e1) {
Log.d(TAG, "No proper algorithm to decrypt the message " + e1.getLocalizedMessage());
} catch (NoSuchPaddingException e1) {
Log.d(TAG, "No proper padding to decrypt the message " + e1.getLocalizedMessage());
} catch (InvalidKeyException e1) {
Log.d(TAG, "Invalid private key " + e1.getLocalizedMessage());
}
} catch (Exception exception) {
Log.d(TAG, "Something went very wrong" + exception.getLocalizedMessage());
}
}
return Result.SUCCESS;
}
private void showNotificationForCallWithNoPing(Intent intent) {
UserEntity userEntity = signatureVerification.getUserEntity();
ncApi.getRoom(ApiUtils.getCredentials(userEntity.getUserId(),
@ -348,7 +235,7 @@ public class NotificationJob extends Job {
largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_call_black_24dp);
}
}
PendingIntent pendingIntent = PendingIntent.getActivity(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@ -462,4 +349,114 @@ public class NotificationJob extends Job {
}
}
}
@NonNull
@Override
public Result doWork() {
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
context = getApplicationContext();
Data data = getInputData();
String subject = data.getString(BundleKeys.KEY_NOTIFICATION_SUBJECT);
String signature = data.getString(BundleKeys.KEY_NOTIFICATION_SIGNATURE);
try {
byte[] base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT);
byte[] base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT);
PushUtils pushUtils = new PushUtils();
PrivateKey privateKey = (PrivateKey) pushUtils.readKeyFromFile(false);
try {
signatureVerification = pushUtils.verifySignature(base64DecodedSignature,
base64DecodedSubject);
if (signatureVerification.isSignatureValid()) {
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedSubject = cipher.doFinal(base64DecodedSubject);
decryptedPushMessage = LoganSquare.parse(new String(decryptedSubject),
DecryptedPushMessage.class);
boolean hasChatSupport = signatureVerification.getUserEntity().hasSpreedCapabilityWithName
("chat-v2");
boolean isInTheSameRoomAsNotification = (ApplicationWideCurrentRoomHolder.getInstance().
getCurrentRoomId().equals(decryptedPushMessage.getId()) ||
ApplicationWideCurrentRoomHolder.getInstance()
.getCurrentRoomToken().equals(decryptedPushMessage.getId())) &&
signatureVerification.getUserEntity().equals(ApplicationWideCurrentRoomHolder
.getInstance().getUserInRoom());
boolean shouldShowNotification = decryptedPushMessage.getApp().equals("spreed") &&
!decryptedPushMessage.getType().equals("room") &&
(!isInTheSameRoomAsNotification ||
!ApplicationWideStateHolder.getInstance().isInForeground() ||
decryptedPushMessage.getType().equals("call"));
if (shouldShowNotification) {
Intent intent;
Bundle bundle = new Bundle();
boolean startACall = decryptedPushMessage.getType().equals("call") || !hasChatSupport;
if (startACall) {
intent = new Intent(context, MagicCallActivity.class);
} else {
intent = new Intent(context, MainActivity.class);
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (!signatureVerification.getUserEntity().hasSpreedCapabilityWithName
("no-ping")) {
bundle.putString(BundleKeys.KEY_ROOM_ID, decryptedPushMessage.getId());
} else {
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, decryptedPushMessage.getId());
}
bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(signatureVerification
.getUserEntity()));
bundle.putBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL,
startACall);
intent.putExtras(bundle);
switch (decryptedPushMessage.getType()) {
case "call":
if (!bundle.containsKey(BundleKeys.KEY_ROOM_TOKEN)) {
context.startActivity(intent);
} else {
showNotificationForCallWithNoPing(intent);
}
break;
case "room":
// do absolutely nothing, we won't even come to this point
break;
case "chat":
if (decryptedPushMessage.getNotificationId() != Long.MIN_VALUE) {
showMessageNotificationWithObjectData(intent);
} else {
showNotification(intent);
}
break;
default:
break;
}
}
}
} catch (NoSuchAlgorithmException e1) {
Log.d(TAG, "No proper algorithm to decrypt the message " + e1.getLocalizedMessage());
} catch (NoSuchPaddingException e1) {
Log.d(TAG, "No proper padding to decrypt the message " + e1.getLocalizedMessage());
} catch (InvalidKeyException e1) {
Log.d(TAG, "Invalid private key " + e1.getLocalizedMessage());
}
} catch (Exception exception) {
Log.d(TAG, "Something went very wrong" + exception.getLocalizedMessage());
}
return Result.SUCCESS;
}
}

Просмотреть файл

@ -2,7 +2,7 @@
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,7 +27,7 @@ import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;
import com.nextcloud.talk.jobs.AccountRemovalJob;
import com.nextcloud.talk.jobs.CapabilitiesJob;
import com.nextcloud.talk.jobs.NotificationJob;
import com.nextcloud.talk.jobs.NotificationWorker;
import com.nextcloud.talk.jobs.PushRegistrationJob;
public class MagicJobCreator implements JobCreator {
@ -40,8 +40,8 @@ public class MagicJobCreator implements JobCreator {
return new PushRegistrationJob();
case AccountRemovalJob.TAG:
return new AccountRemovalJob();
case NotificationJob.TAG:
return new NotificationJob();
case NotificationWorker.TAG:
return new NotificationWorker();
case CapabilitiesJob.TAG:
return new CapabilitiesJob();
default:

Просмотреть файл

@ -0,0 +1,47 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:fillType="nonZero"
android:pathData="M12.729,5C11.044,5 9.833,6.38 9.833,7.702C9.833,9.054 9.93,10.019 10.605,11.08C10.822,11.36 11.074,11.418 11.281,11.659C11.411,12.142 11.513,12.625 11.378,13.107C10.957,13.255 10.557,13.428 10.152,13.59C9.66,13.326 9.09,13.107 8.598,12.914C8.53,12.644 8.579,12.444 8.646,12.19C8.762,12.07 8.868,12.016 8.994,11.901C9.351,11.466 9.37,10.733 9.37,10.212C9.37,9.44 8.675,8.861 7.922,8.861C7.082,8.861 6.474,9.555 6.474,10.212L6.455,10.212C6.455,10.887 6.503,11.37 6.841,11.901C6.938,12.045 7.075,12.07 7.179,12.19C7.244,12.431 7.296,12.673 7.227,12.914C6.61,13.129 6.027,13.397 5.49,13.686C5.085,13.976 5.265,13.862 5.007,14.796C4.888,15.279 6.262,15.501 7.247,15.578C7.198,15.843 7.131,16.196 6.938,16.871C6.629,18.078 11.139,18.512 12.729,18.512C15.074,18.512 18.822,18.072 18.501,16.871C17.999,14.999 18.3,15.221 17.555,14.651C16.503,14.02 15.188,13.525 14.08,13.107C13.935,12.57 14.041,12.171 14.177,11.659C14.403,11.418 14.659,11.312 14.872,11.08C15.537,10.227 15.624,8.741 15.624,7.702C15.624,6.172 14.244,5 12.729,5L12.729,5Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>