]> git.eshelyaron.com Git - emacs.git/commitdiff
Android compatibility fixes
authorPo Lu <luangruo@yahoo.com>
Thu, 21 Mar 2024 06:23:40 +0000 (14:23 +0800)
committerEshel Yaron <me@eshelyaron.com>
Sun, 24 Mar 2024 14:14:10 +0000 (15:14 +0100)
* doc/emacs/android.texi (Android Windowing): Document
restrictions on number of windows under Android 4.4 and earlier.

* java/AndroidManifest.xml.in <EmacsActivity>
<EmacsOpenActivity, EmacsMultitaskActivity>: Assign each class
of activity a unique task affinity.

* java/org/gnu/emacs/EmacsDesktopNotification.java (display1):
Remove redundant priority assignment.

* java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Handle
file URIs when processing attachments from a mailto URI, and
check for KitKat before opening content ones.

* java/org/gnu/emacs/EmacsWindow.java <pointerMap>
(figureChange): Replace coordinate HashMap with a SparseArray.

* java/org/gnu/emacs/EmacsWindowAttachmentManager.java
(registerWindow): Don't specify FLAG_ACTIVITY_NEW_DOCUMENT on
systems where it is absent.

(cherry picked from commit ad0492c5a97aaad7f784f7834772400d9af96b69)

doc/emacs/android.texi
java/AndroidManifest.xml.in
java/org/gnu/emacs/EmacsDesktopNotification.java
java/org/gnu/emacs/EmacsOpenActivity.java
java/org/gnu/emacs/EmacsWindow.java
java/org/gnu/emacs/EmacsWindowAttachmentManager.java

index 56bfa2591f64bc58e05f0f78e4da957943c31f64..b367515cb353717d27797838d5a34adca82352f7 100644 (file)
@@ -864,6 +864,12 @@ behalf of a specific frame, Emacs deletes the frame displayed within
 that window.
 @end itemize
 
+  When the system predates Android 5.0, the window manager will not
+accept more than one user-created Emacs window.  If frame creation gives
+rise to windows in excess of this limit, the window manager will
+arbitrarily select one of their number to display, with the rest
+remaining invisible until that window is destroyed with its frame.
+
 @cindex windowing limitations, android
 @cindex frame parameters, android
 Emacs only supports a limited subset of GUI features on Android; the
index 4d23c7527472d21f1367da0877cdb7bb20f0fcda..563914fb02c322a68917822d3db78acd8abfcc13 100644 (file)
@@ -218,6 +218,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
 
     <activity android:name="org.gnu.emacs.EmacsActivity"
              android:launchMode="singleInstance"
+             android:taskAffinity="emacs.primary_frame"
              android:windowSoftInputMode="adjustResize"
              android:exported="true"
              android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale">
@@ -229,7 +230,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
     </activity>
 
     <activity android:name="org.gnu.emacs.EmacsOpenActivity"
-             android:taskAffinity="open.dialog"
+             android:taskAffinity="emacs.open_dialog"
              android:excludeFromRecents="true"
              android:exported="true">
 
@@ -273,6 +274,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>. -->
     </activity>
 
     <activity android:name="org.gnu.emacs.EmacsMultitaskActivity"
+             android:taskAffinity="emacs.secondary_frame"
              android:windowSoftInputMode="adjustResize"
              android:exported="true"
              android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"/>
index c80aa21b4fec378c21e415be8d7f0f8cff6d6e10..72569631a8c0889dfd1c6e6498d9c858870ca4f8 100644 (file)
@@ -208,22 +208,6 @@ public final class EmacsDesktopNotification
           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;
-         }
-
        builder = new Notification.Builder (context);
        builder.setContentTitle (title);
        builder.setContentText (content);
@@ -231,15 +215,28 @@ public final class EmacsDesktopNotification
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
          {
+           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;
+             }
+
            builder.setPriority (priority);
            insertActions (context, builder);
            notification = builder.build ();
          }
        else
          notification = builder.getNotification ();
-
-       if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN)
-         notification.priority = priority;
       }
     else
       {
index 2cdfa2ec776b11b5c5f8f48e4d5e1bb9657eee86..327a53bc417bf668b17eaed0b00f79c7579ab3e3 100644 (file)
@@ -535,7 +535,9 @@ public final class EmacsOpenActivity extends Activity
                  uri = intent.getParcelableExtra (Intent.EXTRA_STREAM);
 
                if ((scheme = uri.getScheme ()) != null
-                   && scheme.equals ("content"))
+                   && scheme.equals ("content")
+                   && (Build.VERSION.SDK_INT
+                       >= Build.VERSION_CODES.KITKAT))
                  {
                    tem1 = EmacsService.buildContentName (uri, resolver);
                    attachmentString = ("'(\"" + (tem1.replace ("\\", "\\\\")
@@ -543,6 +545,14 @@ public final class EmacsOpenActivity extends Activity
                                                  .replace ("$", "\\$"))
                                        + "\")");
                  }
+               else if (scheme != null && scheme.equals ("file"))
+                 {
+                   tem1 = uri.getPath ();
+                   attachmentString = ("'(\"" + (tem1.replace ("\\", "\\\\")
+                                                 .replace ("\"", "\\\"")
+                                                 .replace ("$", "\\$"))
+                                       + "\")");
+                 }
              }
            else
              {
@@ -567,7 +577,9 @@ public final class EmacsOpenActivity extends Activity
 
                        if (uri != null
                            && (scheme = uri.getScheme ()) != null
-                           && scheme.equals ("content"))
+                           && scheme.equals ("content")
+                           && (Build.VERSION.SDK_INT
+                               >= Build.VERSION_CODES.KITKAT))
                          {
                            tem1
                              = EmacsService.buildContentName (uri, resolver);
@@ -577,6 +589,16 @@ public final class EmacsOpenActivity extends Activity
                                            .replace ("$", "\\$"));
                            builder.append ("\"");
                          }
+                       else if (scheme != null
+                                && scheme.equals ("file"))
+                         {
+                           tem1 = uri.getPath ();
+                           builder.append ("\"");
+                           builder.append (tem1.replace ("\\", "\\\\")
+                                           .replace ("\"", "\\\"")
+                                           .replace ("$", "\\$"));
+                           builder.append ("\"");
+                         }
                      }
 
                    builder.append (")");
@@ -604,7 +626,13 @@ public final class EmacsOpenActivity extends Activity
          {
            fileName = null;
 
-           if (scheme.equals ("content"))
+           if (scheme.equals ("content")
+               /* Retrieving the native file descriptor of a
+                  ParcelFileDescriptor requires Honeycomb, and
+                  proceeding without this capability is pointless on
+                  systems before KitKat, since Emacs doesn't support
+                  opening content files on those.  */
+               && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
              {
                /* This is one of the annoying Android ``content''
                   URIs.  Most of the time, there is actually an
index d81d4106170936341a9afdd78a8f309ad7ed2fbd..06257a69dc5922e4ecee569e5352db1deb7ef86e 100644 (file)
@@ -23,7 +23,6 @@ import java.lang.IllegalStateException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -50,6 +49,7 @@ import android.view.View;
 import android.view.ViewManager;
 import android.view.WindowManager;
 
+import android.util.SparseArray;
 import android.util.Log;
 
 import android.os.Build;
@@ -109,7 +109,7 @@ public final class EmacsWindow extends EmacsHandleObject
 
   /* Map between pointer identifiers and last known position.  Used to
      compute which pointer changed upon a touch event.  */
-  private HashMap<Integer, Coordinate> pointerMap;
+  private SparseArray<Coordinate> pointerMap;
 
   /* The window consumer currently attached, if it exists.  */
   private EmacsWindowAttachmentManager.WindowConsumer attached;
@@ -166,7 +166,7 @@ public final class EmacsWindow extends EmacsHandleObject
     super (handle);
 
     rect = new Rect (x, y, x + width, y + height);
-    pointerMap = new HashMap<Integer, Coordinate> ();
+    pointerMap = new SparseArray<Coordinate> ();
 
     /* Create the view from the context's UI thread.  The window is
        unmapped, so the view is GONE.  */
@@ -1001,7 +1001,8 @@ public final class EmacsWindow extends EmacsHandleObject
       case MotionEvent.ACTION_CANCEL:
        /* Primary pointer released with index 0.  */
        pointerID = event.getPointerId (0);
-       coordinate = pointerMap.remove (pointerID);
+       coordinate = pointerMap.get (pointerID);
+       pointerMap.delete (pointerID);
        break;
 
       case MotionEvent.ACTION_POINTER_DOWN:
@@ -1020,7 +1021,8 @@ public final class EmacsWindow extends EmacsHandleObject
        /* Pointer removed.  Remove it from the map.  */
        pointerIndex = event.getActionIndex ();
        pointerID = event.getPointerId (pointerIndex);
-       coordinate = pointerMap.remove (pointerID);
+       coordinate = pointerMap.get (pointerID);
+       pointerMap.delete (pointerID);
        break;
 
       default:
index 18bdb6dbf60aa3bad9ec9fe50c91a19df263fc9f..aae4e2ee49b2f11deceff9c14041dd44a5254eba 100644 (file)
@@ -124,10 +124,15 @@ public final class EmacsWindowAttachmentManager
 
     intent = new Intent (EmacsService.SERVICE,
                         EmacsMultitaskActivity.class);
-    intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
-                    | Intent.FLAG_ACTIVITY_NEW_TASK
+
+    intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK
                     | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
 
+    /* Intent.FLAG_ACTIVITY_NEW_DOCUMENT is lamentably unavailable on
+       older systems than Lolipop.  */
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+      intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
       EmacsService.SERVICE.startActivity (intent);
     else