]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Mon, 25 Sep 2023 05:01:44 +0000 (13:01 +0800)
committerPo Lu <luangruo@yahoo.com>
Mon, 25 Sep 2023 05:01:44 +0000 (13:01 +0800)
* doc/lispref/os.texi (Desktop Notifications): Revise
documentation for android-notifications-notify to reflect
changes.

* java/org/gnu/emacs/EmacsDesktopNotification.java (display1):
Convert notification importance to a legacy priority between
Android 7.1 and 4.1.

* java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Remove
immutable bitmap constructor, as the underlying Android API
functions are erroneously implemented.

* src/android.c (android_init_emacs_pixmap): Cease searching for
deleted constructor.
(android_create_pixmap_from_bitmap_data): Create a pixmap, then
fill it with the contents of the bitmap, in lieu of employing
the aforementioned constructor.

* src/androidselect.c (Fandroid_notifications_notify): Revise
doc string.

doc/lispref/os.texi
java/org/gnu/emacs/EmacsDesktopNotification.java
java/org/gnu/emacs/EmacsPixmap.java
src/android.c
src/androidselect.c

index 3c704970cda045e0517536f434c03a56ef01c1d3..5400d492f0a22c0fc0c76391a9096c93df686998 100644 (file)
@@ -3220,15 +3220,25 @@ These have the same meaning as they do when used in calls to
 @code{notifications-notify}.
 
 @item :urgency @var{urgency}
+The set of values for @var{urgency} is the same as with
+@code{notifications-notify}, but the urgency applies to all
+notifications displayed with the defined @var{group}, except under
+Android 7.1 and earlier.
+
 @item :group @var{group}
-These two parameters are ignored under Android 7.1 and earlier
-versions of the system.  The set of values for @var{urgency} is the
-same as with @code{notifications-notify}, but the urgency applies to
-all notifications displayed with the defined @var{group}.
+@var{group} is a string that designates a category to which the
+notification sent will belong.  This category is reproduced within the
+system's notification settings menus, but is ignored under Android 7.1
+and earlier.
 
 If @var{group} is nil or not present within @var{params}, it is
 replaced by the string @samp{"Desktop Notifications"}.
 
+Callers should provide one stable combination of @var{urgency} and
+@var{group} for each kind of notification they send, given that the
+system may elect to disregard @var{urgency} if it does not match that
+of any notification previously delivered to @var{group}.
+
 @item :icon @var{icon}
 This parameter controls the symbolic icon the notification will be
 displayed with.  Its value is a string designating an icon within the
index 121d8f481a2fb9636ad9bcd15b353244ebe7643f..56ed984d49759a7bc7e90d2a87aa59bd4e30cdff 100644 (file)
@@ -96,6 +96,7 @@ public final class EmacsDesktopNotification
     RemoteViews contentView;
     Intent intent;
     PendingIntent pending;
+    int priority;
 
     tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
     manager = (NotificationManager) tem;
@@ -116,11 +117,37 @@ public final class EmacsDesktopNotification
                        .build ());
       }
     else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
