Easy import of stickers from signal

Stephen Paul Weber created

Change summary

src/cheogram/java/com/cheogram/android/DownloadDefaultStickers.java | 23 
src/main/AndroidManifest.xml                                        | 19 
src/main/java/eu/siacs/conversations/ui/UriHandlerActivity.java     | 51 
3 files changed, 91 insertions(+), 2 deletions(-)

Detailed changes

src/cheogram/java/com/cheogram/android/DownloadDefaultStickers.java 🔗

@@ -26,6 +26,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.util.HashSet;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.json.JSONArray;
@@ -55,6 +56,7 @@ public class DownloadDefaultStickers extends Service {
 	private NotificationManager notificationManager;
 	private File mStickerDir;
 	private OkHttpClient http = new OkHttpClient();
+	private HashSet<Uri> pendingPacks = new HashSet<Uri>();
 
 	@Override
 	public void onCreate() {
@@ -65,6 +67,9 @@ public class DownloadDefaultStickers extends Service {
 
 	@Override
 	public int onStartCommand(Intent intent, int flags, int startId) {
+		synchronized(pendingPacks) {
+			pendingPacks.add(intent.getData() == null ? Uri.parse("https://stickers.cheogram.com/index.json") : intent.getData());
+		}
 		if (RUNNING.compareAndSet(false, true)) {
 			new Thread(() -> {
 				try {
@@ -124,13 +129,22 @@ public class DownloadDefaultStickers extends Service {
 	}
 
 	private void download() throws Exception {
+		Uri jsonUri;
+		synchronized(pendingPacks) {
+			if (pendingPacks.iterator().hasNext()) {
+				jsonUri = pendingPacks.iterator().next();
+			} else {
+				return;
+			}
+		}
+
 		NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext(), "backup");
-		mBuilder.setContentTitle("Downloading Default Stickers")
+		mBuilder.setContentTitle("Downloading Stickers")
 				.setSmallIcon(R.drawable.ic_archive_white_24dp)
 				.setProgress(1, 0, false);
 		startForeground(NOTIFICATION_ID, mBuilder.build());
 
-		Response r = http.newCall(new Request.Builder().url("https://stickers.cheogram.com/index.json").build()).execute();
+		Response r = http.newCall(new Request.Builder().url(jsonUri.toString()).build()).execute();
 		JSONArray stickers = new JSONArray(r.body().string());
 
 		final Progress progress = new Progress(mBuilder, 1, 0);
@@ -140,6 +154,11 @@ public class DownloadDefaultStickers extends Service {
 			final int percentage = i * 100 / stickers.length();
 			notificationManager.notify(NOTIFICATION_ID, progress.build(percentage));
 		}
+
+		synchronized(pendingPacks) {
+			pendingPacks.remove(jsonUri);
+		}
+		download();
 	}
 
 	private File stickerDir() {

src/main/AndroidManifest.xml 🔗

@@ -166,6 +166,25 @@
 
                 <data android:scheme="xmpp" />
             </intent-filter>
+            <intent-filter android:label="Import Sticker Pack">
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data android:scheme="sgnl" />
+                <data android:pathPrefix="/addstickers/" />
+            </intent-filter>
+            <intent-filter android:label="Import Sticker Pack">
+                <action android:name="android.intent.action.VIEW" />
+
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+
+                <data android:scheme="https" />
+                <data android:host="signal.art" />
+                <data android:pathPrefix="/addstickers/" />
+            </intent-filter>
             <intent-filter android:autoVerify="true">
                 <action android:name="android.intent.action.VIEW" />
 

src/main/java/eu/siacs/conversations/ui/UriHandlerActivity.java 🔗

@@ -18,6 +18,8 @@ import androidx.databinding.DataBindingUtil;
 
 import com.google.common.base.Strings;
 
+import com.cheogram.android.DownloadDefaultStickers;
+
 import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
@@ -52,6 +54,7 @@ public class UriHandlerActivity extends AppCompatActivity {
     private static final Pattern LINK_HEADER_PATTERN = Pattern.compile("<(.*?)>");
     private ActivityUriHandlerBinding binding;
     private Call call;
+    private Uri stickers;
 
     public static void scan(final Activity activity) {
         scan(activity, false);
@@ -109,6 +112,26 @@ public class UriHandlerActivity extends AppCompatActivity {
         handleIntent(intent);
     }
 
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        if (grantResults.length > 0) {
+            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                downloadStickers();
+            }
+        }
+        finish();
+    }
+
+    private void downloadStickers() {
+        Intent intent = new Intent(this, DownloadDefaultStickers.class);
+        intent.setData(stickers);
+        ContextCompat.startForegroundService(this, intent);
+        Toast.makeText(this, "Sticker download started", Toast.LENGTH_SHORT).show();
+        finish();
+    }
+
     private boolean handleUri(final Uri uri) {
         return handleUri(uri, false);
     }
@@ -118,6 +141,21 @@ public class UriHandlerActivity extends AppCompatActivity {
         final XmppUri xmppUri = new XmppUri(uri);
         final List<Jid> accounts = DatabaseBackend.getInstance(this).getAccountJids(true);
 
+        if (uri.getScheme().equals("sgnl")) {
+            stickers = Uri.parse("https://stickers.cheogram.com/signal/" + uri.getQueryParameter("pack_id") + "," + uri.getQueryParameter("pack_key"));
+            if (hasStoragePermission(1)) downloadStickers();
+            return false;
+        }
+
+        if (uri.getScheme().equals("https") && uri.getHost().equals("signal.art")) {
+            android.net.UrlQuerySanitizer q = new android.net.UrlQuerySanitizer();
+            q.setAllowUnregisteredParamaters(true);
+            q.parseQuery(uri.getFragment());
+            stickers = Uri.parse("https://stickers.cheogram.com/signal/" + q.getValue("pack_id") + "," + q.getValue("pack_key"));
+            if (hasStoragePermission(1)) downloadStickers();
+            return false;
+        }
+
         if (SignupUtils.isSupportTokenRegistry() && xmppUri.isValidJid()) {
             final String preAuth = xmppUri.getParameter(XmppUri.PARAMETER_PRE_AUTH);
             final Jid jid = xmppUri.getJid();
@@ -329,4 +367,17 @@ public class UriHandlerActivity extends AppCompatActivity {
         final String trimmed = Strings.nullToEmpty(input).trim();
         return trimmed.charAt(0) == '{' && trimmed.charAt(trimmed.length() - 1) == '}';
     }
+
+    protected boolean hasStoragePermission(int requestCode) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
+                return false;
+            } else {
+                return true;
+            }
+        } else {
+            return true;
+        }
+    }
 }