diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4f95aa544..7fbe05f5b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -66,5 +66,10 @@
android:configChanges="orientation|screenSize"
android:launchMode="singleTask"/>
+
+
+
+
+
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
index a78d7356f..2bcd45904 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java
@@ -102,7 +102,6 @@ import org.webrtc.RendererCommon;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
-import org.webrtc.VideoRenderer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
@@ -165,6 +164,7 @@ public class CallController extends BaseController {
FlipView cameraControlButton;
@BindView(R.id.call_control_switch_camera)
FlipView cameraSwitchButton;
+
@BindView(R.id.connectingRelativeLayoutView)
RelativeLayout connectingView;
@@ -182,23 +182,22 @@ public class CallController extends BaseController {
@Inject
Cache cache;
- PeerConnectionFactory peerConnectionFactory;
- MediaConstraints audioConstraints;
- MediaConstraints videoConstraints;
- MediaConstraints sdpConstraints;
- MagicAudioManager audioManager;
- VideoSource videoSource;
- VideoTrack localVideoTrack;
- AudioSource audioSource;
- AudioTrack localAudioTrack;
- VideoCapturer videoCapturer;
- VideoRenderer localRenderer;
- EglBase rootEglBase;
- boolean leavingCall = false;
- boolean inCall = false;
- Disposable signalingDisposable;
- Disposable pingDisposable;
- List iceServers;
+ private PeerConnectionFactory peerConnectionFactory;
+ private MediaConstraints audioConstraints;
+ private MediaConstraints videoConstraints;
+ private MediaConstraints sdpConstraints;
+ private MagicAudioManager audioManager;
+ private VideoSource videoSource;
+ private VideoTrack localVideoTrack;
+ private AudioSource audioSource;
+ private AudioTrack localAudioTrack;
+ private VideoCapturer videoCapturer;
+ private EglBase rootEglBase;
+ private boolean leavingCall = false;
+ private boolean inCall = false;
+ private Disposable signalingDisposable;
+ private Disposable pingDisposable;
+ private List iceServers;
private CameraEnumerator cameraEnumerator;
private String roomToken;
private UserEntity userEntity;
@@ -252,8 +251,7 @@ public class CallController extends BaseController {
baseUrl = userEntity.getBaseUrl();
}
- isFromNotification = args.containsKey(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL) && TextUtils.isEmpty
- (roomToken);
+ isFromNotification = TextUtils.isEmpty(roomToken);
}
@Override
@@ -636,12 +634,14 @@ public class CallController extends BaseController {
R.string.nc_microphone_permission_permanently_denied,
R.string.nc_permissions_settings, (AppCompatActivity) getActivity());
} else {
- EffortlessPermissions.requestPermissions(getActivity(), R.string.nc_permissions_audio,
- R.string.nc_proceed, R.string.nc_empty, 100, PERMISSIONS_MICROPHONE);
+ if (getActivity() != null) {
+ EffortlessPermissions.requestPermissions(getActivity(), R.string.nc_permissions_audio,
+ R.string.nc_proceed, R.string.nc_empty, 100, PERMISSIONS_MICROPHONE);
+ }
}
}
- @OnClick(R.id.call_control_hangup)
+ @OnClick(R.id.callControlHangupView)
public void onHangupClick() {
if (inCall) {
hangup(false);
@@ -652,7 +652,7 @@ public class CallController extends BaseController {
@OnClick(R.id.call_control_camera)
public void onCameraClick() {
- if (EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA)) {
+ if (getActivity() != null && EffortlessPermissions.hasPermissions(getActivity(), PERMISSIONS_CAMERA)) {
videoOn = !videoOn;
if (videoOn) {
@@ -824,7 +824,7 @@ public class CallController extends BaseController {
super.onDestroy();
}
- public void startPullingSignalingMessages() {
+ private void startPullingSignalingMessages() {
leavingCall = false;
ncApi.getSignalingSettings(credentials, ApiUtils.getUrlForSignalingSettings(baseUrl))
@@ -1055,6 +1055,7 @@ public class CallController extends BaseController {
@Override
public void onError(Throwable e) {
+ Log.d("MARIO", e.getLocalizedMessage());
dispose(signalingDisposable);
}
@@ -1396,7 +1397,7 @@ public class CallController extends BaseController {
}
private void removeMediaStream(String sessionId) {
- if (remoteRenderersLayout.getChildCount() > 0) {
+ if (remoteRenderersLayout != null && remoteRenderersLayout.getChildCount() > 0) {
RelativeLayout relativeLayout = remoteRenderersLayout.findViewWithTag(sessionId);
if (relativeLayout != null) {
SurfaceViewRenderer surfaceViewRenderer = relativeLayout.findViewById(R.id.surface_view);
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
index 13de6bcd5..66c372c76 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java
@@ -126,16 +126,16 @@ public class CallNotificationController extends BaseController {
@OnClick(R.id.callAnswerCameraView)
void answerWithCamera() {
originalBundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, false);
- setBackstackAndProceed();
+ proceedToCall();
}
@OnClick(R.id.callAnswerVoiceOnlyView)
void answerVoiceOnly() {
originalBundle.putBoolean(BundleKeys.KEY_CALL_VOICE_ONLY, true);
- setBackstackAndProceed();
+ proceedToCall();
}
- private void setBackstackAndProceed() {
+ private void proceedToCall() {
originalBundle.putString(BundleKeys.KEY_ROOM_TOKEN, currentRoom.getToken());
getRouter().setRoot(RouterTransaction.with(new CallController(originalBundle))
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalJob.java b/app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalJob.java
index f4d287218..32456ad92 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalJob.java
+++ b/app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalJob.java
@@ -21,12 +21,16 @@
package com.nextcloud.talk.jobs;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import com.bluelinelabs.logansquare.LoganSquare;
import com.evernote.android.job.Job;
+import com.nextcloud.talk.R;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.models.database.UserEntity;
@@ -38,6 +42,7 @@ import com.nextcloud.talk.utils.database.user.UserUtils;
import java.io.IOException;
import java.net.CookieManager;
import java.util.HashMap;
+import java.util.zip.CRC32;
import javax.inject.Inject;
@@ -113,6 +118,21 @@ public class AccountRemovalJob extends Job {
@Override
public void onNext(Void aVoid) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ String groupName = String.format(getContext().getResources().getString(R.string
+ .nc_notification_channel), userEntity.getUserId(), userEntity.getBaseUrl());
+ CRC32 crc32 = new CRC32();
+ crc32.update(groupName.getBytes());
+ NotificationManager notificationManager =
+ (NotificationManager) getContext().getSystemService(Context
+ .NOTIFICATION_SERVICE);
+
+ if (notificationManager != null) {
+ notificationManager.deleteNotificationChannelGroup(Long
+ .toString(crc32.getValue()));
+ }
+ }
+
userUtils.deleteUser(userEntity.getId()).subscribe(new
CompletableObserver() {
@Override
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationJob.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationJob.java
index 96a1a8384..34186ab66 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationJob.java
+++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationJob.java
@@ -26,7 +26,10 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaPlayer;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
@@ -44,6 +47,7 @@ import com.nextcloud.talk.models.RingtoneSettings;
import com.nextcloud.talk.models.SignatureVerification;
import com.nextcloud.talk.models.json.push.DecryptedPushMessage;
import com.nextcloud.talk.utils.ApplicationWideCurrentRoomHolder;
+import com.nextcloud.talk.utils.NotificationUtils;
import com.nextcloud.talk.utils.PushUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
@@ -55,6 +59,8 @@ import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
+import java.util.Calendar;
+import java.util.zip.CRC32;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
@@ -110,10 +116,11 @@ public class NotificationJob extends Job {
.getInstance().getUserInRoom());
boolean shouldShowNotification = decryptedPushMessage.getApp().equals("spreed") &&
+ !decryptedPushMessage.getType().equals("room") &&
(!isInTheSameRoomAsNotification || decryptedPushMessage.getType().equals("call"));
if (shouldShowNotification) {
- int smallIcon;
+ int smallIcon = 0;
Bitmap largeIcon;
String category = "";
int priority = Notification.PRIORITY_HIGH;
@@ -152,8 +159,7 @@ public class NotificationJob extends Job {
getContext().startActivity(intent);
break;
case "room":
- smallIcon = R.drawable.ic_notifications_white_24dp;
- category = Notification.CATEGORY_CALL;
+ // do absolutely nothing, we won't even come to this point
break;
case "chat":
ringtonePreferencesString = appPreferences.getMessageRingtoneUri();
@@ -177,84 +183,70 @@ public class NotificationJob extends Job {
smallIcon = R.drawable.ic_logo;
}
- /*largeIcon = BitmapFactory.decodeResource(context.getResources(), smallIcon);
- CRC32 crc32 = new CRC32();
+ if (decryptedPushMessage.getType().equals("chat")) {
+ largeIcon = BitmapFactory.decodeResource(context.getResources(), smallIcon);
+ CRC32 crc32 = new CRC32();
- Notification.Builder notificationBuilder = new Notification.Builder(context)
- .setLargeIcon(largeIcon)
- .setSmallIcon(smallIcon)
- .setCategory(category)
- .setPriority(priority)
- .setWhen(Calendar.getInstance().getTimeInMillis())
- .setShowWhen(true)
- .setSubText(signatureVerification.getUserEntity().getDisplayName())
- .setContentTitle(decryptedPushMessage.getSubject())
- .setFullScreenIntent(pendingIntent, true)
- .setAutoCancel(true);
+ Notification.Builder notificationBuilder = new Notification.Builder(context)
+ .setLargeIcon(largeIcon)
+ .setSmallIcon(smallIcon)
+ .setCategory(category)
+ .setPriority(priority)
+ .setWhen(Calendar.getInstance().getTimeInMillis())
+ .setShowWhen(true)
+ .setSubText(signatureVerification.getUserEntity().getDisplayName())
+ .setContentTitle(decryptedPushMessage.getSubject())
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true);
- if (Build.VERSION.SDK_INT >= 23) {
- // This method should exist since API 21, but some phones don't have it
- // So as a safeguard, we don't use it until 23
- notificationBuilder.setColor(context.getResources().getColor(R.color.colorPrimary));
- }
+ if (Build.VERSION.SDK_INT >= 23) {
+ // This method should exist since API 21, but some phones don't have it
+ // So as a safeguard, we don't use it until 23
+ notificationBuilder.setColor(context.getResources().getColor(R.color.colorPrimary));
+ }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- String groupName = String.format(context.getResources().getString(R.string
- .nc_notification_channel), signatureVerification.getUserEntity()
- .getDisplayName(), signatureVerification.getUserEntity().getBaseUrl());
- crc32.update(groupName.getBytes());
+ String groupName = String.format(context.getResources().getString(R.string
+ .nc_notification_channel), signatureVerification.getUserEntity()
+ .getUserId(), signatureVerification.getUserEntity().getBaseUrl());
+ crc32.update(groupName.getBytes());
- NotificationUtils.createNotificationChannelGroup(notificationManager,
- Long.toString(crc32.getValue()),
- groupName);
+ NotificationUtils.createNotificationChannelGroup(notificationManager,
+ Long.toString(crc32.getValue()),
+ groupName);
- if (category.equals(Notification.CATEGORY_CALL)) {
NotificationUtils.createNotificationChannel(notificationManager,
- NotificationUtils.NOTIFICATION_CHANNEL_CALLS, context.getResources()
- .getString(R
- .string.nc_notification_channel_calls), context.getResources()
- .getString
- (R.string.nc_notification_channel_calls_description), true,
+ NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V2, context.getResources()
+ .getString(R.string.nc_notification_channel_messages), context.getResources()
+ .getString(R.string.nc_notification_channel_messages_description), true,
NotificationManager.IMPORTANCE_HIGH);
- notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_CALLS);
- } else {
- NotificationUtils.createNotificationChannel(notificationManager,
- NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES, context.getResources()
- .getString(R
- .string.nc_notification_channel_messages), context.getResources()
- .getString
- (R.string.nc_notification_channel_messages_description), true,
- NotificationManager.IMPORTANCE_DEFAULT);
-
- notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES);
+ notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V2);
+ notificationBuilder.setGroup(Long.toString(crc32.getValue()));
}
- notificationBuilder.setGroup(Long.toString(crc32.getValue()));
+ notificationBuilder.setContentIntent(pendingIntent);
+
+ String stringForCrc = decryptedPushMessage.getSubject() + " " + signatureVerification
+ .getUserEntity().getDisplayName() + " " + signatureVerification.getUserEntity
+ ().getBaseUrl() + System.currentTimeMillis();
+
+ crc32 = new CRC32();
+ crc32.update(stringForCrc.getBytes());
+
+ if (notificationManager != null) {
+ notificationManager.notify((int) crc32.getValue(), notificationBuilder.build());
+
+ if (soundUri != null) {
+ MediaPlayer mediaPlayer = MediaPlayer.create(context, soundUri);
+ mediaPlayer.start();
+ mediaPlayer.setOnCompletionListener(MediaPlayer::release);
+
+ }
+ }
}
-
- notificationBuilder.setContentIntent(pendingIntent);
-
- String stringForCrc = decryptedPushMessage.getSubject() + " " + signatureVerification
- .getUserEntity().getDisplayName() + " " + signatureVerification.getUserEntity
- ().getBaseUrl();
-
- crc32 = new CRC32();
- crc32.update(stringForCrc.getBytes());
-
- if (notificationManager != null) {
- notificationManager.notify((int) crc32.getValue(), notificationBuilder.build());
-
- if (soundUri != null) {
- MediaPlayer mediaPlayer = MediaPlayer.create(context, soundUri);
- mediaPlayer.start();
- mediaPlayer.setOnCompletionListener(MediaPlayer::release);
-
- }
- }*/
}
-
}
} catch (NoSuchAlgorithmException e1) {
Log.d(TAG, "No proper algorithm to decrypt the message " + e1.getLocalizedMessage());
diff --git a/app/src/main/java/com/nextcloud/talk/receivers/PackageReplacedReceiver.java b/app/src/main/java/com/nextcloud/talk/receivers/PackageReplacedReceiver.java
new file mode 100644
index 000000000..0aae5f14a
--- /dev/null
+++ b/app/src/main/java/com/nextcloud/talk/receivers/PackageReplacedReceiver.java
@@ -0,0 +1,58 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2018 Mario Danic
+ *
+ * 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 .
+ */
+
+package com.nextcloud.talk.receivers;
+
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+
+import com.nextcloud.talk.utils.NotificationUtils;
+
+public class PackageReplacedReceiver extends BroadcastReceiver {
+ private static final String TAG = "PackageReplacedReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent != null && intent.getAction() != null &&
+ intent.getAction().equals("android.intent.action.MY_PACKAGE_REPLACED")) {
+ try {
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ if (packageInfo.versionCode == 99 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationManager notificationManager =
+ (NotificationManager) context.getSystemService(Context
+ .NOTIFICATION_SERVICE);
+
+ if (notificationManager != null) {
+ notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS);
+ notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES);
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Failed to find package info");
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.java b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.java
index d60ade3ca..a8c736363 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.java
+++ b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.java
@@ -30,6 +30,8 @@ import android.os.Build;
public class NotificationUtils {
public static final String NOTIFICATION_CHANNEL_CALLS = "NOTIFICATION_CHANNEL_CALLS";
public static final String NOTIFICATION_CHANNEL_MESSAGES = "NOTIFICATION_CHANNEL_MESSAGES";
+ public static final String NOTIFICATION_CHANNEL_CALLS_V2 = "NOTIFICATION_CHANNEL_CALLS_V2";
+ public static final String NOTIFICATION_CHANNEL_MESSAGES_V2 = "NOTIFICATION_CHANNEL_MESSAGES_V2";
@TargetApi(Build.VERSION_CODES.O)
public static void createNotificationChannel(NotificationManager notificationManager,
diff --git a/app/src/main/res/layout/controller_call.xml b/app/src/main/res/layout/controller_call.xml
index 9c58dc482..d89c6c07b 100644
--- a/app/src/main/res/layout/controller_call.xml
+++ b/app/src/main/res/layout/controller_call.xml
@@ -132,7 +132,7 @@