Android: Work around Android devices where the am command doesn't work.

This commit is contained in:
Joey Hess 2013-05-31 21:28:37 -04:00
parent b325524b0f
commit a48d340abd
8 changed files with 166 additions and 34 deletions

View file

@ -20,6 +20,7 @@ import Assistant.Install
import Annex.Environment import Annex.Environment
import Utility.WebApp import Utility.WebApp
import Utility.Daemon (checkDaemon) import Utility.Daemon (checkDaemon)
import Utility.Env
import Init import Init
import qualified Git import qualified Git
import qualified Git.Config import qualified Git.Config
@ -32,7 +33,7 @@ import Control.Concurrent
import Control.Concurrent.STM import Control.Concurrent.STM
import System.Process (env, std_out, std_err) import System.Process (env, std_out, std_err)
import Network.Socket (HostName) import Network.Socket (HostName)
import System.Environment import System.Environment (getArgs)
def :: [Command] def :: [Command]
def = [ withOptions [listenOption] $ def = [ withOptions [listenOption] $
@ -158,25 +159,21 @@ firstRun listenhost = do
openBrowser :: Maybe FilePath -> FilePath -> String -> Maybe Handle -> Maybe Handle -> IO () openBrowser :: Maybe FilePath -> FilePath -> String -> Maybe Handle -> Maybe Handle -> IO ()
#ifndef __ANDROID__ #ifndef __ANDROID__
openBrowser mcmd htmlshim _realurl outh errh = do openBrowser mcmd htmlshim _realurl outh errh = runbrowser
#else #else
openBrowser mcmd htmlshim realurl outh errh = do openBrowser mcmd htmlshim realurl outh errh = do
{- The Android app has a menu item that opens this file. -} {- The Android app has a menu item that opens this file. -}
writeFile "/sdcard/git-annex.home/.git-annex-url" realurl writeFile "/sdcard/git-annex.home/.git-annex-url" url
#endif {- Android's `am` command does not work reliably across the
hPutStrLn (fromMaybe stdout outh) $ "Launching web browser on " ++ url - wide range of Android devices. Intead, FIFO should be set to
hFlush stdout - the filename of a fifo that we can write the URL to. -}
environ <- cleanEnvironment v <- getEnv "FIFO"
(_, _, _, pid) <- createProcess p case v of
{ env = environ Nothing -> runbrowser
, std_out = maybe Inherit UseHandle outh Just f -> void $ forkIO $ do
, std_err = maybe Inherit UseHandle errh fd <- openFd f WriteOnly Nothing defaultFileFlags
} void $ fdWrite fd url
exitcode <- waitForProcess pid closeFd fd
unless (exitcode == ExitSuccess) $ do
hPutStrLn (fromMaybe stderr errh) "failed to start web browser"
#ifdef __ANDROID__
hPutStrLn (fromMaybe stderr errh) "To open the WebApp, go to the menu and select \"Open WebApp\""
#endif #endif
where where
p = case mcmd of p = case mcmd of
@ -190,6 +187,18 @@ openBrowser mcmd htmlshim realurl outh errh = do
#else #else
url = fileUrl htmlshim url = fileUrl htmlshim
#endif #endif
runbrowser = do
hPutStrLn (fromMaybe stdout outh) $ "Launching web browser on " ++ url
hFlush stdout
environ <- cleanEnvironment
(_, _, _, pid) <- createProcess p
{ env = environ
, std_out = maybe Inherit UseHandle outh
, std_err = maybe Inherit UseHandle errh
}
exitcode <- waitForProcess pid
unless (exitcode == ExitSuccess) $ do
hPutStrLn (fromMaybe stderr errh) "failed to start web browser"
{- web.browser is a generic git config setting for a web browser program -} {- web.browser is a generic git config setting for a web browser program -}
webBrowser :: Git.Repo -> Maybe FilePath webBrowser :: Git.Repo -> Maybe FilePath

View file

@ -49,6 +49,7 @@ browserProc :: String -> CreateProcess
browserProc url = proc "open" [url] browserProc url = proc "open" [url]
#else #else
#ifdef __ANDROID__ #ifdef __ANDROID__
-- Warning: The `am` command does not work very reliably on Android.
browserProc url = proc "am" browserProc url = proc "am"
["start", "-a", "android.intent.action.VIEW", "-d", url] ["start", "-a", "android.intent.action.VIEW", "-d", url]
#else #else

2
debian/changelog vendored
View file

@ -20,7 +20,7 @@ git-annex (4.20130522) UNRELEASED; urgency=low
* sync: Fix double merge conflict resolution handling. * sync: Fix double merge conflict resolution handling.
* XMPP: Fix a file descriptor leak. * XMPP: Fix a file descriptor leak.
* Android: Added an "Open WebApp" item to the terminal's menu. * Android: Added an "Open WebApp" item to the terminal's menu.
Should work for Android devices that cannot auto-open the webapp on start. * Android: Work around Android devices where the `am` command doesn't work.
* Can now restart certain long-running git processes if they crash, and * Can now restart certain long-running git processes if they crash, and
continue working. continue working.

View file

@ -14,3 +14,5 @@ Just downloaded the .apk (Friday May 3rd). Android 4.2.2 on Google/LG Nexus 4
See this [screenshot](https://docs.google.com/file/d/0B8tqeaAn45VORU1ET1ZpTWxLTjQ/edit?usp=sharing). See this [screenshot](https://docs.google.com/file/d/0B8tqeaAn45VORU1ET1ZpTWxLTjQ/edit?usp=sharing).
Feel free to ping me on IRC if you need additional info or want to test a fix. Feel free to ping me on IRC if you need additional info or want to test a fix.
> [[done]]; now comprehensively fixed. --[[Joey]]

View file

@ -19,3 +19,6 @@ Git annex still syncs with `box.com` even if the warning is showing.
I'm using a Nexus 4 (4.2.2) I'm using a Nexus 4 (4.2.2)
I didn't find `daemon.log`. I didn't find `daemon.log`.
> [[done]]; the android app no longer uses `am`, so no longer needs to
> display a message when `am` fails. --[[Joey]]

View file

@ -11,7 +11,7 @@ PATH:=$(ANDROID_CROSS_COMPILER):$(PATH)
export ANDROID_SDK_ROOT?=$(HOME)/tmp/adt-bundle-linux-x86/sdk export ANDROID_SDK_ROOT?=$(HOME)/tmp/adt-bundle-linux-x86/sdk
export ANDROID_NDK_ROOT?=$(HOME)/tmp/android-ndk-r8d export ANDROID_NDK_ROOT?=$(HOME)/tmp/android-ndk-r8d
# Where to store the $(GIT_ANNEX_ANDROID_SOURCETREE)s to utilities. This # Where to store the source tree used to build utilities. This
# directory will be created by `make source`. # directory will be created by `make source`.
GIT_ANNEX_ANDROID_SOURCETREE?=$(HOME)/tmp/android-sourcetree GIT_ANNEX_ANDROID_SOURCETREE?=$(HOME)/tmp/android-sourcetree

View file

@ -116,6 +116,10 @@ run () {
fi fi
} }
if $cmd test -n "$MKFIFO"; then
# because java is insane
$cmd mkfifo "$MKFIFO"
else
if ! prep; then if ! prep; then
$cmd echo "prep failed. Please report a bug." $cmd echo "prep failed. Please report a bug."
read line read line
@ -125,3 +129,4 @@ if ! install; then
read line read line
fi fi
run run
fi

View file

@ -390,21 +390,65 @@ index f1464e9..b06ec9a 100644
<string name="special_keys">Special keys</string> <string name="special_keys">Special keys</string>
<string name="toggle_soft_keyboard">Toggle soft keyboard</string> <string name="toggle_soft_keyboard">Toggle soft keyboard</string>
diff --git a/src/jackpal/androidterm/ShellTermSession.java b/src/jackpal/androidterm/ShellTermSession.java
index 501e7ab..0b43513 100644
--- a/src/jackpal/androidterm/ShellTermSession.java
+++ b/src/jackpal/androidterm/ShellTermSession.java
@@ -80,12 +80,12 @@ public class ShellTermSession extends TermSession {
}
};
- public ShellTermSession(TermSettings settings, String initialCommand) {
+ public ShellTermSession(TermSettings settings, String initialCommand, String webAppFifo) {
super();
updatePrefs(settings);
- initializeSession();
+ initializeSession(webAppFifo);
mInitialCommand = initialCommand;
mWatcherThread = new Thread() {
@@ -106,7 +106,7 @@ public class ShellTermSession extends TermSession {
setDefaultUTF8Mode(settings.defaultToUTF8Mode());
}
- private void initializeSession() {
+ private void initializeSession(String webAppFifo) {
TermSettings settings = mSettings;
int[] processId = new int[1];
@@ -128,9 +128,10 @@ public class ShellTermSession extends TermSession {
if (settings.verifyPath()) {
path = checkPath(path);
}
- String[] env = new String[2];
+ String[] env = new String[3];
env[0] = "TERM=" + settings.getTermType();
env[1] = "PATH=" + path;
+ env[2] = "FIFO=" + webAppFifo;
createSubprocess(processId, settings.getShell(), env);
mProcId = processId[0];
diff --git a/src/jackpal/androidterm/Term.java b/src/jackpal/androidterm/Term.java diff --git a/src/jackpal/androidterm/Term.java b/src/jackpal/androidterm/Term.java
index 8a3a4ac..af8d1ad 100644 index 8a3a4ac..824025d 100644
--- a/src/jackpal/androidterm/Term.java --- a/src/jackpal/androidterm/Term.java
+++ b/src/jackpal/androidterm/Term.java +++ b/src/jackpal/androidterm/Term.java
@@ -21,6 +21,9 @@ import java.text.Collator; @@ -20,6 +20,13 @@ import java.io.UnsupportedEncodingException;
import java.text.Collator;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
+import java.lang.Process;
+import java.lang.ProcessBuilder;
+import java.util.Map;
+
+import java.io.FileReader; +import java.io.FileReader;
+import java.io.BufferedReader; +import java.io.BufferedReader;
+ +import java.io.File;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ActivityNotFoundException; @@ -59,6 +66,11 @@ import android.view.inputmethod.InputMethodManager;
@@ -59,6 +62,11 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -416,7 +460,75 @@ index 8a3a4ac..af8d1ad 100644
import jackpal.androidterm.emulatorview.ColorScheme; import jackpal.androidterm.emulatorview.ColorScheme;
import jackpal.androidterm.emulatorview.EmulatorView; import jackpal.androidterm.emulatorview.EmulatorView;
import jackpal.androidterm.emulatorview.TermSession; import jackpal.androidterm.emulatorview.TermSession;
@@ -911,31 +919,15 @@ public class Term extends Activity implements UpdateCallback { @@ -107,6 +119,9 @@ public class Term extends Activity implements UpdateCallback {
public static final String EXTRA_WINDOW_ID = "jackpal.androidterm.window_id";
private int onResumeSelectWindow = -1;
+ public static String appDir;
+ public static String webAppFifo;
+
private PowerManager.WakeLock mWakeLock;
private WifiManager.WifiLock mWifiLock;
// Available on API 12 and later
@@ -257,6 +272,48 @@ public class Term extends Activity implements UpdateCallback {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+
+ try {
+ appDir = getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;
+ } catch (Exception e) {
+ appDir = "/data/data/ga.androidterm";
+ }
+ webAppFifo = appDir + "/fifo";
+
+ /* webapp url opening thread */
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ /* First, set up the fifo that urls to open will be
+ * read from. This is complicated by java not being
+ * able to mkfifo. */
+ File f = new File (webAppFifo);
+ if (! f.exists()) {
+ ProcessBuilder pb = new ProcessBuilder(appDir + "/lib/lib.start.so");
+ Map<String, String> env = pb.environment();
+ env.put("MKFIFO", webAppFifo);
+ Process p = pb.start();
+ p.waitFor();
+ }
+
+ /* Reading from the fifo blocks until a url is written
+ * to it. */
+ BufferedReader buf = new BufferedReader(new FileReader(webAppFifo));
+ while (true) {
+ String s = buf.readLine();
+ try {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(s));
+ startActivity(intent);
+ } catch (Exception e) {
+ }
+
+ }
+ } catch (Exception e) {
+ }
+ }
+ }.start();
+
Log.e(TermDebug.LOG_TAG, "onCreate");
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mSettings = new TermSettings(getResources(), mPrefs);
@@ -427,7 +484,7 @@ public class Term extends Activity implements UpdateCallback {
}
protected static TermSession createTermSession(Context context, TermSettings settings, String initialCommand) {
- ShellTermSession session = new ShellTermSession(settings, initialCommand);
+ ShellTermSession session = new ShellTermSession(settings, initialCommand, webAppFifo);
// XXX We should really be able to fetch this from within TermSession
session.setProcessExitMessage(context.getString(R.string.process_exit_message));
@@ -911,31 +968,15 @@ public class Term extends Activity implements UpdateCallback {
} }
private void doEmailTranscript() { private void doEmailTranscript() {