-      notification = (new Notification.Builder (context)
-                     .setContentTitle (title)
-                     .setContentText (content)
-                     .setSmallIcon (icon)
-                     .build ());
+      {
+       /* Android 7.1 and earlier don't segregate notifications into
+          distinct categories, but permit an importance to be
+          assigned to each individual notification.  */
+
+       switch (importance)
+         {
+         case 2: /* IMPORTANCE_LOW */
+         default:
+           priority = Notification.PRIORITY_LOW;
+           break;
+
+         case 3: /* IMPORTANCE_DEFAULT */
+           priority = Notification.PRIORITY_DEFAULT;
+           break;
+
+         case 4: /* IMPORTANCE_HIGH */
+           priority = Notification.PRIORITY_HIGH;
+           break;
+         }
+       
+       notification = (new Notification.Builder (context)
+                       .setContentTitle (title)
+                       .setContentText (content)
+                       .setSmallIcon (icon)
+                       .setPriority (priority)
+                       .build ());
+
+       if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN)
+         notification.priority = priority;
+      }
     else
       {
        notification = new Notification ();
index e02699ecba7f068cf5ba012a48f3bb07e37dc91e..fa6e61c15a52e4d71fcaf2841af407a8bd446000 100644 (file)
@@ -50,39 +50,6 @@ public final class EmacsPixmap extends EmacsHandleObject
      changed.  */
   private long gcClipRectID;
 
-  public
-  EmacsPixmap (short handle, int colors[], int width,
-              int height, int depth)
-  {
-    super (handle);
-
-    if (depth != 1 && depth != 24)
-      throw new IllegalArgumentException ("Invalid depth specified"
-                                         + " for pixmap: " + depth);
-
-    switch (depth)
-      {
-      case 1:
-       bitmap = Bitmap.createBitmap (colors, width, height,
-                                     Bitmap.Config.ALPHA_8);
-       break;
-
-      case 24:
-       bitmap = Bitmap.createBitmap (colors, width, height,
-                                     Bitmap.Config.ARGB_8888);
-       bitmap.setHasAlpha (false);
-       break;
-      }
-
-    this.width = width;
-    this.height = height;
-    this.depth = depth;
-
-    /* The immutable bitmap constructor is only leveraged to create
-       small fringe bitmaps.  */
-    this.needCollect = false;
-  }
-
   public
   EmacsPixmap (short handle, int width, int height, int depth)
   {
index 0996a84823d16ab637c38b56d8ae4f54f0d127d0..4df9d71b1b1dc3db84b2bb56827b9e1135fad2f1 100644 (file)
@@ -73,7 +73,6 @@ bool android_init_gui;
 struct android_emacs_pixmap
 {
   jclass class;
-  jmethodID constructor;
   jmethodID constructor_mutable;
 };
 
@@ -1649,7 +1648,6 @@ android_init_emacs_pixmap (void)
                                        name, signature);       \
   assert (pixmap_class.c_name);
 
-  FIND_METHOD (constructor, "<init>", "(S[IIII)V");
   FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
 
 #undef FIND_METHOD
@@ -3404,86 +3402,91 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
                                        unsigned long background,
                                        unsigned int depth)
 {
-  android_handle prev_max_handle;
-  jobject object;
-  jintArray colors;
   android_pixmap pixmap;
+  jobject object;
+  AndroidBitmapInfo info;
+  unsigned int *depth_24;
+  unsigned char *depth_8;
+  void *bitmap_data;
   unsigned int x, y;
-  jint *region;
+  unsigned int r, g, b;
 
-  USE_SAFE_ALLOCA;
+  /* Create a pixmap with the right dimensions and depth.  */
+  pixmap = android_create_pixmap (width, height, depth);
 
-  /* Create the color array holding the data.  */
-  colors = (*android_java_env)->NewIntArray (android_java_env,
-                                            width * height);
-  android_exception_check ();
+  /* Lock the bitmap data.  */
+  bitmap_data = android_lock_bitmap (pixmap, &info, &object);
+
+  /* Merely return if locking the bitmap fails.  */
+  if (!bitmap_data)
+    return pixmap;
 
-  SAFE_NALLOCA (region, sizeof *region, width);
+  eassert (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888
+          || info.format == ANDROID_BITMAP_FORMAT_A_8);
 
-  for (y = 0; y < height; ++y)
+  /* Begin copying each line.  */
+
+  switch (info.format)
     {
-      for (x = 0; x < width; ++x)
+    case ANDROID_BITMAP_FORMAT_RGBA_8888:
+
+      /* Swizzle the pixels into ABGR format.  Android uses Skia's
+        ``native color type'', which is ABGR.  This is despite the
+        format being named ``ARGB'', and more confusingly
+        `ANDROID_BITMAP_FORMAT_RGBA_8888' in bitmap.h.  */
+
+      r = background & 0x00ff0000;
+      g = background & 0x0000ff00;
+      b = background & 0x000000ff;
+      background = (r >> 16) | g | (b << 16) | 0xff000000;
+      r = foreground & 0x00ff0000;
+      g = foreground & 0x0000ff00;
+      b = foreground & 0x000000ff;
+      foreground = (r >> 16) | g | (b << 16) | 0xff000000;
+
+      for (y = 0; y < height; ++y)
        {
-         if (depth == 24)
-           {
-             /* The alpha channels must be set, or otherwise, the
-                pixmap will be created entirely transparent.  */
+         depth_24 = (void *) ((char *) bitmap_data + y * info.stride);
 
-             if (data[x / 8] & (1 << (x % 8)))
-               region[x] = foreground | 0xff000000;
-             else
-               region[x] = background | 0xff000000;
-           }
-         else
-           {
-             if (data[x / 8] & (1 << (x % 8)))
-               region[x] = foreground;
-             else
-               region[x] = background;
-           }
+         for (x = 0; x < width; ++x)
+           depth_24[x] = ((data[x / 8] & (1 << (x % 8)))
+                          ? foreground : background);
+
+         data += (width + 7) / 8;
        }
 
-      (*android_java_env)->SetIntArrayRegion (android_java_env,
-                                             colors,
-                                             width * y, width,
-                                             region);
-      data += width / 8;
-    }
+      break;
 
-  /* First, allocate the pixmap handle.  */
-  prev_max_handle = max_handle;
-  pixmap = android_alloc_id ();
+    case ANDROID_BITMAP_FORMAT_A_8:
 
-  if (!pixmap)
-    {
-      ANDROID_DELETE_LOCAL_REF ((jobject) colors);
-      error ("Out of pixmap handles!");
-    }
+      /* 8-bit pixmaps are created, but in spite of that they are
+        employed only to represent bitmaps.  */
 
-  object = (*android_java_env)->NewObject (android_java_env,
-                                          pixmap_class.class,
-                                          pixmap_class.constructor,
-                                          (jshort) pixmap, colors,
-                                          (jint) width, (jint) height,
-                                          (jint) depth);
-  (*android_java_env)->ExceptionClear (android_java_env);
-  ANDROID_DELETE_LOCAL_REF ((jobject) colors);
+      foreground = (foreground ? 255 : 0);
+      background = (background ? 255 : 0);
 
-  if (!object)
-    {
-      max_handle = prev_max_handle;
-      memory_full (0);
+      for (y = 0; y < height; ++y)
+       {
+         depth_8 = (void *) ((char *) bitmap_data + y * info.stride);
+
+         for (x = 0; x < width; ++x)
+           depth_8[x] = ((data[x / 8] & (1 << (x % 8)))
+                         ? foreground : background);
+
+         data += (width + 7) / 8;
+       }
+
+      break;
+
+    default:
+      emacs_abort ();
     }
 
-  android_handles[pixmap].type = ANDROID_HANDLE_PIXMAP;
-  android_handles[pixmap].handle
-    = (*android_java_env)->NewGlobalRef (android_java_env, object);
+  /* Unlock the bitmap itself.  */
+  AndroidBitmap_unlockPixels (android_java_env, object);
   ANDROID_DELETE_LOCAL_REF (object);
 
-  if (!android_handles[pixmap].handle)
-    memory_full (0);
-
-  SAFE_FREE ();
+  /* Return the pixmap.  */
   return pixmap;
 }
 
index 5735eda2dd5661cb6f0ec21e593bb2b1835d826e..cf2265d4cf4c8cec55411df900ad983367346df6 100644 (file)
@@ -660,12 +660,18 @@ keywords is understood:
   :icon         The name of a drawable resource to display as the
                 notification's icon.
 
-The notification group and urgency are ignored on Android 7.1 and
-earlier versions of Android.  Outside such older systems, it
-identifies a category that will be displayed in the system Settings
-menu.  The urgency provided always extends to affect all notifications
-displayed within that category.  If the group is not provided, it
-defaults to the string "Desktop Notifications".
+The notification group is ignored on Android 7.1 and earlier versions
+of Android.  Outside such older systems, it identifies a category that
+will be displayed in the system Settings menu, and the urgency
+provided always extends to affect all notifications displayed within
+that category.  If the group is not provided, it defaults to the
+string "Desktop Notifications".
+
+Each caller should strive to provide one unchanging combination of
+notification group and urgency for each kind of notification it sends,
+inasmuch as the system may, subject to user configuration, disregard
+the urgency specified within a notification, should it not be the
+first notification sent to its notification group.
 
 The provided icon should be the name of a "drawable resource" present
 within the "android.R.drawable" class designating an icon with a