From 07de70b8a8feacc2f5ad2784486c08b0de552d77 Mon Sep 17 00:00:00 2001
From: James Brown <soylentblue@hotmail.co.uk>
Date: Tue, 23 Apr 2024 22:46:27 +1000
Subject: [PATCH] Fix notifications

---
 app/build.gradle                              |  8 +-
 app/src/main/AndroidManifest.xml              | 10 +--
 .../app/service/WalletConnectV2Service.java   | 89 ------------------
 .../com/alphawallet/app/ui/HomeActivity.java  | 25 +++---
 .../walletconnect/AWWalletConnectClient.java  | 90 ++++++++++++++++---
 5 files changed, 91 insertions(+), 131 deletions(-)
 delete mode 100644 app/src/main/java/com/alphawallet/app/service/WalletConnectV2Service.java

diff --git a/app/build.gradle b/app/build.gradle
index 1834955e15..c693aab79f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -52,7 +52,7 @@ android {
         applicationId "io.stormbird.wallet"
         minSdk 24
         targetSdk 34
-        versionCode 263
+        versionCode 266
         versionName "3.81"
 
         android.buildFeatures.buildConfig true
@@ -64,13 +64,13 @@ android {
         def DEFAULT_INFURA_API_KEY = "\"da3717f25f824cc1baa32d812386d93f\""
         def DEFAULT_OPENSEA_API_KEY = "\"...\""; //Put your OpenSea developer API key in here, otherwise you are reliant on the backup NFT fetch method (which usually works ok)
         def DEFAULT_POLYGONSCAN_API_KEY = "\"...\""; //Put your Polygonscan developer API key in here to get access to Polygon/Mumbai token discovery and transactions
-        def DEFUALT_WALLETCONNECT_PROJECT_ID = "\"40c6071febfd93f4fe485c232a8a4cd9\""
+        def DEFAULT_WALLETCONNECT_PROJECT_ID = "\"40c6071febfd93f4fe485c232a8a4cd9\""
         def DEFAULT_AURORA_API_KEY = "\"HFDDY5BNKGXBB82DE2G8S64C3C41B76PYI\""; //Put your Aurorascan.dev API key here - this one will rate limit as it is common
 
         buildConfigField 'int', 'DB_VERSION', '54'
 
         buildConfigField "String", XInfuraAPI, DEFAULT_INFURA_API_KEY
-        buildConfigField "String", "WALLETCONNECT_PROJECT_ID", DEFUALT_WALLETCONNECT_PROJECT_ID
+        buildConfigField "String", "WALLETCONNECT_PROJECT_ID", DEFAULT_WALLETCONNECT_PROJECT_ID
 
         buildConfigField "String", "NOTIFICATION_API_BASE_URL", NOTIFICATION_API_BASE_URL
 
@@ -92,7 +92,7 @@ android {
                 cFlags "-DOSKEY=" + DEFAULT_OPENSEA_API_KEY + ""
                 cFlags "-DPSKEY=" + DEFAULT_POLYGONSCAN_API_KEY + ""
                 cFlags "-DASKEY=" + DEFAULT_AURORA_API_KEY + ""
-                cFlags "-DWCKEY=" + DEFUALT_WALLETCONNECT_PROJECT_ID + ""
+                cFlags "-DWCKEY=" + DEFAULT_WALLETCONNECT_PROJECT_ID + ""
             }
             cmake {
                 cFlags "-Wno-dev"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5ff288e72b..bebca4a7ce 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
     <uses-permission android:name="android.permission.USE_BIOMETRIC" />
     <!-- Note: this permission is used to display the active WalletConnect Notification. This is a courtesy to the user to inform them a WalletConnect channel is active -->
     <!-- This is pegged to class WalletConnectV2Service which has no data connection, the data connection is only active when the AlphaWallet app is open -->
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>
 
     <uses-feature
@@ -121,14 +121,6 @@
                 android:name=".ui.SplashActivity"
                 android:theme="@style/AppTheme.NoActionBar.Splash" />
 
-        <!-- Note: this service is used to display the active WalletConnect Notification. This is a courtesy to the user to inform them a WalletConnect channel is active -->
-        <service
-                android:name=".service.WalletConnectV2Service"
-                android:enabled="true"
-                android:foregroundServiceType="specialUse"
-                android:exported="false">
-        </service>
-
         <service
                 android:name=".service.AlphaWalletFirebaseMessagingService"
                 android:exported="false">
diff --git a/app/src/main/java/com/alphawallet/app/service/WalletConnectV2Service.java b/app/src/main/java/com/alphawallet/app/service/WalletConnectV2Service.java
deleted file mode 100644
index 3672524652..0000000000
--- a/app/src/main/java/com/alphawallet/app/service/WalletConnectV2Service.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.alphawallet.app.service;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.ServiceInfo;
-import android.os.Build;
-import android.os.IBinder;
-
-import androidx.annotation.RequiresApi;
-import androidx.core.app.NotificationCompat;
-
-import com.alphawallet.app.R;
-import com.alphawallet.app.ui.WalletConnectNotificationActivity;
-
-import dagger.hilt.android.AndroidEntryPoint;
-
-@AndroidEntryPoint
-public class WalletConnectV2Service extends Service
-{
-    private static final String TAG = WalletConnectV2Service.class.getName();
-
-    final String CHANNEL_ID = "WalletConnectV2Service";
-    @Override
-    public IBinder onBind(Intent intent)
-    {
-        return null;
-    }
-
-    @RequiresApi(api = Build.VERSION_CODES.O)
-    @Override
-    public void onCreate()
-    {
-        super.onCreate();
-    }
-
-    private Notification createNotification()
-    {
-        Intent notificationIntent = new Intent(this, WalletConnectNotificationActivity.class);
-        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
-
-        return new NotificationCompat.Builder(this, CHANNEL_ID)
-                .setContentTitle(getString(R.string.notify_wallet_connect_title))
-                .setContentText(getString(R.string.notify_wallet_connect_content))
-                .setSmallIcon(R.drawable.ic_logo)
-                .setContentIntent(pendingIntent)
-                .build();
-    }
-
-    @RequiresApi(api = Build.VERSION_CODES.O)
-    private void createNotificationChannel()
-    {
-        CharSequence name = getString(R.string.notify_wallet_connect_title);
-        String description = getString(R.string.notify_wallet_connect_content);
-        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);
-        channel.setDescription(description);
-        NotificationManager notificationManager = getSystemService(NotificationManager.class);
-        notificationManager.createNotificationChannel(channel);
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
-        {
-            createNotificationChannel();
-        }
-        Notification notification = createNotification();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-        {
-            startForeground(startId, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
-        }
-        else
-        {
-            startForeground(startId, notification);
-        }
-
-        return START_STICKY;
-    }
-
-    @Override
-    public void onDestroy()
-    {
-        super.onDestroy();
-        stopForeground(true);
-    }
-}
diff --git a/app/src/main/java/com/alphawallet/app/ui/HomeActivity.java b/app/src/main/java/com/alphawallet/app/ui/HomeActivity.java
index eaf9e230fc..57d365aa22 100644
--- a/app/src/main/java/com/alphawallet/app/ui/HomeActivity.java
+++ b/app/src/main/java/com/alphawallet/app/ui/HomeActivity.java
@@ -931,27 +931,22 @@ private void hideDialog()
         }
     }
 
-    private boolean checkNotificationPermission(int permissionTag)
+    private void checkNotificationPermission(int permissionTag)
     {
-            if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
-                    != PackageManager.PERMISSION_GRANTED)
+        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
+                != PackageManager.PERMISSION_GRANTED)
+        {
+            String[] permissions;
+            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU)
             {
-                String[] permissions;
-                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU)
-                {
-                    permissions = new String[]{Manifest.permission.POST_NOTIFICATIONS};
-                }
-                else
-                {
-                    permissions = new String[]{Manifest.permission.ACCESS_NOTIFICATION_POLICY};
-                }
-                requestPermissions(permissions, permissionTag);
-                return false;
+                permissions = new String[]{Manifest.permission.POST_NOTIFICATIONS};
             }
             else
             {
-                return true;
+                permissions = new String[]{Manifest.permission.ACCESS_NOTIFICATION_POLICY};
             }
