mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-01 08:17:38 +00:00
Update Android port
* 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.
This commit is contained in:
parent
947409d408
commit
df5a9a78b5
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
{
|
||||
|
139
src/android.c
139
src/android.c
@ -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);
|
||||
|
||||
SAFE_NALLOCA (region, sizeof *region, width);
|
||||
/* Merely return if locking the bitmap fails. */
|
||||
if (!bitmap_data)
|
||||
return pixmap;
|
||||
|
||||
for (y = 0; y < height; ++y)
|
||||
eassert (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888
|
||||
|| info.format == ANDROID_BITMAP_FORMAT_A_8);
|
||||
|
||||
/* Begin copying each line. */
|
||||
|
||||
switch (info.format)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (depth == 24)
|
||||
{
|
||||
/* The alpha channels must be set, or otherwise, the
|
||||
pixmap will be created entirely transparent. */
|
||||
case ANDROID_BITMAP_FORMAT_RGBA_8888:
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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)
|
||||
{
|
||||
depth_24 = (void *) ((char *) bitmap_data + y * info.stride);
|
||||
|
||||
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;
|
||||
|
||||
case ANDROID_BITMAP_FORMAT_A_8:
|
||||
|
||||
/* 8-bit pixmaps are created, but in spite of that they are
|
||||
employed only to represent bitmaps. */
|
||||
|
||||
foreground = (foreground ? 255 : 0);
|
||||
background = (background ? 255 : 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 ();
|
||||
}
|
||||
|
||||
/* First, allocate the pixmap handle. */
|
||||
prev_max_handle = max_handle;
|
||||
pixmap = android_alloc_id ();
|
||||
|
||||
if (!pixmap)
|
||||
{
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) colors);
|
||||
error ("Out of pixmap handles!");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!object)
|
||||
{
|
||||
max_handle = prev_max_handle;
|
||||
memory_full (0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user