diff --git a/app/build.gradle b/app/build.gradle
index 539b1123d6..fa94805a21 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -283,6 +283,8 @@ dependencies {
def work_version = "2.7.0-alpha05"
def exif_version = "1.3.3"
def biometric_version = "1.2.0-alpha03"
+ def tile_wear_version = "1.0.0-alpha10"
+ def guava_version = "30.1.1-android"
def billingclient_version = "3.0.3"
def javamail_version = "1.6.7"
def jsoup_version = "1.13.1"
@@ -398,6 +400,13 @@ dependencies {
// https://developer.android.com/jetpack/androidx/releases/biometric
implementation "androidx.biometric:biometric:$biometric_version"
+ // https://mvnrepository.com/artifact/androidx.wear.tiles/tiles
+ // https://developer.android.com/training/articles/wear-tiles
+ // https://github.com/google/guava
+ implementation "androidx.wear.tiles:tiles:$tile_wear_version"
+ debugImplementation "androidx.wear.tiles:tiles-renderer:$tile_wear_version"
+ implementation "com.google.guava:guava:$guava_version"
+
// https://developer.android.com/google/play/billing/billing_library_releases_notes
// https://android-developers.googleblog.com/2020/06/meet-google-play-billing-library.html
githubImplementation "com.android.billingclient:billing:$billingclient_version"
diff --git a/app/src/amazon/AndroidManifest.xml b/app/src/amazon/AndroidManifest.xml
index de7d89a6c2..e8f3fc1039 100644
--- a/app/src/amazon/AndroidManifest.xml
+++ b/app/src/amazon/AndroidManifest.xml
@@ -383,6 +383,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/debug/java/eu/faircode/email/ActivityTileWear.java b/app/src/debug/java/eu/faircode/email/ActivityTileWear.java
new file mode 100644
index 0000000000..5e4fb1849e
--- /dev/null
+++ b/app/src/debug/java/eu/faircode/email/ActivityTileWear.java
@@ -0,0 +1,40 @@
+package eu.faircode.email;
+
+import android.content.ComponentName;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import androidx.activity.ComponentActivity;
+import androidx.annotation.Nullable;
+import androidx.wear.tiles.manager.TileUiClient;
+
+public class ActivityTileWear extends ComponentActivity {
+ private TileUiClient mTileUiClient;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ FrameLayout rootLayout = new FrameLayout(this);
+ FrameLayout.LayoutParams layoutparams =
+ new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ rootLayout.setLayoutParams(layoutparams);
+ rootLayout.setBackgroundColor(Color.BLACK);
+
+ setContentView(rootLayout);
+
+ mTileUiClient = new TileUiClient(this,
+ new ComponentName(this, ServiceTileWear.class), rootLayout);
+ mTileUiClient.connect();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mTileUiClient.close();
+ }
+}
diff --git a/app/src/fdroid/AndroidManifest.xml b/app/src/fdroid/AndroidManifest.xml
index d08b28453c..b769c6416c 100644
--- a/app/src/fdroid/AndroidManifest.xml
+++ b/app/src/fdroid/AndroidManifest.xml
@@ -380,6 +380,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
.
+
+ Copyright 2018-2021 by Marcel Bokhorst (M66B)
+*/
+
+import static androidx.wear.tiles.DimensionBuilders.dp;
+import static androidx.wear.tiles.DimensionBuilders.expand;
+import static androidx.wear.tiles.DimensionBuilders.wrap;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+import androidx.wear.tiles.LayoutElementBuilders;
+import androidx.wear.tiles.RequestBuilders;
+import androidx.wear.tiles.ResourceBuilders;
+import androidx.wear.tiles.TileBuilders;
+import androidx.wear.tiles.TileProviderService;
+import androidx.wear.tiles.TimelineBuilders;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.text.NumberFormat;
+import java.util.concurrent.Callable;
+
+public class ServiceTileWear extends TileProviderService {
+ private static final String RESOURCES_VERSION = "1";
+
+ private static final ListeningExecutorService executor =
+ MoreExecutors.listeningDecorator(Helper.getBackgroundExecutor(1, "wear"));
+
+ @NonNull
+ @Override
+ protected ListenableFuture onTileRequest(
+ @NonNull RequestBuilders.TileRequest requestParams) {
+
+ DB db = DB.getInstance(this);
+ NumberFormat NF = NumberFormat.getInstance();
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean unseen_ignored = prefs.getBoolean("unseen_ignored", false);
+
+ return executor.submit(new Callable() {
+ @Override
+ public TileBuilders.Tile call() throws Exception {
+ TupleMessageStats stats = db.message().getWidgetUnseen(null);
+
+ Integer unseen = (stats == null ? null : (unseen_ignored ? stats.notifying : stats.unseen));
+
+ LayoutElementBuilders.LayoutElement layout = LayoutElementBuilders.Row.builder()
+ .setWidth(wrap())
+ .setHeight(expand())
+ .setVerticalAlignment(LayoutElementBuilders.VERTICAL_ALIGN_CENTER)
+ .addContent(LayoutElementBuilders.Image.builder()
+ .setResourceId("mail")
+ .setWidth(dp(24f))
+ .setHeight(dp(24f)))
+ .addContent(LayoutElementBuilders.Spacer.builder()
+ .setWidth(dp(3f)))
+ .addContent(LayoutElementBuilders.Text.builder()
+ .setText(unseen == null ? "-" : NF.format(unseen)))
+ .build();
+
+ return TileBuilders.Tile.builder()
+ .setResourcesVersion(RESOURCES_VERSION)
+ .setTimeline(TimelineBuilders.Timeline.builder()
+ .addTimelineEntry(TimelineBuilders.TimelineEntry.builder().setLayout(
+ LayoutElementBuilders.Layout.builder().setRoot(layout))))
+ .build();
+ }
+ });
+ }
+
+ @NonNull
+ @Override
+ protected ListenableFuture onResourcesRequest(
+ @NonNull RequestBuilders.ResourcesRequest requestParams) {
+ return executor.submit(new Callable() {
+ @Override
+ public ResourceBuilders.Resources call() throws Exception {
+ return ResourceBuilders.Resources.builder()
+ .setVersion(RESOURCES_VERSION)
+ .addIdToImageMapping("mail",
+ ResourceBuilders.ImageResource.builder()
+ .setAndroidResourceByResId(ResourceBuilders.AndroidImageResourceByResId.builder()
+ .setResourceId(R.drawable.baseline_mail_24)
+ .build())
+ .build())
+ .build();
+ }
+ });
+ }
+
+ public static void update(Context context) {
+ TileProviderService.getUpdater(context).requestUpdate(ServiceTileWear.class);
+ }
+}
diff --git a/app/src/play/AndroidManifest.xml b/app/src/play/AndroidManifest.xml
index 203d0dd59c..e0812235f8 100644
--- a/app/src/play/AndroidManifest.xml
+++ b/app/src/play/AndroidManifest.xml
@@ -381,6 +381,20 @@
+
+
+
+
+
+
+
+