+            requestPermissions(permissions, permissionTag);
+        }
     }
 
     @Override
diff --git a/app/src/main/java/com/alphawallet/app/walletconnect/AWWalletConnectClient.java b/app/src/main/java/com/alphawallet/app/walletconnect/AWWalletConnectClient.java
index b41abcb580..7a60abc9f0 100644
--- a/app/src/main/java/com/alphawallet/app/walletconnect/AWWalletConnectClient.java
+++ b/app/src/main/java/com/alphawallet/app/walletconnect/AWWalletConnectClient.java
@@ -5,11 +5,16 @@
 import static com.walletconnect.web3.wallet.client.Wallet.Model;
 import static com.walletconnect.web3.wallet.client.Wallet.Params;
 
+import android.Manifest;
 import android.app.Activity;
 import android.app.Application;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -18,8 +23,12 @@
 
 import androidx.activity.result.ActivityResultLauncher;
 import androidx.annotation.NonNull;
-import androidx.core.content.ContextCompat;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.ActivityCompat;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
 import androidx.lifecycle.MutableLiveData;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 
 import com.alphawallet.app.App;
 import com.alphawallet.app.C;
@@ -34,7 +43,7 @@
 import com.alphawallet.app.repository.KeyProviderFactory;
 import com.alphawallet.app.repository.PreferenceRepositoryType;
 import com.alphawallet.app.service.GasService;
