mirror of
https://github.com/masscollaborationlabs/emacs.git
synced 2025-07-06 04:09:37 +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
5 changed files with 129 additions and 116 deletions
|
@ -3220,15 +3220,25 @@ These have the same meaning as they do when used in calls to
|
||||||
@code{notifications-notify}.
|
@code{notifications-notify}.
|
||||||
|
|
||||||
@item :urgency @var{urgency}
|
@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}
|
@item :group @var{group}
|
||||||
These two parameters are ignored under Android 7.1 and earlier
|
@var{group} is a string that designates a category to which the
|
||||||
versions of the system. The set of values for @var{urgency} is the
|
notification sent will belong. This category is reproduced within the
|
||||||
same as with @code{notifications-notify}, but the urgency applies to
|
system's notification settings menus, but is ignored under Android 7.1
|
||||||
all notifications displayed with the defined @var{group}.
|
and earlier.
|
||||||
|
|
||||||
If @var{group} is nil or not present within @var{params}, it is
|
If @var{group} is nil or not present within @var{params}, it is
|
||||||
replaced by the string @samp{"Desktop Notifications"}.
|
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}
|
@item :icon @var{icon}
|
||||||
This parameter controls the symbolic icon the notification will be
|
This parameter controls the symbolic icon the notification will be
|
||||||
displayed with. Its value is a string designating an icon within the
|
displayed with. Its value is a string designating an icon within the
|
||||||
|
|
|
@ -96,6 +96,7 @@ public final class EmacsDesktopNotification
|
||||||
RemoteViews contentView;
|
RemoteViews contentView;
|
||||||
Intent intent;
|
Intent intent;
|
||||||
PendingIntent pending;
|
PendingIntent pending;
|
||||||
|
int priority;
|
||||||
|
|
||||||
tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
|
tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
|
||||||
manager = (NotificationManager) tem;
|
manager = (NotificationManager) tem;
|
||||||
|
@ -116,11 +117,37 @@ public final class EmacsDesktopNotification
|
||||||
.build ());
|
.build ());
|
||||||
}
|
}
|
||||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||||
notification = (new Notification.Builder (context)
|
{
|
||||||
.setContentTitle (title)
|
/* Android 7.1 and earlier don't segregate notifications into
|
||||||
.setContentText (content)
|
distinct categories, but permit an importance to be
|
||||||
.setSmallIcon (icon)
|
assigned to each individual notification. */
|
||||||
.build ());
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
notification = new Notification ();
|
notification = new Notification ();
|
||||||
|
|
|
@ -50,39 +50,6 @@ public final class EmacsPixmap extends EmacsHandleObject
|
||||||
changed. */
|
changed. */
|
||||||
private long gcClipRectID;
|
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
|
public
|
||||||
EmacsPixmap (short handle, int width, int height, int depth)
|
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
|
struct android_emacs_pixmap
|
||||||
{
|
{
|
||||||
jclass class;
|
jclass class;
|
||||||
jmethodID constructor;
|
|
||||||
jmethodID constructor_mutable;
|
jmethodID constructor_mutable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1649,7 +1648,6 @@ android_init_emacs_pixmap (void)
|
||||||
name, signature); \
|
name, signature); \
|
||||||
assert (pixmap_class.c_name);
|
assert (pixmap_class.c_name);
|
||||||
|
|
||||||
FIND_METHOD (constructor, "<init>", "(S[IIII)V");
|
|
||||||
FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
|
FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
|
||||||
|
|
||||||
#undef FIND_METHOD
|
#undef FIND_METHOD
|
||||||
|
@ -3404,86 +3402,91 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
|
||||||
unsigned long background,
|
unsigned long background,
|
||||||
unsigned int depth)
|
unsigned int depth)
|
||||||
{
|
{
|
||||||
android_handle prev_max_handle;
|
|
||||||
jobject object;
|
|
||||||
jintArray colors;
|
|
||||||
android_pixmap pixmap;
|
android_pixmap pixmap;
|
||||||
|
jobject object;
|
||||||
|
AndroidBitmapInfo info;
|
||||||
|
unsigned int *depth_24;
|
||||||
|
unsigned char *depth_8;
|
||||||
|
void *bitmap_data;
|
||||||
unsigned int x, y;
|
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. */
|
/* Lock the bitmap data. */
|
||||||
colors = (*android_java_env)->NewIntArray (android_java_env,
|
bitmap_data = android_lock_bitmap (pixmap, &info, &object);
|
||||||
width * height);
|
|
||||||
android_exception_check ();
|
|
||||||
|
|
||||||
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)
|
case ANDROID_BITMAP_FORMAT_RGBA_8888:
|
||||||
{
|
|
||||||
if (depth == 24)
|
|
||||||
{
|
|
||||||
/* The alpha channels must be set, or otherwise, the
|
|
||||||
pixmap will be created entirely transparent. */
|
|
||||||
|
|
||||||
if (data[x / 8] & (1 << (x % 8)))
|
/* Swizzle the pixels into ABGR format. Android uses Skia's
|
||||||
region[x] = foreground | 0xff000000;
|
``native color type'', which is ABGR. This is despite the
|
||||||
else
|
format being named ``ARGB'', and more confusingly
|
||||||
region[x] = background | 0xff000000;
|
`ANDROID_BITMAP_FORMAT_RGBA_8888' in bitmap.h. */
|
||||||
}
|
|
||||||
else
|
r = background & 0x00ff0000;
|
||||||
{
|
g = background & 0x0000ff00;
|
||||||
if (data[x / 8] & (1 << (x % 8)))
|
b = background & 0x000000ff;
|
||||||
region[x] = foreground;
|
background = (r >> 16) | g | (b << 16) | 0xff000000;
|
||||||
else
|
r = foreground & 0x00ff0000;
|
||||||
region[x] = background;
|
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,
|
break;
|
||||||
colors,
|
|
||||||
width * y, width,
|
case ANDROID_BITMAP_FORMAT_A_8:
|
||||||
region);
|
|
||||||
data += width / 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. */
|
/* Unlock the bitmap itself. */
|
||||||
prev_max_handle = max_handle;
|
AndroidBitmap_unlockPixels (android_java_env, object);
|
||||||
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);
|
|
||||||
ANDROID_DELETE_LOCAL_REF (object);
|
ANDROID_DELETE_LOCAL_REF (object);
|
||||||
|
|
||||||
if (!android_handles[pixmap].handle)
|
/* Return the pixmap. */
|
||||||
memory_full (0);
|
|
||||||
|
|
||||||
SAFE_FREE ();
|
|
||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -660,12 +660,18 @@ keywords is understood:
|
||||||
:icon The name of a drawable resource to display as the
|
:icon The name of a drawable resource to display as the
|
||||||
notification's icon.
|
notification's icon.
|
||||||
|
|
||||||
The notification group and urgency are ignored on Android 7.1 and
|
The notification group is ignored on Android 7.1 and earlier versions
|
||||||
earlier versions of Android. Outside such older systems, it
|
of Android. Outside such older systems, it identifies a category that
|
||||||
identifies a category that will be displayed in the system Settings
|
will be displayed in the system Settings menu, and the urgency
|
||||||
menu. The urgency provided always extends to affect all notifications
|
provided always extends to affect all notifications displayed within
|
||||||
displayed within that category. If the group is not provided, it
|
that category. If the group is not provided, it defaults to the
|
||||||
defaults to the string "Desktop Notifications".
|
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
|
The provided icon should be the name of a "drawable resource" present
|
||||||
within the "android.R.drawable" class designating an icon with a
|
within the "android.R.drawable" class designating an icon with a
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue