This source file includes following definitions.
- invalidateFocus1
- invalidateFocus
- detachWindow
- attachWindow
- destroy
- getAttachedWindow
- onCreate
- onGlobalLayout
- onDestroy
- onWindowFocusChanged
- onPause
- onResume
- onContextMenuClosed
- syncFullscreenWith
- onAttachedToWindow
- onActivityResult
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.gnu.emacs;
21
22 import java.lang.IllegalStateException;
23 import java.util.List;
24 import java.util.ArrayList;
25
26 import android.app.Activity;
27
28 import android.content.ContentResolver;
29 import android.content.Context;
30 import android.content.Intent;
31
32 import android.os.Build;
33 import android.os.Bundle;
34
35 import android.util.Log;
36
37 import android.net.Uri;
38
39 import android.view.Menu;
40 import android.view.View;
41 import android.view.ViewTreeObserver;
42 import android.view.Window;
43 import android.view.WindowInsets;
44 import android.view.WindowInsetsController;
45
46 import android.widget.FrameLayout;
47
48 public class EmacsActivity extends Activity
49 implements EmacsWindowAttachmentManager.WindowConsumer,
50 ViewTreeObserver.OnGlobalLayoutListener
51 {
52 public static final String TAG = "EmacsActivity";
53
54
55 public static final int ACCEPT_DOCUMENT_TREE = 1;
56
57
58 private EmacsWindow window;
59
60
61 private FrameLayout layout;
62
63
64 public static final List<EmacsActivity> focusedActivities;
65
66
67 public static EmacsActivity lastFocusedActivity;
68
69
70 public static EmacsWindow focusedWindow;
71
72
73 private boolean isPaused;
74
75
76 private boolean isFullscreen;
77
78
79 private static Menu lastClosedMenu;
80
81 static
82 {
83 focusedActivities = new ArrayList<EmacsActivity> ();
84 };
85
86 public static void
87 invalidateFocus1 (EmacsWindow window)
88 {
89 if (window.view.isFocused ())
90 focusedWindow = window;
91
92 for (EmacsWindow child : window.children)
93 invalidateFocus1 (child);
94 }
95
96 public static void
97 invalidateFocus ()
98 {
99 EmacsWindow oldFocus;
100
101
102
103
104 oldFocus = focusedWindow;
105 focusedWindow = null;
106
107 for (EmacsActivity activity : focusedActivities)
108 {
109 if (activity.window != null)
110 invalidateFocus1 (activity.window);
111 }
112
113
114
115
116 if (oldFocus != null)
117 EmacsNative.sendFocusOut (oldFocus.handle,
118 System.currentTimeMillis ());
119
120 if (focusedWindow != null)
121 EmacsNative.sendFocusIn (focusedWindow.handle,
122 System.currentTimeMillis ());
123 }
124
125 @Override
126 public final void
127 detachWindow ()
128 {
129 syncFullscreenWith (null);
130
131 if (window == null)
132 Log.w (TAG, "detachWindow called, but there is no window");
133 else
134 {
135
136
137 window.setConsumer (null);
138
139
140 window.noticeDeiconified ();
141 layout.removeView (window.view);
142 window = null;
143
144 invalidateFocus ();
145 }
146 }
147
148 @Override
149 public final void
150 attachWindow (EmacsWindow child)
151 {
152 Log.d (TAG, "attachWindow: " + child);
153
154 if (window != null)
155 throw new IllegalStateException ("trying to attach window when one"
156 + " already exists");
157
158 syncFullscreenWith (child);
159
160
161
162 window = child;
163 layout.addView (window.view);
164 child.setConsumer (this);
165
166
167 if (!child.getDontFocusOnMap ())
168 window.view.requestFocus ();
169
170
171 if (isPaused)
172 window.noticeIconified ();
173
174
175 invalidateFocus ();
176 }
177
178 @Override
179 public final void
180 destroy ()
181 {
182 finish ();
183 }
184
185 @Override
186 public final EmacsWindow
187 getAttachedWindow ()
188 {
189 return window;
190 }
191
192 @Override
193 public final void
194 onCreate (Bundle savedInstanceState)
195 {
196 FrameLayout.LayoutParams params;
197 Intent intent;
198 View decorView;
199 ViewTreeObserver observer;
200 int matchParent;
201
202
203
204 intent = getIntent ();
205 EmacsService.extraStartupArgument
206 = intent.getStringExtra ("org.gnu.emacs.STARTUP_ARGUMENT");
207
208 matchParent = FrameLayout.LayoutParams.MATCH_PARENT;
209 params
210 = new FrameLayout.LayoutParams (matchParent,
211 matchParent);
212
213
214 layout = new FrameLayout (this);
215 layout.setLayoutParams (params);
216
217
218 setContentView (layout);
219
220
221 EmacsService.startEmacsService (this);
222
223
224 EmacsWindowAttachmentManager.MANAGER.registerWindowConsumer (this);
225
226
227
228
229
230
231 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
232 && Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
233 {
234 decorView = getWindow ().getDecorView ();
235 observer = decorView.getViewTreeObserver ();
236 observer.addOnGlobalLayoutListener (this);
237 }
238
239 super.onCreate (savedInstanceState);
240 }
241
242 @Override
243 public final void
244 onGlobalLayout ()
245 {
246 syncFullscreenWith (window);
247 }
248
249 @Override
250 public final void
251 onDestroy ()
252 {
253 EmacsWindowAttachmentManager manager;
254 boolean isMultitask;
255
256 manager = EmacsWindowAttachmentManager.MANAGER;
257
258
259
260 Log.d (TAG, "onDestroy " + this);
261 isMultitask = this instanceof EmacsMultitaskActivity;
262 manager.removeWindowConsumer (this, isMultitask || isFinishing ());
263 focusedActivities.remove (this);
264 invalidateFocus ();
265
266
267 if (lastFocusedActivity == this)
268 lastFocusedActivity = null;
269
270 super.onDestroy ();
271 }
272
273 @Override
274 public final void
275 onWindowFocusChanged (boolean isFocused)
276 {
277 Log.d (TAG, ("onWindowFocusChanged: "
278 + (isFocused ? "YES" : "NO")));
279
280 if (isFocused && !focusedActivities.contains (this))
281 {
282 focusedActivities.add (this);
283 lastFocusedActivity = this;
284
285
286
287
288
289 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
290 && Build.VERSION.SDK_INT < Build.VERSION_CODES.R
291 && isFullscreen)
292 syncFullscreenWith (window);
293 }
294 else
295 focusedActivities.remove (this);
296
297 invalidateFocus ();
298 }
299
300 @Override
301 public final void
302 onPause ()
303 {
304 isPaused = true;
305
306 EmacsWindowAttachmentManager.MANAGER.noticeIconified (this);
307 super.onPause ();
308 }
309
310 @Override
311 public final void
312 onResume ()
313 {
314 isPaused = false;
315
316 EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this);
317 super.onResume ();
318 }
319
320 @Override
321 public final void
322 onContextMenuClosed (Menu menu)
323 {
324 int serial;
325
326 Log.d (TAG, "onContextMenuClosed: " + menu);
327
328
329
330 if (((EmacsContextMenu.wasSubmenuSelected == -2)
331 || (EmacsContextMenu.wasSubmenuSelected >= 0
332 && ((System.currentTimeMillis ()
333 - EmacsContextMenu.wasSubmenuSelected)
334 <= 300)))
335 || menu == lastClosedMenu)
336 {
337 EmacsContextMenu.wasSubmenuSelected = -1;
338 lastClosedMenu = menu;
339 return;
340 }
341
342
343
344
345 lastClosedMenu = null;
346
347
348
349 if (!EmacsContextMenu.itemAlreadySelected)
350 {
351 serial = EmacsContextMenu.lastMenuEventSerial;
352 EmacsNative.sendContextMenu ((short) 0, 0,
353 serial);
354 }
355
356 super.onContextMenuClosed (menu);
357 }
358
359 @SuppressWarnings ("deprecation")
360 public final void
361 syncFullscreenWith (EmacsWindow emacsWindow)
362 {
363 WindowInsetsController controller;
364 Window window;
365 int behavior, flags;
366 View view;
367
368 if (emacsWindow != null)
369 isFullscreen = emacsWindow.fullscreen;
370 else
371 isFullscreen = false;
372
373
374
375
376 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
377 {
378 window = getWindow ();
379
380
381 if (window == null)
382 return;
383
384 behavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
385 controller = window.getInsetsController ();
386 controller.setSystemBarsBehavior (behavior);
387
388 if (isFullscreen)
389 controller.hide (WindowInsets.Type.statusBars ()
390 | WindowInsets.Type.navigationBars ());
391 else
392 controller.show (WindowInsets.Type.statusBars ()
393 | WindowInsets.Type.navigationBars ());
394
395 return;
396 }
397
398 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
399 {
400
401
402 window = getWindow ();
403
404 if (window == null)
405 return;
406
407 view = window.getDecorView ();
408
409 if (isFullscreen)
410 {
411 flags = 0;
412 flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
413
414 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
415 {
416
417
418 flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
419 flags |= View.SYSTEM_UI_FLAG_IMMERSIVE;
420 flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
421 }
422
423
424 view.setSystemUiVisibility (flags);
425 }
426 else
427 view.setSystemUiVisibility (View.SYSTEM_UI_FLAG_VISIBLE);
428 }
429 }
430
431 @Override
432 public final void
433 onAttachedToWindow ()
434 {
435 super.onAttachedToWindow ();
436
437
438 syncFullscreenWith (window);
439 }
440
441
442
443 @Override
444 public final void
445 onActivityResult (int requestCode, int resultCode, Intent data)
446 {
447 ContentResolver resolver;
448 Uri uri;
449 int flags;
450
451 switch (requestCode)
452 {
453 case ACCEPT_DOCUMENT_TREE:
454
455
456
457
458 if (resultCode == RESULT_OK)
459 {
460 resolver = getContentResolver ();
461 uri = data.getData ();
462 flags = (Intent.FLAG_GRANT_READ_URI_PERMISSION
463 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
464
465 try
466 {
467 if (uri != null)
468 resolver.takePersistableUriPermission (uri, flags);
469 }
470 catch (Exception exception)
471 {
472
473
474
475 }
476 }
477
478 break;
479 }
480 }
481 };