-import com.alphawallet.app.service.WalletConnectV2Service;
+import com.alphawallet.app.ui.WalletConnectNotificationActivity;
 import com.alphawallet.app.ui.WalletConnectSessionActivity;
 import com.alphawallet.app.ui.WalletConnectV2Activity;
 import com.alphawallet.app.ui.widget.entity.ActionSheetCallback;
@@ -86,6 +95,7 @@ public class AWWalletConnectClient implements Web3Wallet.WalletDelegate
     private boolean hasConnection;
     private Application application;
     private final PreferenceRepositoryType preferenceRepository;
+    private final int WC_NOTIFICATION_ID = 25964950;
 
     public AWWalletConnectClient(Context context, WalletConnectInteract walletConnectInteract, PreferenceRepositoryType preferenceRepository, GasService gasService)
     {
@@ -270,18 +280,13 @@ private void updateService(List<WalletConnectSessionItem> items)
     {
         try
         {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+            if (items.isEmpty())
             {
-                if (items.isEmpty())
-                {
-                    context.stopService(new Intent(context, WalletConnectV2Service.class));
-                    //now signal
-                }
-                else
-                {
-                    Intent serviceIntent = new Intent(context, WalletConnectV2Service.class);
-                    ContextCompat.startForegroundService(context, serviceIntent);
-                }
+                removeNotification();
+            }
+            else
+            {
+                displayNotification();
             }
         }
         catch (Exception e)
@@ -291,6 +296,63 @@ private void updateService(List<WalletConnectSessionItem> items)
         }
     }
 
+    public void displayNotification()
+    {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+        {
+            createNotificationChannel();
+        }
+        Notification notification = createNotification();
+
+        // Issue the notification if we have user permission
+        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
+        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED)
+        {
+            notificationManager.notify(WC_NOTIFICATION_ID, notification);
+        }
+        else
+        {
+            Intent intent = new Intent(C.REQUEST_NOTIFICATION_ACCESS);
+            LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+        }
+    }
+
+    final String CHANNEL_ID = "WalletConnectV2Service";
+    private Notification createNotification()
+    {
+        Intent notificationIntent = new Intent(context, WalletConnectNotificationActivity.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, WC_NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
+
+        return new NotificationCompat.Builder(context, CHANNEL_ID)
+                .setContentTitle(context.getString(R.string.notify_wallet_connect_title))
+                .setContentText(context.getString(R.string.notify_wallet_connect_content))
+                .setSmallIcon(R.drawable.ic_logo)
+                .setContentIntent(pendingIntent)
+                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+                .build();
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.O)
+    private void createNotificationChannel()
+    {
+        CharSequence name = context.getString(R.string.notify_wallet_connect_title);
+        String description = context.getString(R.string.notify_wallet_connect_content);
+        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);
+        channel.setDescription(description);
+        NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
+        notificationManager.createNotificationChannel(channel);
+    }
+
+    //remove notification
+    private void removeNotification()
+    {
+        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
+        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED)
+        {
+            notificationManager.cancel(WC_NOTIFICATION_ID);
+        }
+    }
+
 
     public void reject(Model.SessionProposal sessionProposal, WalletConnectV2Callback callback)
     {