author | Chris Peterson <cpeterson@mozilla.com> |
Thu, 07 Mar 2013 17:55:49 +0000 | |
changeset 136697 | 6b8e128a989c40614621dd72a437d9e66435afd2 |
parent 136696 | a93c2f4828ae404583f730fda1d8bf52a78c4633 |
child 136698 | d1b71de5bbc128ecc1ae32fea556df104502097a |
push id | 336 |
push user | akeybl@mozilla.com |
push date | Mon, 17 Jun 2013 22:53:19 +0000 |
treeherder | mozilla-release@574a39cdf657 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mfinkle |
bugs | 847839 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/ScreenOrientation.h +++ b/dom/base/ScreenOrientation.h @@ -5,17 +5,16 @@ #ifndef mozilla_dom_ScreenOrientation_h #define mozilla_dom_ScreenOrientation_h namespace mozilla { namespace dom { // Make sure that any change here is also made in // * mobile/android/base/GeckoScreenOrientationListener.java -// * embedding/android/GeckoScreenOrientationListener.java typedef uint32_t ScreenOrientation; static const ScreenOrientation eScreenOrientation_None = 0; static const ScreenOrientation eScreenOrientation_PortraitPrimary = 1u << 0; static const ScreenOrientation eScreenOrientation_PortraitSecondary = 1u << 1; static const ScreenOrientation eScreenOrientation_LandscapePrimary = 1u << 2; static const ScreenOrientation eScreenOrientation_LandscapeSecondary = 1u << 3;
--- a/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl +++ b/dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl @@ -13,17 +13,17 @@ dictionary SmsThreadListItem }; [scriptable, builtinclass, uuid(edb1de12-8d58-11e2-b382-7bf132b20cb2)] interface nsIMobileMessageCallback : nsISupports { /** * All SMS related errors that could apply to SmsRequest objects. * Make sure to keep this list in sync with the list in: - * embedding/android/GeckoSmsManager.java + * mobile/android/GeckoSmsManager.java */ const unsigned short SUCCESS_NO_ERROR = 0; const unsigned short NO_SIGNAL_ERROR = 1; const unsigned short NOT_FOUND_ERROR = 2; const unsigned short UNKNOWN_ERROR = 3; const unsigned short INTERNAL_ERROR = 4; /**
--- a/dom/mobilemessage/src/Types.h +++ b/dom/mobilemessage/src/Types.h @@ -9,17 +9,17 @@ #include "IPCMessageUtils.h" namespace mozilla { namespace dom { namespace mobilemessage { // For MmsMessageData.state and SmsMessageData.deliveryState // Please keep the following files in sync with enum below: -// embedding/android/GeckoSmsManager.java +// mobile/android/base/GeckoSmsManager.java enum DeliveryState { eDeliveryState_Sent = 0, eDeliveryState_Received, eDeliveryState_Sending, eDeliveryState_Error, eDeliveryState_Unknown, eDeliveryState_NotDownloaded, // This state should stay at the end.
deleted file mode 100644 --- a/embedding/android/AlertNotification.java +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.graphics.*; -import android.net.Uri; -import android.util.Log; -import android.widget.RemoteViews; -import java.net.*; -import java.text.NumberFormat; - -public class AlertNotification - extends Notification -{ - Context mContext; - int mId; - int mIcon; - String mTitle; - String mText; - boolean mProgressStyle; - NotificationManager mNotificationManager; - double mPrevPercent = -1; - String mPrevAlertText = ""; - static final double UPDATE_THRESHOLD = .01; - - public AlertNotification(Context aContext, int aNotificationId, int aIcon, - String aTitle, String aText, long aWhen) { - super(aIcon, (aText.length() > 0) ? aText : aTitle, aWhen); - - mContext = aContext; - mIcon = aIcon; - mTitle = aTitle; - mText = aText; - mProgressStyle = false; - mId = aNotificationId; - - mNotificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - } - - public boolean isProgressStyle() { - return mProgressStyle; - } - - public void show() { - mNotificationManager.notify(mId, this); - } - - public void setCustomIcon(Uri aIconUri) { - if (aIconUri == null || aIconUri.getScheme() == null) - return; - - // Custom view - int layout = R.layout.notification_icon_text; - RemoteViews view = new RemoteViews(GeckoApp.mAppContext.getPackageName(), layout); - try { - URL url = new URL(aIconUri.toString()); - Bitmap bm = BitmapFactory.decodeStream(url.openStream()); - view.setImageViewBitmap(R.id.notificationImage, bm); - view.setTextViewText(R.id.notificationTitle, mTitle); - if (mText.length() > 0) { - view.setTextViewText(R.id.notificationText, mText); - } - contentView = view; - mNotificationManager.notify(mId, this); - } catch(Exception ex) { - Log.e("GeckoAlert", "failed to create bitmap", ex); - } - } - - public void updateProgress(String aAlertText, long aProgress, long aProgressMax) { - if (!mProgressStyle) { - // Custom view - int layout = aAlertText.length() > 0 ? R.layout.notification_progress_text : R.layout.notification_progress; - - RemoteViews view = new RemoteViews(GeckoApp.mAppContext.getPackageName(), layout); - view.setImageViewResource(R.id.notificationImage, mIcon); - view.setTextViewText(R.id.notificationTitle, mTitle); - contentView = view; - flags |= FLAG_ONGOING_EVENT | FLAG_ONLY_ALERT_ONCE; - - mProgressStyle = true; - } - - String text; - double percent = 0; - if (aProgressMax > 0) - percent = ((double)aProgress / (double)aProgressMax); - - if (aAlertText.length() > 0) - text = aAlertText; - else - text = NumberFormat.getPercentInstance().format(percent); - - if (mPrevAlertText.equals(text) && Math.abs(mPrevPercent - percent) < UPDATE_THRESHOLD) - return; - - contentView.setTextViewText(R.id.notificationText, text); - contentView.setProgressBar(R.id.notificationProgressbar, (int)aProgressMax, (int)aProgress, false); - - // Update the notification - mNotificationManager.notify(mId, this); - - mPrevPercent = percent; - mPrevAlertText = text; - } -}
deleted file mode 100644 --- a/embedding/android/AndroidManifest.xml.in +++ /dev/null @@ -1,149 +0,0 @@ -#filter substitution -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="@ANDROID_PACKAGE_NAME@" - android:installLocation="auto" - android:versionCode="@ANDROID_VERSION_CODE@" - android:versionName="@MOZ_APP_VERSION@" -#ifdef MOZ_ANDROID_SHARED_ID - android:sharedUserId="@MOZ_ANDROID_SHARED_ID@" -#endif - > - - <uses-sdk android:minSdkVersion="5" - android:targetSdkVersion="11"/> - - <compatible-screens> - <!-- all xlarge size screens --> - <screen android:screenSize="xlarge" android:screenDensity="ldpi" /> - <screen android:screenSize="xlarge" android:screenDensity="mdpi" /> - <screen android:screenSize="xlarge" android:screenDensity="hdpi" /> - <screen android:screenSize="xlarge" android:screenDensity="xhdpi" /> - </compatible-screens> - - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/> - - <uses-permission android:name="android.permission.WAKE_LOCK"/> - <uses-permission android:name="android.permission.VIBRATE"/> - -#ifdef MOZ_WEBSMS_BACKEND - <!-- WebSMS --> - <uses-permission android:name="android.permission.SEND_SMS"/> - <uses-permission android:name="android.permission.RECEIVE_SMS"/> - <uses-permission android:name="android.permission.WRITE_SMS"/> - <uses-permission android:name="android.permission.READ_SMS"/> -#endif - - <uses-feature android:name="android.hardware.location" android:required="false"/> - <uses-feature android:name="android.hardware.location.gps" android:required="false"/> - <uses-feature android:name="android.hardware.touchscreen"/> - - <uses-permission android:name="android.permission.CAMERA" /> - <uses-feature android:name="android.hardware.camera" android:required="false"/> - <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/> - - <application android:label="@MOZ_APP_DISPLAYNAME@" - android:icon="@drawable/icon" -#if MOZILLA_OFFICIAL - android:debuggable="false"> -#else - android:debuggable="true"> -#endif - - <activity android:name="App" - android:label="@MOZ_APP_DISPLAYNAME@" - android:configChanges="keyboard|keyboardHidden|mcc|mnc" - android:windowSoftInputMode="stateUnspecified|adjustResize" - android:launchMode="singleTask" - android:theme="@style/GreyTheme"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - - <!-- Default browser intents --> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - <data android:scheme="http" /> - <data android:scheme="https" /> - <data android:scheme="about" /> - <data android:scheme="javascript" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.BROWSABLE" /> - <category android:name="android.intent.category.DEFAULT" /> - <data android:scheme="file" /> - <data android:scheme="http" /> - <data android:scheme="https" /> - <data android:mimeType="text/html"/> - <data android:mimeType="text/plain"/> - <data android:mimeType="application/xhtml+xml"/> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.WEB_SEARCH" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - <data android:scheme="" /> - <data android:scheme="http" /> - <data android:scheme="https" /> - </intent-filter> - - <!-- For debugging --> - <intent-filter> - <action android:name="org.mozilla.gecko.DEBUG" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - - <receiver android:name="NotificationHandler"> - <intent-filter> - <action android:name="org.mozilla.gecko.ACTION_ALERT_CLICK" /> - <action android:name="org.mozilla.gecko.ACTION_ALERT_CLEAR" /> - </intent-filter> - </receiver> - - <activity android:name="Restarter" - android:process="@ANDROID_PACKAGE_NAME@Restarter" - android:theme="@style/GreyTheme" - android:excludeFromRecents="true"> - <intent-filter> - <action android:name="org.mozilla.gecko.restart"/> - </intent-filter> - </activity> - -#if MOZ_CRASHREPORTER - <activity android:name="CrashReporter" - android:label="@string/crash_reporter_title" - android:icon="@drawable/crash_reporter" - android:excludeFromRecents="true"> - <intent-filter> - <action android:name="org.mozilla.gecko.reportCrash" /> - </intent-filter> - </activity> -#endif - - <activity android:name="LauncherShortcuts" - android:label="@string/launcher_shortcuts_title" - android:theme="@android:style/Theme.Translucent"> - <!-- This intent-filter allows your shortcuts to be created in the launcher. --> - <intent-filter> - <action android:name="android.intent.action.CREATE_SHORTCUT" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity android:name="org.mozilla.gecko.VideoPlayer" - android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation" - android:theme="@android:style/Theme.NoTitleBar" > - <intent-filter> - <action android:name="org.mozilla.gecko.PLAY_VIDEO" /> - </intent-filter> - </activity> - </application> -</manifest>
deleted file mode 100644 --- a/embedding/android/App.java.in +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#filter substitution -package @ANDROID_PACKAGE_NAME@; - -import org.mozilla.gecko.GeckoApp; - -public class App extends GeckoApp { - public String getPackageName() { - return "@ANDROID_PACKAGE_NAME@"; - } - public String getContentProcessName() { - return "@MOZ_CHILD_PROCESS_NAME@"; - } -}; -
deleted file mode 100644 --- a/embedding/android/CrashReporter.java.in +++ /dev/null @@ -1,311 +0,0 @@ -/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#filter substitution -package @ANDROID_PACKAGE_NAME@; - -import java.util.HashMap; -import java.util.Map; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.InputStreamReader; -import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; - -import org.mozilla.gecko.R; - -public class CrashReporter extends Activity -{ - private static final String LOGTAG = "GeckoCrashReporter"; - - private static final String PASSED_MINI_DUMP_KEY = "minidumpPath"; - private static final String MINI_DUMP_PATH_KEY = "upload_file_minidump"; - private static final String PAGE_URL_KEY = "URL"; - private static final String NOTES_KEY = "Notes"; - private static final String SERVER_URL_KEY = "ServerURL"; - - private static final String CRASH_REPORT_SUFFIX = "/mozilla/Crash Reports/"; - private static final String PENDING_SUFFIX = CRASH_REPORT_SUFFIX + "pending"; - private static final String SUBMITTED_SUFFIX = CRASH_REPORT_SUFFIX + "submitted"; - - private Handler mHandler; - private ProgressDialog mProgressDialog; - private File mPendingMinidumpFile; - private File mPendingExtrasFile; - private HashMap<String, String> mExtrasStringMap; - - private boolean moveFile(File inFile, File outFile) { - Log.i(LOGTAG, "moving " + inFile + " to " + outFile); - if (inFile.renameTo(outFile)) - return true; - try { - outFile.createNewFile(); - Log.i(LOGTAG, "couldn't rename minidump file"); - // so copy it instead - FileChannel inChannel = new FileInputStream(inFile).getChannel(); - FileChannel outChannel = new FileOutputStream(outFile).getChannel(); - long transferred = inChannel.transferTo(0, inChannel.size(), outChannel); - inChannel.close(); - outChannel.close(); - - if (transferred > 0) - inFile.delete(); - } catch (Exception e) { - Log.e(LOGTAG, "exception while copying minidump file: ", e); - return false; - } - return true; - } - - private void doFinish() { - if (mHandler != null) { - mHandler.post(new Runnable() { - public void run() { - finish(); - } - }); - } - } - - @Override - public void finish() { - try { - if (mProgressDialog.isShowing()) { - mProgressDialog.dismiss(); - } - } catch (Exception e) { - Log.e(LOGTAG, "exception while closing progress dialog: ", e); - } - super.finish(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // mHandler is created here so runnables can be run on the main thread - mHandler = new Handler(); - setContentView(R.layout.crash_reporter); - mProgressDialog = new ProgressDialog(this); - mProgressDialog.setMessage(getString(R.string.sending_crash_report)); - - final Button restartButton = (Button) findViewById(R.id.restart); - final Button closeButton = (Button) findViewById(R.id.close); - String passedMinidumpPath = getIntent().getStringExtra(PASSED_MINI_DUMP_KEY); - File passedMinidumpFile = new File(passedMinidumpPath); - File pendingDir = new File(getFilesDir(), PENDING_SUFFIX); - pendingDir.mkdirs(); - mPendingMinidumpFile = new File(pendingDir, passedMinidumpFile.getName()); - moveFile(passedMinidumpFile, mPendingMinidumpFile); - - File extrasFile = new File(passedMinidumpPath.replaceAll(".dmp", ".extra")); - mPendingExtrasFile = new File(pendingDir, extrasFile.getName()); - moveFile(extrasFile, mPendingExtrasFile); - - mExtrasStringMap = new HashMap<String, String>(); - readStringsFromFile(mPendingExtrasFile.getPath(), mExtrasStringMap); - } - - private void backgroundSendReport() { - final CheckBox sendReportCheckbox = (CheckBox) findViewById(R.id.send_report); - if (!sendReportCheckbox.isChecked()) { - doFinish(); - return; - } - - mProgressDialog.show(); - new Thread(new Runnable() { - public void run() { - sendReport(mPendingMinidumpFile, mExtrasStringMap, mPendingExtrasFile); - } - }, "CrashReporter Thread").start(); - } - - public void onCloseClick(View v) { // bound via crash_reporter.xml - backgroundSendReport(); - } - - public void onRestartClick(View v) { // bound via crash_reporter.xml - doRestart(); - backgroundSendReport(); - } - - private boolean readStringsFromFile(String filePath, Map<String, String> stringMap) { - try { - BufferedReader reader = new BufferedReader(new FileReader(filePath)); - return readStringsFromReader(reader, stringMap); - } catch (Exception e) { - Log.e(LOGTAG, "exception while reading strings: ", e); - return false; - } - } - - private boolean readStringsFromReader(BufferedReader reader, Map<String, String> stringMap) throws IOException { - String line; - while ((line = reader.readLine()) != null) { - int equalsPos = -1; - if ((equalsPos = line.indexOf('=')) != -1) { - String key = line.substring(0, equalsPos); - String val = unescape(line.substring(equalsPos + 1)); - stringMap.put(key, val); - } - } - reader.close(); - return true; - } - - private String generateBoundary() { - // Generate some random numbers to fill out the boundary - int r0 = (int)((double)Integer.MAX_VALUE * Math.random()); - int r1 = (int)((double)Integer.MAX_VALUE * Math.random()); - return String.format("---------------------------%08X%08X", r0, r1); - } - - private void sendPart(OutputStream os, String boundary, String name, String data) { - try { - os.write(("--" + boundary + "\r\n" + - "Content-Disposition: form-data; name=\"" + name + "\"\r\n" + - "\r\n" + - data + "\r\n" - ).getBytes()); - } catch (Exception ex) { - Log.e(LOGTAG, "Exception when sending \"" + name + "\"", ex); - } - } - - private void sendFile(OutputStream os, String boundary, String name, File file) throws IOException { - os.write(("--" + boundary + "\r\n" + - "Content-Disposition: form-data; name=\"" + name + "\"; " + - "filename=\"" + file.getName() + "\"\r\n" + - "Content-Type: application/octet-stream\r\n" + - "\r\n" - ).getBytes()); - FileChannel fc = new FileInputStream(file).getChannel(); - fc.transferTo(0, fc.size(), Channels.newChannel(os)); - fc.close(); - } - - private void sendReport(File minidumpFile, Map<String, String> extras, File extrasFile) { - Log.i(LOGTAG, "sendReport: " + minidumpFile.getPath()); - final CheckBox includeURLCheckbox = (CheckBox) findViewById(R.id.include_url); - - String spec = extras.get(SERVER_URL_KEY); - if (spec == null) { - doFinish(); - return; - } - - Log.i(LOGTAG, "server url: " + spec); - try { - URL url = new URL(spec); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setRequestMethod("POST"); - String boundary = generateBoundary(); - conn.setDoOutput(true); - conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); - - OutputStream os = conn.getOutputStream(); - for (String key : extras.keySet()) { - if (key.equals(PAGE_URL_KEY)) { - if (includeURLCheckbox.isChecked()) - sendPart(os, boundary, key, extras.get(key)); - } else if (!key.equals(SERVER_URL_KEY) && !key.equals(NOTES_KEY)) { - sendPart(os, boundary, key, extras.get(key)); - } - } - - // Add some extra information to notes so its displayed by - // crash-stats.mozilla.org. Remove this when bug 607942 is fixed. - StringBuffer sb = new StringBuffer(); - sb.append(extras.containsKey(NOTES_KEY) ? extras.get(NOTES_KEY) + "\n" : ""); - if (@MOZ_MIN_CPU_VERSION@ < 7) - sb.append("nothumb Build\n"); - sb.append(Build.MANUFACTURER).append(' ') - .append(Build.MODEL).append('\n') - .append(Build.FINGERPRINT); - sendPart(os, boundary, NOTES_KEY, sb.toString()); - - sendPart(os, boundary, "Min_ARM_Version", "@MOZ_MIN_CPU_VERSION@"); - sendPart(os, boundary, "Android_Manufacturer", Build.MANUFACTURER); - sendPart(os, boundary, "Android_Model", Build.MODEL); - sendPart(os, boundary, "Android_Board", Build.BOARD); - sendPart(os, boundary, "Android_Brand", Build.BRAND); - sendPart(os, boundary, "Android_Device", Build.DEVICE); - sendPart(os, boundary, "Android_Display", Build.DISPLAY); - sendPart(os, boundary, "Android_Fingerprint", Build.FINGERPRINT); - sendPart(os, boundary, "Android_CPU_ABI", Build.CPU_ABI); - if (Build.VERSION.SDK_INT >= 8) { - try { - sendPart(os, boundary, "Android_CPU_ABI2", Build.CPU_ABI2); - sendPart(os, boundary, "Android_Hardware", Build.HARDWARE); - } catch (Exception ex) { - Log.e(LOGTAG, "Exception while sending SDK version 8 keys", ex); - } - } - sendPart(os, boundary, "Android_Version", Build.VERSION.SDK_INT + " (" + Build.VERSION.CODENAME + ")"); - - sendFile(os, boundary, MINI_DUMP_PATH_KEY, minidumpFile); - os.write(("\r\n--" + boundary + "--\r\n").getBytes()); - os.flush(); - os.close(); - BufferedReader br = new BufferedReader( - new InputStreamReader(conn.getInputStream())); - HashMap<String, String> responseMap = new HashMap<String, String>(); - readStringsFromReader(br, responseMap); - - if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - File submittedDir = new File(getFilesDir(), - SUBMITTED_SUFFIX); - submittedDir.mkdirs(); - minidumpFile.delete(); - extrasFile.delete(); - String crashid = responseMap.get("CrashID"); - File file = new File(submittedDir, crashid + ".txt"); - FileOutputStream fos = new FileOutputStream(file); - fos.write("Crash ID: ".getBytes()); - fos.write(crashid.getBytes()); - fos.close(); - } - } catch (IOException e) { - Log.e(LOGTAG, "exception during send: ", e); - } - - doFinish(); - } - - private void doRestart() { - try { - String action = "android.intent.action.MAIN"; - Intent intent = new Intent(action); - intent.setClassName("@ANDROID_PACKAGE_NAME@", - "@ANDROID_PACKAGE_NAME@.App"); - Log.i(LOGTAG, intent.toString()); - startActivity(intent); - } catch (Exception e) { - Log.e(LOGTAG, "error while trying to restart", e); - } - } - - private String unescape(String string) { - return string.replaceAll("\\\\\\\\", "\\").replaceAll("\\\\n", "\n").replaceAll("\\\\t", "\t"); - } -}
deleted file mode 100644 --- a/embedding/android/GeckoApp.java +++ /dev/null @@ -1,858 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.io.*; -import java.util.*; -import java.util.zip.*; -import java.nio.*; -import java.nio.channels.FileChannel; -import java.util.concurrent.*; -import java.lang.reflect.*; - -import android.os.*; -import android.app.*; -import android.text.*; -import android.view.*; -import android.view.inputmethod.*; -import android.content.*; -import android.content.res.*; -import android.graphics.*; -import android.widget.*; -import android.hardware.*; - -import android.util.*; -import android.net.*; -import android.database.*; -import android.provider.*; -import android.content.pm.*; -import android.content.pm.PackageManager.*; -import dalvik.system.*; - -abstract public class GeckoApp - extends Activity -{ - private static final String LOG_FILE_NAME = "GeckoApp"; - - public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK"; - public static final String ACTION_ALERT_CLEAR = "org.mozilla.gecko.ACTION_ALERT_CLEAR"; - public static final String ACTION_WEBAPP = "org.mozilla.gecko.WEBAPP"; - public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG"; - public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK"; - - public static AbsoluteLayout mainLayout; - public static GeckoSurfaceView surfaceView; - public static SurfaceView cameraView; - public static GeckoApp mAppContext; - public static boolean mFullscreen = false; - public static File sGREDir = null; - static Thread mLibLoadThread = null; - public Handler mMainHandler; - private IntentFilter mConnectivityFilter; - private BroadcastReceiver mConnectivityReceiver; - private BroadcastReceiver mBatteryReceiver; - - enum LaunchState {PreLaunch, Launching, WaitForDebugger, - Launched, GeckoRunning, GeckoExiting}; - private static LaunchState sLaunchState = LaunchState.PreLaunch; - private static boolean sTryCatchAttached = false; - - - static boolean checkLaunchState(LaunchState checkState) { - synchronized(sLaunchState) { - return sLaunchState == checkState; - } - } - - static void setLaunchState(LaunchState setState) { - synchronized(sLaunchState) { - sLaunchState = setState; - } - } - - // if mLaunchState is equal to checkState this sets mLaunchState to setState - // and return true. Otherwise we return false. - static boolean checkAndSetLaunchState(LaunchState checkState, LaunchState setState) { - synchronized(sLaunchState) { - if (sLaunchState != checkState) - return false; - sLaunchState = setState; - return true; - } - } - - void showErrorDialog(String message) - { - new AlertDialog.Builder(this) - .setMessage(message) - .setCancelable(false) - .setPositiveButton(R.string.exit_label, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, - int id) - { - GeckoApp.this.finish(); - System.exit(0); - } - }).show(); - } - - public static final String PLUGIN_ACTION = "android.webkit.PLUGIN"; - - /** - * A plugin that wish to be loaded in the WebView must provide this permission - * in their AndroidManifest.xml. - */ - public static final String PLUGIN_PERMISSION = "android.webkit.permission.PLUGIN"; - - private static final String LOGTAG = "PluginManager"; - - private static final String PLUGIN_SYSTEM_LIB = "/system/lib/plugins/"; - - private static final String PLUGIN_TYPE = "type"; - private static final String TYPE_NATIVE = "native"; - public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>(); - - String[] getPluginDirectories() { - - ArrayList<String> directories = new ArrayList<String>(); - PackageManager pm = this.mAppContext.getPackageManager(); - List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION), - PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); - - synchronized(mPackageInfoCache) { - - // clear the list of existing packageInfo objects - mPackageInfoCache.clear(); - - - for (ResolveInfo info : plugins) { - - // retrieve the plugin's service information - ServiceInfo serviceInfo = info.serviceInfo; - if (serviceInfo == null) { - Log.w(LOGTAG, "Ignore bad plugin"); - continue; - } - - Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName); - - - // retrieve information from the plugin's manifest - PackageInfo pkgInfo; - try { - pkgInfo = pm.getPackageInfo(serviceInfo.packageName, - PackageManager.GET_PERMISSIONS - | PackageManager.GET_SIGNATURES); - } catch (Exception e) { - Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName); - continue; - } - if (pkgInfo == null) { - Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Could not load package information."); - continue; - } - - /* - * find the location of the plugin's shared library. The default - * is to assume the app is either a user installed app or an - * updated system app. In both of these cases the library is - * stored in the app's data directory. - */ - String directory = pkgInfo.applicationInfo.dataDir + "/lib"; - final int appFlags = pkgInfo.applicationInfo.flags; - final int updatedSystemFlags = ApplicationInfo.FLAG_SYSTEM | - ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; - // preloaded system app with no user updates - if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) { - directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName; - } - - // check if the plugin has the required permissions - String permissions[] = pkgInfo.requestedPermissions; - if (permissions == null) { - Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission."); - continue; - } - boolean permissionOk = false; - for (String permit : permissions) { - if (PLUGIN_PERMISSION.equals(permit)) { - permissionOk = true; - break; - } - } - if (!permissionOk) { - Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission (2)."); - continue; - } - - // check to ensure the plugin is properly signed - Signature signatures[] = pkgInfo.signatures; - if (signatures == null) { - Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Not signed."); - continue; - } - - // determine the type of plugin from the manifest - if (serviceInfo.metaData == null) { - Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined"); - continue; - } - - String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE); - if (!TYPE_NATIVE.equals(pluginType)) { - Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType); - continue; - } - - try { - Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name); - - //TODO implement any requirements of the plugin class here! - boolean classFound = true; - - if (!classFound) { - Log.e(LOGTAG, "The plugin's class' " + serviceInfo.name + "' does not extend the appropriate class."); - continue; - } - - } catch (NameNotFoundException e) { - Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName); - continue; - } catch (ClassNotFoundException e) { - Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name); - continue; - } - - // if all checks have passed then make the plugin available - mPackageInfoCache.add(pkgInfo); - directories.add(directory); - } - } - - return directories.toArray(new String[directories.size()]); - } - - Class<?> getPluginClass(String packageName, String className) - throws NameNotFoundException, ClassNotFoundException { - Context pluginContext = this.mAppContext.createPackageContext(packageName, - Context.CONTEXT_INCLUDE_CODE | - Context.CONTEXT_IGNORE_SECURITY); - ClassLoader pluginCL = pluginContext.getClassLoader(); - return pluginCL.loadClass(className); - } - - // Returns true when the intent is going to be handled by gecko launch - boolean launch(Intent intent) - { - if (!checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched)) - return false; - - if (intent == null) - intent = getIntent(); - final Intent i = intent; - new Thread() { - public void run() { - try { - if (mLibLoadThread != null) - mLibLoadThread.join(); - } catch (InterruptedException ie) {} - - // Show the URL we are about to load, if the intent has one - if (Intent.ACTION_VIEW.equals(i.getAction())) { - surfaceView.mSplashURL = i.getDataString(); - } - surfaceView.drawSplashScreen(); - - // unpack files in the components directory - try { - unpackComponents(); - } catch (FileNotFoundException fnfe) { - Log.e(LOG_FILE_NAME, "error unpacking components", fnfe); - Looper.prepare(); - showErrorDialog(getString(R.string.error_loading_file)); - Looper.loop(); - return; - } catch (IOException ie) { - Log.e(LOG_FILE_NAME, "error unpacking components", ie); - String msg = ie.getMessage(); - Looper.prepare(); - if (msg != null && msg.equalsIgnoreCase("No space left on device")) - showErrorDialog(getString(R.string.no_space_to_start_error)); - else - showErrorDialog(getString(R.string.error_loading_file)); - Looper.loop(); - return; - } - - // and then fire us up - try { - String env = i.getStringExtra("env0"); - GeckoAppShell.runGecko(getApplication().getPackageResourcePath(), - i.getStringExtra("args"), - i.getDataString()); - } catch (Exception e) { - Log.e(LOG_FILE_NAME, "top level exception", e); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - pw.flush(); - GeckoAppShell.reportJavaCrash(sw.toString()); - } - } - }.start(); - return true; - } - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) - { - mAppContext = this; - mMainHandler = new Handler(); - - if (!sTryCatchAttached) { - sTryCatchAttached = true; - mMainHandler.post(new Runnable() { - public void run() { - try { - Looper.loop(); - } catch (Exception e) { - Log.e(LOG_FILE_NAME, "top level exception", e); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); - pw.flush(); - GeckoAppShell.reportJavaCrash(sw.toString()); - } - // resetting this is kinda pointless, but oh well - sTryCatchAttached = false; - } - }); - } - - SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); - String localeCode = settings.getString(getPackageName() + ".locale", ""); - if (localeCode != null && localeCode.length() > 0) - GeckoAppShell.setSelectedLocale(localeCode); - - Log.i(LOG_FILE_NAME, "create"); - super.onCreate(savedInstanceState); - - if (sGREDir == null) - sGREDir = new File(this.getApplicationInfo().dataDir); - - getWindow().setFlags(mFullscreen ? - WindowManager.LayoutParams.FLAG_FULLSCREEN : 0, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - - if (cameraView == null) { - cameraView = new SurfaceView(this); - cameraView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - } - - if (surfaceView == null) - surfaceView = new GeckoSurfaceView(this); - else - mainLayout.removeAllViews(); - - mainLayout = new AbsoluteLayout(this); - mainLayout.addView(surfaceView, - new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.MATCH_PARENT, // level 8 - AbsoluteLayout.LayoutParams.MATCH_PARENT, - 0, - 0)); - - setContentView(mainLayout, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, - ViewGroup.LayoutParams.FILL_PARENT)); - - mConnectivityFilter = new IntentFilter(); - mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mConnectivityReceiver = new GeckoConnectivityReceiver(); - - IntentFilter batteryFilter = new IntentFilter(); - batteryFilter.addAction(Intent.ACTION_BATTERY_CHANGED); - mBatteryReceiver = new GeckoBatteryManager(); - registerReceiver(mBatteryReceiver, batteryFilter); - - if (SmsManager.getInstance() != null) { - SmsManager.getInstance().start(); - } - - GeckoNetworkManager.getInstance().init(); - - if (!checkAndSetLaunchState(LaunchState.PreLaunch, - LaunchState.Launching)) - return; - - checkAndLaunchUpdate(); - mLibLoadThread = new Thread(new Runnable() { - public void run() { - // At some point while loading the gecko libs our default locale gets set - // so just save it to locale here and reset it as default after the join - Locale locale = Locale.getDefault(); - GeckoAppShell.loadGeckoLibs( - getApplication().getPackageResourcePath()); - Locale.setDefault(locale); - Resources res = getBaseContext().getResources(); - Configuration config = res.getConfiguration(); - config.locale = locale; - res.updateConfiguration(config, res.getDisplayMetrics()); - }}); - mLibLoadThread.start(); - } - - public void enableCameraView() { - // Some phones (eg. nexus S) need at least a 8x16 preview size - mainLayout.addView(cameraView, new AbsoluteLayout.LayoutParams(8, 16, 0, 0)); - } - - public void disableCameraView() { - mainLayout.removeView(cameraView); - } - - @Override - protected void onNewIntent(Intent intent) { - if (checkLaunchState(LaunchState.GeckoExiting)) { - // We're exiting and shouldn't try to do anything else just incase - // we're hung for some reason we'll force the process to exit - System.exit(0); - return; - } - final String action = intent.getAction(); - if (ACTION_DEBUG.equals(action) && - checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitForDebugger)) { - - mMainHandler.postDelayed(new Runnable() { - public void run() { - Log.i(LOG_FILE_NAME, "Launching from debug intent after 5s wait"); - setLaunchState(LaunchState.Launching); - launch(null); - } - }, 1000 * 5 /* 5 seconds */); - Log.i(LOG_FILE_NAME, "Intent : ACTION_DEBUG - waiting 5s before launching"); - return; - } - if (checkLaunchState(LaunchState.WaitForDebugger) || launch(intent)) - return; - - if (Intent.ACTION_MAIN.equals(action)) { - Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN"); - GeckoAppShell.sendEventToGecko(new GeckoEvent("")); - } - else if (Intent.ACTION_VIEW.equals(action)) { - String uri = intent.getDataString(); - GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); - Log.i(LOG_FILE_NAME,"onNewIntent: "+uri); - } - else if (ACTION_WEBAPP.equals(action)) { - String uri = intent.getStringExtra("args"); - GeckoAppShell.sendEventToGecko(new GeckoEvent(uri)); - Log.i(LOG_FILE_NAME,"Intent : WEBAPP - " + uri); - } - else if (ACTION_BOOKMARK.equals(action)) { - String args = intent.getStringExtra("args"); - GeckoAppShell.sendEventToGecko(new GeckoEvent(args)); - Log.i(LOG_FILE_NAME,"Intent : BOOKMARK - " + args); - } - } - - @Override - public void onPause() - { - Log.i(LOG_FILE_NAME, "pause"); - GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING)); - // The user is navigating away from this activity, but nothing - // has come to the foreground yet; for Gecko, we may want to - // stop repainting, for example. - - // Whatever we do here should be fast, because we're blocking - // the next activity from showing up until we finish. - - // onPause will be followed by either onResume or onStop. - super.onPause(); - - unregisterReceiver(mConnectivityReceiver); - GeckoNetworkManager.getInstance().stop(); - GeckoScreenOrientationListener.getInstance().stop(); - } - - @Override - public void onResume() - { - Log.i(LOG_FILE_NAME, "resume"); - if (checkLaunchState(LaunchState.GeckoRunning)) - GeckoAppShell.onResume(); - // After an onPause, the activity is back in the foreground. - // Undo whatever we did in onPause. - super.onResume(); - - // Just in case. Normally we start in onNewIntent - if (checkLaunchState(LaunchState.PreLaunch) || - checkLaunchState(LaunchState.Launching)) - onNewIntent(getIntent()); - - registerReceiver(mConnectivityReceiver, mConnectivityFilter); - GeckoNetworkManager.getInstance().start(); - GeckoScreenOrientationListener.getInstance().start(); - } - - @Override - public void onStop() - { - Log.i(LOG_FILE_NAME, "stop"); - // We're about to be stopped, potentially in preparation for - // being destroyed. We're killable after this point -- as I - // understand it, in extreme cases the process can be terminated - // without going through onDestroy. - // - // We might also get an onRestart after this; not sure what - // that would mean for Gecko if we were to kill it here. - // Instead, what we should do here is save prefs, session, - // etc., and generally mark the profile as 'clean', and then - // dirty it again if we get an onResume. - - GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING)); - super.onStop(); - GeckoAppShell.putChildInBackground(); - } - - @Override - public void onRestart() - { - Log.i(LOG_FILE_NAME, "restart"); - GeckoAppShell.putChildInForeground(); - super.onRestart(); - } - - @Override - public void onStart() - { - Log.i(LOG_FILE_NAME, "start"); - GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_START)); - super.onStart(); - } - - @Override - public void onDestroy() - { - Log.i(LOG_FILE_NAME, "destroy"); - - // Tell Gecko to shutting down; we'll end up calling System.exit() - // in onXreExit. - if (isFinishing()) - GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN)); - - if (SmsManager.getInstance() != null) { - SmsManager.getInstance().stop(); - if (isFinishing()) - SmsManager.getInstance().shutdown(); - } - - GeckoNetworkManager.getInstance().stop(); - GeckoScreenOrientationListener.getInstance().stop(); - - super.onDestroy(); - - unregisterReceiver(mBatteryReceiver); - } - - @Override - public void onConfigurationChanged(android.content.res.Configuration newConfig) - { - Log.i(LOG_FILE_NAME, "configuration changed"); - // nothing, just ignore - super.onConfigurationChanged(newConfig); - } - - @Override - public void onLowMemory() - { - Log.e(LOG_FILE_NAME, "low memory"); - if (checkLaunchState(LaunchState.GeckoRunning)) - GeckoAppShell.onLowMemory(); - super.onLowMemory(); - } - - abstract public String getPackageName(); - abstract public String getContentProcessName(); - - protected void unpackComponents() - throws IOException, FileNotFoundException - { - File applicationPackage = new File(getApplication().getPackageResourcePath()); - File componentsDir = new File(sGREDir, "components"); - if (componentsDir.lastModified() == applicationPackage.lastModified()) - return; - - componentsDir.mkdir(); - componentsDir.setLastModified(applicationPackage.lastModified()); - - GeckoAppShell.killAnyZombies(); - - ZipFile zip = new ZipFile(applicationPackage); - - byte[] buf = new byte[32768]; - try { - if (unpackFile(zip, buf, null, "removed-files")) - removeFiles(); - } catch (Exception ex) { - // This file may not be there, so just log any errors and move on - Log.w(LOG_FILE_NAME, "error removing files", ex); - } - - // copy any .xpi file into an extensions/ directory - Enumeration<? extends ZipEntry> zipEntries = zip.entries(); - while (zipEntries.hasMoreElements()) { - ZipEntry entry = zipEntries.nextElement(); - if (entry.getName().startsWith("extensions/") && entry.getName().endsWith(".xpi")) { - Log.i("GeckoAppJava", "installing extension : " + entry.getName()); - unpackFile(zip, buf, entry, entry.getName()); - } - } - } - - void removeFiles() throws IOException { - BufferedReader reader = new BufferedReader( - new FileReader(new File(sGREDir, "removed-files"))); - try { - for (String removedFileName = reader.readLine(); - removedFileName != null; removedFileName = reader.readLine()) { - File removedFile = new File(sGREDir, removedFileName); - if (removedFile.exists()) - removedFile.delete(); - } - } finally { - reader.close(); - } - - } - - private boolean unpackFile(ZipFile zip, byte[] buf, ZipEntry fileEntry, - String name) - throws IOException, FileNotFoundException - { - if (fileEntry == null) - fileEntry = zip.getEntry(name); - if (fileEntry == null) - throw new FileNotFoundException("Can't find " + name + " in " + - zip.getName()); - - File outFile = new File(sGREDir, name); - if (outFile.lastModified() == fileEntry.getTime() && - outFile.length() == fileEntry.getSize()) - return false; - - File dir = outFile.getParentFile(); - if (!dir.exists()) - dir.mkdirs(); - - InputStream fileStream; - fileStream = zip.getInputStream(fileEntry); - - OutputStream outStream = new FileOutputStream(outFile); - - while (fileStream.available() > 0) { - int read = fileStream.read(buf, 0, buf.length); - outStream.write(buf, 0, read); - } - - fileStream.close(); - outStream.close(); - outFile.setLastModified(fileEntry.getTime()); - return true; - } - - public void addEnvToIntent(Intent intent) { - Map<String,String> envMap = System.getenv(); - Set<Map.Entry<String,String>> envSet = envMap.entrySet(); - Iterator<Map.Entry<String,String>> envIter = envSet.iterator(); - int c = 0; - while (envIter.hasNext()) { - Map.Entry<String,String> entry = envIter.next(); - intent.putExtra("env" + c, entry.getKey() + "=" - + entry.getValue()); - c++; - } - } - - public void doRestart() { - try { - String action = "org.mozilla.gecko.restart"; - Intent intent = new Intent(action); - intent.setClassName(getPackageName(), - getPackageName() + ".Restarter"); - addEnvToIntent(intent); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - Log.i(LOG_FILE_NAME, intent.toString()); - GeckoAppShell.killAnyZombies(); - startActivity(intent); - } catch (Exception e) { - Log.i(LOG_FILE_NAME, "error doing restart", e); - } - finish(); - // Give the restart process time to start before we die - GeckoAppShell.waitForAnotherGeckoProc(); - } - - public void handleNotification(String action, String alertName, String alertCookie) { - GeckoAppShell.handleNotification(action, alertName, alertCookie); - } - - private void checkAndLaunchUpdate() { - Log.i(LOG_FILE_NAME, "Checking for an update"); - - int statusCode = 8; // UNEXPECTED_ERROR - File baseUpdateDir = null; - if (Build.VERSION.SDK_INT >= 8) - baseUpdateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); - else - baseUpdateDir = new File(Environment.getExternalStorageDirectory().getPath(), "download"); - - File updateDir = new File(new File(baseUpdateDir, "updates"),"0"); - - File updateFile = new File(updateDir, "update.apk"); - File statusFile = new File(updateDir, "update.status"); - - if (!statusFile.exists() || !readUpdateStatus(statusFile).equals("pending")) - return; - - if (!updateFile.exists()) - return; - - Log.i(LOG_FILE_NAME, "Update is available!"); - - // Launch APK - File updateFileToRun = new File(updateDir, getPackageName() + "-update.apk"); - try { - if (updateFile.renameTo(updateFileToRun)) { - String amCmd = "/system/bin/am start -a android.intent.action.VIEW " + - "-n com.android.packageinstaller/.PackageInstallerActivity -d file://" + - updateFileToRun.getPath(); - Log.i(LOG_FILE_NAME, amCmd); - Runtime.getRuntime().exec(amCmd); - statusCode = 0; // OK - } else { - Log.i(LOG_FILE_NAME, "Cannot rename the update file!"); - statusCode = 7; // WRITE_ERROR - } - } catch (Exception e) { - Log.i(LOG_FILE_NAME, "error launching installer to update", e); - } - - // Update the status file - String status = statusCode == 0 ? "succeeded\n" : "failed: "+ statusCode + "\n"; - - OutputStream outStream; - try { - byte[] buf = status.getBytes("UTF-8"); - outStream = new FileOutputStream(statusFile); - outStream.write(buf, 0, buf.length); - outStream.close(); - } catch (Exception e) { - Log.i(LOG_FILE_NAME, "error writing status file", e); - } - - if (statusCode == 0) - System.exit(0); - } - - private String readUpdateStatus(File statusFile) { - String status = ""; - try { - BufferedReader reader = new BufferedReader(new FileReader(statusFile)); - status = reader.readLine(); - reader.close(); - } catch (Exception e) { - Log.i(LOG_FILE_NAME, "error reading update status", e); - } - return status; - } - - static final int FILE_PICKER_REQUEST = 1; - - private SynchronousQueue<String> mFilePickerResult = new SynchronousQueue(); - public String showFilePicker(String aMimeType) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType(aMimeType); - GeckoApp.this. - startActivityForResult( - Intent.createChooser(intent, getString(R.string.choose_file)), - FILE_PICKER_REQUEST); - String filePickerResult = ""; - - try { - while (null == (filePickerResult = mFilePickerResult.poll(1, TimeUnit.MILLISECONDS))) { - Log.i("GeckoApp", "processing events from showFilePicker "); - GeckoAppShell.processNextNativeEvent(); - } - } catch (InterruptedException e) { - Log.i(LOG_FILE_NAME, "showing file picker ", e); - } - - return filePickerResult; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, - Intent data) { - String filePickerResult = ""; - if (data != null && resultCode == RESULT_OK) { - try { - ContentResolver cr = getContentResolver(); - Uri uri = data.getData(); - Cursor cursor = GeckoApp.mAppContext.getContentResolver().query( - uri, - new String[] { OpenableColumns.DISPLAY_NAME }, - null, - null, - null); - String name = null; - if (cursor != null) { - try { - if (cursor.moveToNext()) { - name = cursor.getString(0); - } - } finally { - cursor.close(); - } - } - String fileName = "tmp_"; - String fileExt = null; - int period; - if (name == null || (period = name.lastIndexOf('.')) == -1) { - String mimeType = cr.getType(uri); - fileExt = "." + GeckoAppShell.getExtensionFromMimeType(mimeType); - } else { - fileExt = name.substring(period); - fileName = name.substring(0, period); - } - File file = File.createTempFile(fileName, fileExt, sGREDir); - - FileOutputStream fos = new FileOutputStream(file); - InputStream is = cr.openInputStream(uri); - byte[] buf = new byte[4096]; - int len = is.read(buf); - while (len != -1) { - fos.write(buf, 0, len); - len = is.read(buf); - } - fos.close(); - filePickerResult = file.getAbsolutePath(); - }catch (Exception e) { - Log.e(LOG_FILE_NAME, "showing file picker", e); - } - } - try { - mFilePickerResult.put(filePickerResult); - } catch (InterruptedException e) { - Log.i(LOG_FILE_NAME, "error returning file picker result", e); - } - } -}
deleted file mode 100644 --- a/embedding/android/GeckoAppShell.java +++ /dev/null @@ -1,1806 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.io.*; -import java.lang.reflect.*; -import java.nio.*; -import java.nio.channels.*; -import java.text.*; -import java.util.*; -import java.util.zip.*; -import java.util.concurrent.*; - -import android.os.*; -import android.app.*; -import android.text.*; -import android.view.*; -import android.view.inputmethod.*; -import android.content.*; -import android.content.res.*; -import android.content.pm.*; -import android.graphics.*; -import android.widget.*; -import android.hardware.*; -import android.location.*; -import android.webkit.MimeTypeMap; -import android.media.MediaScannerConnection; -import android.media.MediaScannerConnection.MediaScannerConnectionClient; -import android.provider.Settings; - -import android.util.*; -import android.net.Uri; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -import android.graphics.drawable.*; -import android.graphics.Bitmap; - -import org.json.JSONArray; -import org.json.JSONObject; - -public class GeckoAppShell -{ - private static final String LOG_FILE_NAME = "GeckoAppShell"; - - // static members only - private GeckoAppShell() { } - - static private LinkedList<GeckoEvent> gPendingEvents = - new LinkedList<GeckoEvent>(); - - static private boolean gRestartScheduled = false; - - static private final Timer mIMETimer = new Timer(); - static private final HashMap<Integer, AlertNotification> - mAlertNotifications = new HashMap<Integer, AlertNotification>(); - - static private final int NOTIFY_IME_RESETINPUTSTATE = 0; - static private final int NOTIFY_IME_SETOPENSTATE = 1; - static private final int NOTIFY_IME_CANCELCOMPOSITION = 2; - static private final int NOTIFY_IME_FOCUSCHANGE = 3; - - static private File sCacheFile = null; - static private int sFreeSpace = -1; - - /* The Android-side API: API methods that Android calls */ - - // Initialization methods - public static native void nativeInit(); - public static native void nativeRun(String args); - - // helper methods - public static native void setSurfaceView(GeckoSurfaceView sv); - public static native void putenv(String map); - public static native void onResume(); - public static native void onLowMemory(); - public static native void callObserver(String observerKey, String topic, String data); - public static native void removeObserver(String observerKey); - public static native void loadGeckoLibsNative(String apkName); - public static native void loadSQLiteLibsNative(String apkName, boolean shouldExtract); - public static native void loadNSSLibsNative(String apkName, boolean shouldExtract); - public static native void onChangeNetworkLinkStatus(String status); - public static native void reportJavaCrash(String stack); - - public static native void processNextNativeEvent(); - - public static native void notifyBatteryChange(double aLevel, boolean aCharging, double aRemainingTime); - - public static native void notifySmsReceived(String aSender, String aBody, int aMessageClass, long aTimestamp); - public static native void notifySmsSent(int aId, String aReceiver, String aBody, long aTimestamp, int aRequestId); - public static native void notifySmsDelivery(int aId, int aDeliveryStatus, String aReceiver, String aBody, long aTimestamp); - public static native void notifySmsSendFailed(int aError, int aRequestId); - public static native void notifyGetSms(int aId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); - public static native void notifyGetSmsFailed(int aError, int aRequestId); - public static native void notifySmsDeleted(boolean aDeleted, int aRequestId); - public static native void notifySmsDeleteFailed(int aError, int aRequestId); - public static native void notifyNoMessageInList(int aRequestId); - public static native void notifyListCreated(int aListId, int aMessageId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); - public static native void notifyGotNextMessage(int aMessageId, int aDeliveryStatus, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId); - public static native void notifyReadingMessageListFailed(int aError, int aRequestId); - public static native void onSurfaceTextureFrameAvailable(Object surfaceTexture, int id); - - // A looper thread, accessed by GeckoAppShell.getHandler - private static class LooperThread extends Thread { - public SynchronousQueue<Handler> mHandlerQueue = - new SynchronousQueue<Handler>(); - - public void run() { - Looper.prepare(); - try { - mHandlerQueue.put(new Handler()); - } catch (InterruptedException ie) {} - Looper.loop(); - } - } - - private static class GeckoMediaScannerClient implements MediaScannerConnectionClient { - private String mFile = ""; - private String mMimeType = ""; - private MediaScannerConnection mScanner = null; - - public GeckoMediaScannerClient(Context aContext, String aFile, String aMimeType) { - mFile = aFile; - mMimeType = aMimeType; - mScanner = new MediaScannerConnection(aContext, this); - if (mScanner != null) - mScanner.connect(); - } - - public void onMediaScannerConnected() { - mScanner.scanFile(mFile, mMimeType); - } - - public void onScanCompleted(String path, Uri uri) { - if(path.equals(mFile)) { - mScanner.disconnect(); - mScanner = null; - } - } - } - - // Get a Handler for the main java thread - public static Handler getMainHandler() { - return GeckoApp.mAppContext.mMainHandler; - } - - private static Handler sHandler = null; - - // Get a Handler for a looper thread, or create one if it doesn't exist yet - public static Handler getHandler() { - if (sHandler == null) { - LooperThread lt = new LooperThread(); - lt.start(); - try { - sHandler = lt.mHandlerQueue.take(); - } catch (InterruptedException ie) {} - } - return sHandler; - } - - public static File getCacheDir() { - if (sCacheFile == null) - sCacheFile = GeckoApp.mAppContext.getCacheDir(); - return sCacheFile; - } - - public static long getFreeSpace() { - try { - if (sFreeSpace == -1) { - File cacheDir = getCacheDir(); - if (cacheDir != null) { - StatFs cacheStats = new StatFs(cacheDir.getPath()); - sFreeSpace = cacheStats.getFreeBlocks() * - cacheStats.getBlockSize(); - } else { - Log.i(LOG_FILE_NAME, "Unable to get cache dir"); - } - } - } catch (Exception e) { - Log.e(LOG_FILE_NAME, "exception while stating cache dir: ", e); - } - return sFreeSpace; - } - - static boolean moveFile(File inFile, File outFile) - { - Log.i(LOG_FILE_NAME, "moving " + inFile + " to " + outFile); - if (outFile.isDirectory()) - outFile = new File(outFile, inFile.getName()); - try { - if (inFile.renameTo(outFile)) - return true; - } catch (SecurityException se) { - Log.w(LOG_FILE_NAME, "error trying to rename file", se); - } - try { - long lastModified = inFile.lastModified(); - outFile.createNewFile(); - // so copy it instead - FileChannel inChannel = new FileInputStream(inFile).getChannel(); - FileChannel outChannel = new FileOutputStream(outFile).getChannel(); - long size = inChannel.size(); - long transferred = inChannel.transferTo(0, size, outChannel); - inChannel.close(); - outChannel.close(); - outFile.setLastModified(lastModified); - - if (transferred == size) - inFile.delete(); - else - return false; - } catch (Exception e) { - Log.e(LOG_FILE_NAME, "exception while moving file: ", e); - try { - outFile.delete(); - } catch (SecurityException se) { - Log.w(LOG_FILE_NAME, "error trying to delete file", se); - } - return false; - } - return true; - } - - static boolean moveDir(File from, File to) { - try { - to.mkdirs(); - if (from.renameTo(to)) - return true; - } catch (SecurityException se) { - Log.w(LOG_FILE_NAME, "error trying to rename file", se); - } - File[] files = from.listFiles(); - boolean retVal = true; - if (files == null) - return false; - try { - Iterator fileIterator = Arrays.asList(files).iterator(); - while (fileIterator.hasNext()) { - File file = (File)fileIterator.next(); - File dest = new File(to, file.getName()); - if (file.isDirectory()) - retVal = moveDir(file, dest) ? retVal : false; - else - retVal = moveFile(file, dest) ? retVal : false; - } - from.delete(); - } catch(Exception e) { - Log.e(LOG_FILE_NAME, "error trying to move file", e); - } - return retVal; - } - - // java-side stuff - public static void loadGeckoLibs(String apkName) { - // The package data lib directory isn't placed in ld.so's - // search path, so we have to manually load libraries that - // libxul will depend on. Not ideal. - System.loadLibrary("mozglue"); - GeckoApp geckoApp = GeckoApp.mAppContext; - String homeDir; - if (Build.VERSION.SDK_INT < 8 || - geckoApp.getApplication().getPackageResourcePath().startsWith("/data") || - geckoApp.getApplication().getPackageResourcePath().startsWith("/system")) { - File home = geckoApp.getFilesDir(); - homeDir = home.getPath(); - // handle the application being moved to phone from sdcard - File profileDir = new File(homeDir, "mozilla"); - File oldHome = new File("/data/data/" + - GeckoApp.mAppContext.getPackageName() + "/mozilla"); - if (oldHome.exists()) - moveDir(oldHome, profileDir); - if (Build.VERSION.SDK_INT >= 8) { - File extHome = geckoApp.getExternalFilesDir(null); - File extProf = new File (extHome, "mozilla"); - if (extHome != null && extProf != null && extProf.exists()) - moveDir(extProf, profileDir); - } - } else { - File home = geckoApp.getExternalFilesDir(null); - homeDir = home.getPath(); - // handle the application being moved to phone from sdcard - File profileDir = new File(homeDir, "mozilla"); - File oldHome = new File("/data/data/" + - GeckoApp.mAppContext.getPackageName() + "/mozilla"); - if (oldHome.exists()) - moveDir(oldHome, profileDir); - - File intHome = geckoApp.getFilesDir(); - File intProf = new File(intHome, "mozilla"); - if (intHome != null && intProf != null && intProf.exists()) - moveDir(intProf, profileDir); - } - try { - String[] dirs = GeckoApp.mAppContext.getPluginDirectories(); - StringBuffer pluginSearchPath = new StringBuffer(); - for (int i = 0; i < dirs.length; i++) { - Log.i("GeckoPlugins", "dir: " + dirs[i]); - pluginSearchPath.append(dirs[i]); - pluginSearchPath.append(":"); - } - GeckoAppShell.putenv("MOZ_PLUGIN_PATH="+pluginSearchPath); - } catch (Exception ex) { - Log.i("GeckoPlugins", "exception getting plugin dirs", ex); - } - - GeckoAppShell.putenv("HOME=" + homeDir); - GeckoAppShell.putenv("GRE_HOME=" + GeckoApp.sGREDir.getPath()); - Intent i = geckoApp.getIntent(); - String env = i.getStringExtra("env0"); - Log.i(LOG_FILE_NAME, "env0: "+ env); - for (int c = 1; env != null; c++) { - GeckoAppShell.putenv(env); - env = i.getStringExtra("env" + c); - Log.i(LOG_FILE_NAME, "env"+ c +": "+ env); - } - - File f = geckoApp.getDir("tmp", Context.MODE_WORLD_READABLE | - Context.MODE_WORLD_WRITEABLE ); - - if (!f.exists()) - f.mkdirs(); - - GeckoAppShell.putenv("TMPDIR=" + f.getPath()); - - f = Environment.getDownloadCacheDirectory(); - GeckoAppShell.putenv("EXTERNAL_STORAGE=" + f.getPath()); - - File cacheFile = getCacheDir(); - GeckoAppShell.putenv("MOZ_LINKER_CACHE=" + cacheFile.getPath()); - - // setup the app-specific cache path - f = geckoApp.getCacheDir(); - GeckoAppShell.putenv("CACHE_DIRECTORY=" + f.getPath()); - - // gingerbread introduces File.getUsableSpace(). We should use that. - long freeSpace = getFreeSpace(); - try { - File downloadDir = null; - File updatesDir = null; - if (Build.VERSION.SDK_INT >= 8) { - downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - updatesDir = GeckoApp.mAppContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); - } else { - updatesDir = downloadDir = new File(Environment.getExternalStorageDirectory().getPath(), "download"); - } - GeckoAppShell.putenv("DOWNLOADS_DIRECTORY=" + downloadDir.getPath()); - GeckoAppShell.putenv("UPDATES_DIRECTORY=" + updatesDir.getPath()); - } - catch (Exception e) { - Log.i(LOG_FILE_NAME, "No download directory has been found: " + e); - } - - putLocaleEnv(); - - boolean extractLibs = GeckoApp.ACTION_DEBUG.equals(i.getAction()); - if (!extractLibs) { - // remove any previously extracted libs - File[] files = cacheFile.listFiles(); - if (files != null) { - Iterator cacheFiles = Arrays.asList(files).iterator(); - while (cacheFiles.hasNext()) { - File libFile = (File)cacheFiles.next(); - if (libFile.getName().endsWith(".so")) - libFile.delete(); - } - } - } - loadSQLiteLibsNative(apkName, extractLibs); - loadNSSLibsNative(apkName, extractLibs); - loadGeckoLibsNative(apkName); - } - - private static void putLocaleEnv() { - GeckoAppShell.putenv("LANG=" + Locale.getDefault().toString()); - NumberFormat nf = NumberFormat.getInstance(); - if (nf instanceof DecimalFormat) { - DecimalFormat df = (DecimalFormat)nf; - DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); - - GeckoAppShell.putenv("LOCALE_DECIMAL_POINT=" + dfs.getDecimalSeparator()); - GeckoAppShell.putenv("LOCALE_THOUSANDS_SEP=" + dfs.getGroupingSeparator()); - GeckoAppShell.putenv("LOCALE_GROUPING=" + (char)df.getGroupingSize()); - } - } - - public static void runGecko(String apkPath, String args, String url) { - // run gecko -- it will spawn its own thread - GeckoAppShell.nativeInit(); - - // Tell Gecko where the target surface view is for rendering - GeckoAppShell.setSurfaceView(GeckoApp.surfaceView); - - // First argument is the .apk path - String combinedArgs = apkPath + " -greomni " + apkPath; - if (args != null) - combinedArgs += " " + args; - if (url != null) - combinedArgs += " " + url; - - // and go - GeckoAppShell.nativeRun(combinedArgs); - } - - private static void sendPendingEventsToGecko() { - try { - while (!gPendingEvents.isEmpty()) { - GeckoEvent e = gPendingEvents.removeFirst(); - notifyGeckoOfEvent(e); - } - } catch (NoSuchElementException e) {} - } - - public static void sendEventToGecko(GeckoEvent e) { - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) { - notifyGeckoOfEvent(e); - } else { - gPendingEvents.addLast(e); - } - } - - public static void sendEventToGeckoSync(GeckoEvent e) { - sendEventToGecko(e); - geckoEventSync(); - } - - // Tell the Gecko event loop that an event is available. - public static native void notifyGeckoOfEvent(GeckoEvent event); - - /* - * The Gecko-side API: API methods that Gecko calls - */ - public static void scheduleRedraw() { - // Redraw everything - scheduleRedraw(0, -1, -1, -1, -1); - } - - public static void scheduleRedraw(int nativeWindow, int x, int y, int w, int h) { - GeckoEvent e; - - if (x == -1) { - e = new GeckoEvent(GeckoEvent.DRAW, null); - } else { - e = new GeckoEvent(GeckoEvent.DRAW, new Rect(x, y, w, h)); - } - - e.mNativeWindow = nativeWindow; - - sendEventToGecko(e); - } - - /* Delay updating IME states (see bug 573800) */ - private static final class IMEStateUpdater extends TimerTask - { - static private IMEStateUpdater instance; - private boolean mEnable, mReset; - - static private IMEStateUpdater getInstance() { - if (instance == null) { - instance = new IMEStateUpdater(); - mIMETimer.schedule(instance, 200); - } - return instance; - } - - static public synchronized void enableIME() { - getInstance().mEnable = true; - } - - static public synchronized void resetIME() { - getInstance().mReset = true; - } - - public void run() { - synchronized(IMEStateUpdater.class) { - instance = null; - } - - InputMethodManager imm = (InputMethodManager) - GeckoApp.surfaceView.getContext().getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm == null) - return; - - if (mReset) - imm.restartInput(GeckoApp.surfaceView); - - if (!mEnable) - return; - - int state = GeckoApp.surfaceView.mIMEState; - if (state != GeckoSurfaceView.IME_STATE_DISABLED && - state != GeckoSurfaceView.IME_STATE_PLUGIN) - imm.showSoftInput(GeckoApp.surfaceView, 0); - else - imm.hideSoftInputFromWindow( - GeckoApp.surfaceView.getWindowToken(), 0); - } - } - - public static void notifyIME(int type, int state) { - if (GeckoApp.surfaceView == null) - return; - - switch (type) { - case NOTIFY_IME_RESETINPUTSTATE: - // Composition event is already fired from widget. - // So reset IME flags. - GeckoApp.surfaceView.inputConnection.reset(); - - // Don't use IMEStateUpdater for reset. - // Because IME may not work showSoftInput() - // after calling restartInput() immediately. - // So we have to call showSoftInput() delay. - InputMethodManager imm = (InputMethodManager) - GeckoApp.surfaceView.getContext().getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm == null) { - // no way to reset IME status directly - IMEStateUpdater.resetIME(); - } else { - imm.restartInput(GeckoApp.surfaceView); - } - - // keep current enabled state - IMEStateUpdater.enableIME(); - break; - - case NOTIFY_IME_CANCELCOMPOSITION: - IMEStateUpdater.resetIME(); - break; - - case NOTIFY_IME_FOCUSCHANGE: - IMEStateUpdater.resetIME(); - break; - } - } - - public static void notifyIMEEnabled(int state, String typeHint, String modeHint, - String actionHint, boolean landscapeFS) - { - if (GeckoApp.surfaceView == null) - return; - - /* When IME is 'disabled', IME processing is disabled. - In addition, the IME UI is hidden */ - GeckoApp.surfaceView.mIMEState = state; - GeckoApp.surfaceView.mIMETypeHint = typeHint; - GeckoApp.surfaceView.mIMEModeHint = modeHint; - GeckoApp.surfaceView.mIMEActionHint = actionHint; - GeckoApp.surfaceView.mIMELandscapeFS = landscapeFS; - IMEStateUpdater.enableIME(); - } - - public static void notifyIMEChange(String text, int start, int end, int newEnd) { - if (GeckoApp.surfaceView == null || - GeckoApp.surfaceView.inputConnection == null) - return; - - InputMethodManager imm = (InputMethodManager) - GeckoApp.surfaceView.getContext().getSystemService( - Context.INPUT_METHOD_SERVICE); - if (imm == null) - return; - - // Log.d("GeckoAppJava", String.format("IME: notifyIMEChange: t=%s s=%d ne=%d oe=%d", - // text, start, newEnd, end)); - - if (newEnd < 0) - GeckoApp.surfaceView.inputConnection.notifySelectionChange( - imm, start, end); - else - GeckoApp.surfaceView.inputConnection.notifyTextChange( - imm, text, start, end, newEnd); - } - - // these 2 stubs are never called in XUL Fennec, but we need them so that - // the JNI code shared between XUL and Native Fennec doesn't die. - public static void notifyScreenShot(final ByteBuffer data, final int tabId, - final int left, final int top, - final int right, final int bottom, - final int bufferWidth, final int bufferHeight, final int token) { - } - - public static void notifyPaintedRect(float top, float left, float bottom, float right) { - } - - private static CountDownLatch sGeckoPendingAcks = null; - - // Block the current thread until the Gecko event loop is caught up - synchronized public static void geckoEventSync() { - sGeckoPendingAcks = new CountDownLatch(1); - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.GECKO_EVENT_SYNC)); - while (sGeckoPendingAcks.getCount() != 0) { - try { - sGeckoPendingAcks.await(); - } catch (InterruptedException e) {} - } - sGeckoPendingAcks = null; - } - - // Signal the Java thread that it's time to wake up - public static void acknowledgeEventSync() { - CountDownLatch tmp = sGeckoPendingAcks; - if (tmp != null) - tmp.countDown(); - } - - static Sensor gAccelerometerSensor = null; - static Sensor gOrientationSensor = null; - - public static void enableDeviceMotion(boolean enable) { - - SensorManager sm = (SensorManager) - GeckoApp.surfaceView.getContext().getSystemService(Context.SENSOR_SERVICE); - - if (gAccelerometerSensor == null || gOrientationSensor == null) { - gAccelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - gOrientationSensor = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION); - } - - if (enable) { - if (gAccelerometerSensor != null) - sm.registerListener(GeckoApp.surfaceView, gAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME); - if (gOrientationSensor != null) - sm.registerListener(GeckoApp.surfaceView, gOrientationSensor, SensorManager.SENSOR_DELAY_GAME); - } else { - if (gAccelerometerSensor != null) - sm.unregisterListener(GeckoApp.surfaceView, gAccelerometerSensor); - if (gOrientationSensor != null) - sm.unregisterListener(GeckoApp.surfaceView, gOrientationSensor); - } - } - - public static void enableLocation(final boolean enable) { - - getMainHandler().post(new Runnable() { - public void run() { - GeckoSurfaceView view = GeckoApp.surfaceView; - LocationManager lm = (LocationManager) - view.getContext().getSystemService(Context.LOCATION_SERVICE); - - if (enable) { - Criteria crit = new Criteria(); - crit.setAccuracy(Criteria.ACCURACY_FINE); - String provider = lm.getBestProvider(crit, true); - if (provider == null) - return; - - Looper l = Looper.getMainLooper(); - Location loc = lm.getLastKnownLocation(provider); - if (loc != null) { - view.onLocationChanged(loc); - } - lm.requestLocationUpdates(provider, 100, (float).5, view, l); - } else { - lm.removeUpdates(view); - } - } - }); - } - - public static void enableLocationHighAccuracy(final boolean enable) { - // unsupported - } - - /* - * Keep these values consistent with |SensorType| in Hal.h - */ - private static final int SENSOR_ORIENTATION = 1; - private static final int SENSOR_ACCELERATION = 2; - private static final int SENSOR_PROXIMITY = 3; - - private static Sensor gProximitySensor = null; - - public static void enableSensor(int aSensortype) { - SensorManager sm = (SensorManager) - GeckoApp.surfaceView.getContext(). - getSystemService(Context.SENSOR_SERVICE); - - switch(aSensortype) { - case SENSOR_PROXIMITY: - if(gProximitySensor == null) - gProximitySensor = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY); - sm.registerListener(GeckoApp.surfaceView, gProximitySensor, - SensorManager.SENSOR_DELAY_GAME); - break; - } - } - - public static void disableSensor(int aSensortype) { - SensorManager sm = (SensorManager) - GeckoApp.surfaceView.getContext(). - getSystemService(Context.SENSOR_SERVICE); - - switch(aSensortype) { - case SENSOR_PROXIMITY: - sm.unregisterListener(GeckoApp.surfaceView, gProximitySensor); - break; - } - } - - public static void moveTaskToBack() { - GeckoApp.mAppContext.moveTaskToBack(true); - } - - public static void returnIMEQueryResult(String result, int selectionStart, int selectionLength) { - GeckoApp.surfaceView.inputConnection.mSelectionStart = selectionStart; - GeckoApp.surfaceView.inputConnection.mSelectionLength = selectionLength; - try { - GeckoApp.surfaceView.inputConnection.mQueryResult.put(result); - } catch (InterruptedException e) { - } - } - - static void onAppShellReady() - { - // mLaunchState can only be Launched at this point - GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoRunning); - sendPendingEventsToGecko(); - } - - static void onXreExit() { - // mLaunchState can only be Launched or GeckoRunning at this point - GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoExiting); - Log.i("GeckoAppJava", "XRE exited"); - if (gRestartScheduled) { - GeckoApp.mAppContext.doRestart(); - } else { - Log.i("GeckoAppJava", "we're done, good bye"); - GeckoApp.mAppContext.finish(); - } - System.exit(0); - } - static void scheduleRestart() { - Log.i("GeckoAppJava", "scheduling restart"); - gRestartScheduled = true; - } - - // "Installs" an application by creating a shortcut - static void createShortcut(String aTitle, String aURI, String aIconData, String aType) { - Log.w("GeckoAppJava", "createShortcut for " + aURI + " [" + aTitle + "] > " + aType); - - // the intent to be launched by the shortcut - Intent shortcutIntent = new Intent(); - if (aType.equalsIgnoreCase("webapp")) { - shortcutIntent.setAction("org.mozilla.gecko.WEBAPP"); - shortcutIntent.putExtra("args", "--webapp=" + aURI); - } else { - shortcutIntent.setAction("org.mozilla.gecko.BOOKMARK"); - shortcutIntent.putExtra("args", "--url=" + aURI); - } - shortcutIntent.setClassName(GeckoApp.mAppContext, - GeckoApp.mAppContext.getPackageName() + ".App"); - - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aTitle); - byte[] raw = Base64.decode(aIconData.substring(22), Base64.DEFAULT); - Bitmap bitmap = BitmapFactory.decodeByteArray(raw, 0, raw.length); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap); - intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); - GeckoApp.mAppContext.sendBroadcast(intent); - } - - static String[] getHandlersForMimeType(String aMimeType, String aAction) { - Intent intent = getIntentForActionString(aAction); - if (aMimeType != null && aMimeType.length() > 0) - intent.setType(aMimeType); - return getHandlersForIntent(intent); - } - - static String[] getHandlersForURL(String aURL, String aAction) { - // aURL may contain the whole URL or just the protocol - Uri uri = aURL.indexOf(':') >= 0 ? Uri.parse(aURL) : new Uri.Builder().scheme(aURL).build(); - Intent intent = getIntentForActionString(aAction); - intent.setData(uri); - return getHandlersForIntent(intent); - } - - static String[] getHandlersForIntent(Intent intent) { - PackageManager pm = - GeckoApp.surfaceView.getContext().getPackageManager(); - List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); - int numAttr = 4; - String[] ret = new String[list.size() * numAttr]; - for (int i = 0; i < list.size(); i++) { - ResolveInfo resolveInfo = list.get(i); - ret[i * numAttr] = resolveInfo.loadLabel(pm).toString(); - if (resolveInfo.isDefault) - ret[i * numAttr + 1] = "default"; - else - ret[i * numAttr + 1] = ""; - ret[i * numAttr + 2] = resolveInfo.activityInfo.applicationInfo.packageName; - ret[i * numAttr + 3] = resolveInfo.activityInfo.name; - } - return ret; - } - - static Intent getIntentForActionString(String aAction) { - // Default to the view action if no other action as been specified. - if (aAction != null && aAction.length() > 0) - return new Intent(aAction); - else - return new Intent(Intent.ACTION_VIEW); - } - - static String getExtensionFromMimeType(String aMimeType) { - return MimeTypeMap.getSingleton().getExtensionFromMimeType(aMimeType); - } - - static String getMimeTypeFromExtensions(String aFileExt) { - MimeTypeMap mtm = MimeTypeMap.getSingleton(); - StringTokenizer st = new StringTokenizer(aFileExt, "., "); - String type = null; - String subType = null; - while (st.hasMoreElements()) { - String ext = st.nextToken(); - String mt = mtm.getMimeTypeFromExtension(ext); - if (mt == null) - continue; - int slash = mt.indexOf('/'); - String tmpType = mt.substring(0, slash); - if (!tmpType.equalsIgnoreCase(type)) - type = type == null ? tmpType : "*"; - String tmpSubType = mt.substring(slash + 1); - if (!tmpSubType.equalsIgnoreCase(subType)) - subType = subType == null ? tmpSubType : "*"; - } - if (type == null) - type = "*"; - if (subType == null) - subType = "*"; - return type + "/" + subType; - } - - static boolean openUriExternal(String aUriSpec, String aMimeType, String aPackageName, - String aClassName, String aAction, String aTitle) { - Intent intent = getIntentForActionString(aAction); - if (aAction.equalsIgnoreCase(Intent.ACTION_SEND)) { - intent.putExtra(Intent.EXTRA_TEXT, aUriSpec); - intent.putExtra(Intent.EXTRA_SUBJECT, aTitle); - if (aMimeType != null && aMimeType.length() > 0) - intent.setType(aMimeType); - } else if (aMimeType.length() > 0) { - intent.setDataAndType(Uri.parse(aUriSpec), aMimeType); - } else { - Uri uri = Uri.parse(aUriSpec); - if ("vnd.youtube".equals(uri.getScheme())) { - // Special case youtube to fallback to our own player - String[] handlers = getHandlersForURL(aUriSpec, aAction); - if (handlers.length == 0) { - intent = new Intent(VideoPlayer.VIDEO_ACTION); - intent.setClassName(GeckoApp.mAppContext.getPackageName(), - "org.mozilla.gecko.VideoPlayer"); - intent.setData(uri); - GeckoApp.mAppContext.startActivity(intent); - return true; - } - } - if ("sms".equals(uri.getScheme())) { - // Have a apecial handling for the SMS, as the message body - // is not extracted from the URI automatically - final String query = uri.getEncodedQuery(); - if (query != null && query.length() > 0) { - final String[] fields = query.split("&"); - boolean foundBody = false; - String resultQuery = ""; - for (int i = 0; i < fields.length; i++) { - final String field = fields[i]; - if (field.length() > 5 && "body=".equals(field.substring(0, 5))) { - final String body = Uri.decode(field.substring(5)); - intent.putExtra("sms_body", body); - foundBody = true; - } - else { - resultQuery = resultQuery.concat(resultQuery.length() > 0 ? "&" + field : field); - } - } - if (foundBody) { - // Put the query without the body field back into the URI - final String prefix = aUriSpec.substring(0, aUriSpec.indexOf('?')); - uri = Uri.parse(resultQuery.length() > 0 ? prefix + "?" + resultQuery : prefix); - } - } - } - intent.setData(uri); - } - if (aPackageName.length() > 0 && aClassName.length() > 0) - intent.setClassName(aPackageName, aClassName); - - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - try { - GeckoApp.surfaceView.getContext().startActivity(intent); - return true; - } catch(ActivityNotFoundException e) { - return false; - } - } - - static SynchronousQueue<String> sClipboardQueue = - new SynchronousQueue<String>(); - - // On some devices, access to the clipboard service needs to happen - // on a thread with a looper, so dispatch this to our looper thread - // Note: the main looper won't work because it may be blocked on the - // gecko thread, which is most likely this thread - static String getClipboardText() { - getHandler().post(new Runnable() { - public void run() { - Context context = GeckoApp.surfaceView.getContext(); - String text = null; - if (android.os.Build.VERSION.SDK_INT >= 11) { - android.content.ClipboardManager cm = (android.content.ClipboardManager) - context.getSystemService(Context.CLIPBOARD_SERVICE); - if (cm.hasPrimaryClip()) { - ClipData clip = cm.getPrimaryClip(); - if (clip != null) { - ClipData.Item item = clip.getItemAt(0); - text = item.coerceToText(context).toString(); - } - } - } else { - android.text.ClipboardManager cm = (android.text.ClipboardManager) - context.getSystemService(Context.CLIPBOARD_SERVICE); - if (cm.hasText()) - text = cm.getText().toString(); - } - try { - sClipboardQueue.put(text != null ? text : ""); - } catch (InterruptedException ie) {} - }}); - try { - String ret = sClipboardQueue.take(); - return ret == "" ? null : ret; - } catch (InterruptedException ie) {} - return null; - } - - static void setClipboardText(final String text) { - getHandler().post(new Runnable() { - public void run() { - Context context = GeckoApp.surfaceView.getContext(); - if (android.os.Build.VERSION.SDK_INT >= 11) { - android.content.ClipboardManager cm = (android.content.ClipboardManager) - context.getSystemService(Context.CLIPBOARD_SERVICE); - cm.setPrimaryClip(ClipData.newPlainText("Text", text)); - } else { - android.text.ClipboardManager cm = (android.text.ClipboardManager) - context.getSystemService(Context.CLIPBOARD_SERVICE); - cm.setText(text); - } - }}); - } - - public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText, - String aAlertCookie, String aAlertName) { - Log.i("GeckoAppJava", "GeckoAppShell.showAlertNotification\n" + - "- image = '" + aImageUrl + "'\n" + - "- title = '" + aAlertTitle + "'\n" + - "- text = '" + aAlertText +"'\n" + - "- cookie = '" + aAlertCookie +"'\n" + - "- name = '" + aAlertName + "'"); - - int icon = R.drawable.icon; // Just use the app icon by default - - Uri imageUri = Uri.parse(aImageUrl); - String scheme = imageUri.getScheme(); - if ("drawable".equals(scheme)) { - String resource = imageUri.getSchemeSpecificPart(); - resource = resource.substring(resource.lastIndexOf('/') + 1); - try { - Class drawableClass = R.drawable.class; - Field f = drawableClass.getField(resource); - icon = f.getInt(null); - } catch (Exception e) {} // just means the resource doesn't exist - imageUri = null; - } - - int notificationID = aAlertName.hashCode(); - - // Remove the old notification with the same ID, if any - removeNotification(notificationID); - - AlertNotification notification = - new AlertNotification(GeckoApp.mAppContext,notificationID, icon, - aAlertTitle, aAlertText, - System.currentTimeMillis()); - - // The intent to launch when the user clicks the expanded notification - Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CLICK); - notificationIntent.setClassName(GeckoApp.mAppContext, - GeckoApp.mAppContext.getPackageName() + ".NotificationHandler"); - - // Put the strings into the intent as an URI "alert:<name>#<cookie>" - Uri dataUri = Uri.fromParts("alert", aAlertName, aAlertCookie); - notificationIntent.setData(dataUri); - - PendingIntent contentIntent = PendingIntent.getBroadcast(GeckoApp.mAppContext, 0, notificationIntent, 0); - notification.setLatestEventInfo(GeckoApp.mAppContext, aAlertTitle, aAlertText, contentIntent); - notification.setCustomIcon(imageUri); - // The intent to execute when the status entry is deleted by the user with the "Clear All Notifications" button - Intent clearNotificationIntent = new Intent(GeckoApp.ACTION_ALERT_CLEAR); - clearNotificationIntent.setClassName(GeckoApp.mAppContext, - GeckoApp.mAppContext.getPackageName() + ".NotificationHandler"); - clearNotificationIntent.setData(dataUri); - notification.deleteIntent = PendingIntent.getBroadcast(GeckoApp.mAppContext, 0, clearNotificationIntent, 0); - - mAlertNotifications.put(notificationID, notification); - - notification.show(); - - Log.i("GeckoAppJava", "Created notification ID " + notificationID); - } - - public static void alertsProgressListener_OnProgress(String aAlertName, long aProgress, long aProgressMax, String aAlertText) { - Log.i("GeckoAppJava", "GeckoAppShell.alertsProgressListener_OnProgress\n" + - "- name = '" + aAlertName +"', " + - "progress = " + aProgress +" / " + aProgressMax + ", text = '" + aAlertText + "'"); - - int notificationID = aAlertName.hashCode(); - AlertNotification notification = mAlertNotifications.get(notificationID); - if (notification != null) - notification.updateProgress(aAlertText, aProgress, aProgressMax); - - if (aProgress == aProgressMax) { - // Hide the notification at 100% - removeObserver(aAlertName); - removeNotification(notificationID); - } - } - - public static void alertsProgressListener_OnCancel(String aAlertName) { - Log.i("GeckoAppJava", "GeckoAppShell.alertsProgressListener_OnCancel('" + aAlertName + "'"); - - removeObserver(aAlertName); - - int notificationID = aAlertName.hashCode(); - removeNotification(notificationID); - } - - public static void handleNotification(String aAction, String aAlertName, String aAlertCookie) { - int notificationID = aAlertName.hashCode(); - - if (GeckoApp.ACTION_ALERT_CLICK.equals(aAction)) { - Log.i("GeckoAppJava", "GeckoAppShell.handleNotification: callObserver(alertclickcallback)"); - callObserver(aAlertName, "alertclickcallback", aAlertCookie); - - AlertNotification notification = mAlertNotifications.get(notificationID); - if (notification != null && notification.isProgressStyle()) { - // When clicked, keep the notification, if it displays a progress - return; - } - } - - callObserver(aAlertName, "alertfinished", aAlertCookie); - - removeObserver(aAlertName); - - removeNotification(notificationID); - } - - private static void removeNotification(int notificationID) { - mAlertNotifications.remove(notificationID); - - NotificationManager notificationManager = (NotificationManager) - GeckoApp.mAppContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(notificationID); - } - - public static int getDpi() { - DisplayMetrics metrics = new DisplayMetrics(); - GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - return metrics.densityDpi; - } - - public static void setFullScreen(boolean fullscreen) { - GeckoApp.mFullscreen = fullscreen; - - // force a reconfiguration to hide/show the system bar - GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER); - } - - public static String showFilePickerForExtensions(String aExtensions) { - return GeckoApp.mAppContext. - showFilePicker(getMimeTypeFromExtensions(aExtensions)); - } - - public static String showFilePickerForMimeType(String aMimeType) { - return GeckoApp.mAppContext.showFilePicker(aMimeType); - } - - public static void performHapticFeedback(boolean aIsLongPress) { - GeckoApp.surfaceView. - performHapticFeedback(aIsLongPress ? - HapticFeedbackConstants.LONG_PRESS : - HapticFeedbackConstants.VIRTUAL_KEY); - } - - private static Vibrator vibrator() { - return (Vibrator) GeckoApp.surfaceView.getContext().getSystemService(Context.VIBRATOR_SERVICE); - } - - public static void vibrate(long milliseconds) { - vibrator().vibrate(milliseconds); - } - - public static void vibrate(long[] pattern, int repeat) { - vibrator().vibrate(pattern, repeat); - } - - public static void cancelVibrate() { - vibrator().cancel(); - } - - public static void showInputMethodPicker() { - InputMethodManager imm = (InputMethodManager) GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showInputMethodPicker(); - } - - public static void hideProgressDialog() { - GeckoApp.surfaceView.mShowingSplashScreen = false; - } - - public static void setKeepScreenOn(final boolean on) { - GeckoApp.mAppContext.runOnUiThread(new Runnable() { - public void run() { - GeckoApp.surfaceView.setKeepScreenOn(on); - } - }); - } - - public static boolean isNetworkLinkUp() { - ConnectivityManager cm = (ConnectivityManager) - GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = cm.getActiveNetworkInfo(); - if (info == null || !info.isConnected()) - return false; - return true; - } - - public static boolean isNetworkLinkKnown() { - ConnectivityManager cm = (ConnectivityManager) - GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE); - if (cm.getActiveNetworkInfo() == null) - return false; - return true; - } - - public static void setSelectedLocale(String localeCode) { - SharedPreferences settings = - GeckoApp.mAppContext.getPreferences(Activity.MODE_PRIVATE); - settings.edit().putString(GeckoApp.mAppContext.getPackageName() + ".locale", - localeCode).commit(); - Locale locale; - int index; - if ((index = localeCode.indexOf('-')) != -1 || - (index = localeCode.indexOf('_')) != -1) { - String langCode = localeCode.substring(0, index); - String countryCode = localeCode.substring(index + 1); - locale = new Locale(langCode, countryCode); - } else { - locale = new Locale(localeCode); - } - Locale.setDefault(locale); - - Resources res = GeckoApp.mAppContext.getBaseContext().getResources(); - Configuration config = res.getConfiguration(); - config.locale = locale; - res.updateConfiguration(config, res.getDisplayMetrics()); - } - - public static int[] getSystemColors() { - // attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h - final int[] attrsAppearance = { - android.R.attr.textColor, - android.R.attr.textColorPrimary, - android.R.attr.textColorPrimaryInverse, - android.R.attr.textColorSecondary, - android.R.attr.textColorSecondaryInverse, - android.R.attr.textColorTertiary, - android.R.attr.textColorTertiaryInverse, - android.R.attr.textColorHighlight, - android.R.attr.colorForeground, - android.R.attr.colorBackground, - android.R.attr.panelColorForeground, - android.R.attr.panelColorBackground - }; - - int[] result = new int[attrsAppearance.length]; - - final ContextThemeWrapper contextThemeWrapper = - new ContextThemeWrapper(GeckoApp.mAppContext, android.R.style.TextAppearance); - - final TypedArray appearance = contextThemeWrapper.getTheme().obtainStyledAttributes(attrsAppearance); - - if (appearance != null) { - for (int i = 0; i < appearance.getIndexCount(); i++) { - int idx = appearance.getIndex(i); - int color = appearance.getColor(idx, 0); - result[idx] = color; - } - appearance.recycle(); - } - - return result; - } - - public static void putChildInBackground() { - try { - File cgroupFile = new File("/proc/" + android.os.Process.myPid() + "/cgroup"); - BufferedReader br = new BufferedReader(new FileReader(cgroupFile)); - String[] cpuLine = br.readLine().split("/"); - br.close(); - final String backgroundGroup = cpuLine.length == 2 ? cpuLine[1] : ""; - GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { - public boolean callback(int pid) { - if (pid != android.os.Process.myPid()) { - try { - FileOutputStream fos = new FileOutputStream( - new File("/dev/cpuctl/" + backgroundGroup +"/tasks")); - fos.write(new Integer(pid).toString().getBytes()); - fos.close(); - } catch(Exception e) { - Log.e(LOG_FILE_NAME, "error putting child in the background", e); - } - } - return true; - } - }; - EnumerateGeckoProcesses(visitor); - } catch (Exception e) { - Log.e("GeckoInputStream", "error reading cgroup", e); - } - } - - public static void putChildInForeground() { - GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { - public boolean callback(int pid) { - if (pid != android.os.Process.myPid()) { - try { - FileOutputStream fos = new FileOutputStream(new File("/dev/cpuctl/tasks")); - fos.write(new Integer(pid).toString().getBytes()); - fos.close(); - } catch(Exception e) { - Log.e(LOG_FILE_NAME, "error putting child in the foreground", e); - } - } - return true; - } - }; - EnumerateGeckoProcesses(visitor); - } - - public static void killAnyZombies() { - GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { - public boolean callback(int pid) { - if (pid != android.os.Process.myPid()) - android.os.Process.killProcess(pid); - return true; - } - }; - - EnumerateGeckoProcesses(visitor); - } - - public static boolean checkForGeckoProcs() { - - class GeckoPidCallback implements GeckoProcessesVisitor { - public boolean otherPidExist = false; - public boolean callback(int pid) { - if (pid != android.os.Process.myPid()) { - otherPidExist = true; - return false; - } - return true; - } - } - GeckoPidCallback visitor = new GeckoPidCallback(); - EnumerateGeckoProcesses(visitor); - return visitor.otherPidExist; - } - - interface GeckoProcessesVisitor{ - boolean callback(int pid); - } - - static int sPidColumn = -1; - static int sUserColumn = -1; - private static void EnumerateGeckoProcesses(GeckoProcessesVisitor visiter) { - - try { - - // run ps and parse its output - java.lang.Process ps = Runtime.getRuntime().exec("ps"); - BufferedReader in = new BufferedReader(new InputStreamReader(ps.getInputStream()), - 2048); - - String headerOutput = in.readLine(); - - // figure out the column offsets. We only care about the pid and user fields - if (sPidColumn == -1 || sUserColumn == -1) { - StringTokenizer st = new StringTokenizer(headerOutput); - - int tokenSoFar = 0; - while(st.hasMoreTokens()) { - String next = st.nextToken(); - if (next.equalsIgnoreCase("PID")) - sPidColumn = tokenSoFar; - else if (next.equalsIgnoreCase("USER")) - sUserColumn = tokenSoFar; - tokenSoFar++; - } - } - - // alright, the rest are process entries. - String psOutput = null; - while ((psOutput = in.readLine()) != null) { - String[] split = psOutput.split("\\s+"); - if (split.length <= sPidColumn || split.length <= sUserColumn) - continue; - int uid = android.os.Process.getUidForName(split[sUserColumn]); - if (uid == android.os.Process.myUid() && - !split[split.length - 1].equalsIgnoreCase("ps")) { - int pid = Integer.parseInt(split[sPidColumn]); - boolean keepGoing = visiter.callback(pid); - if (keepGoing == false) - break; - } - } - in.close(); - } - catch (Exception e) { - Log.i(LOG_FILE_NAME, "finding procs throws ", e); - } - } - - public static void waitForAnotherGeckoProc(){ - int countdown = 40; - while (!checkForGeckoProcs() && --countdown > 0) { - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException ie) {} - } - } - - public static void scanMedia(String aFile, String aMimeType) { - Context context = GeckoApp.surfaceView.getContext(); - GeckoMediaScannerClient client = new GeckoMediaScannerClient(context, aFile, aMimeType); - } - - public static byte[] getIconForExtension(String aExt, int iconSize) { - try { - if (iconSize <= 0) - iconSize = 16; - - if (aExt != null && aExt.length() > 1 && aExt.charAt(0) == '.') - aExt = aExt.substring(1); - - PackageManager pm = GeckoApp.surfaceView.getContext().getPackageManager(); - Drawable icon = getDrawableForExtension(pm, aExt); - if (icon == null) { - // Use a generic icon - icon = pm.getDefaultActivityIcon(); - } - - Bitmap bitmap = ((BitmapDrawable)icon).getBitmap(); - if (bitmap.getWidth() != iconSize || bitmap.getHeight() != iconSize) - bitmap = Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, true); - - ByteBuffer buf = ByteBuffer.allocate(iconSize * iconSize * 4); - bitmap.copyPixelsToBuffer(buf); - - return buf.array(); - } - catch (Exception e) { - Log.i(LOG_FILE_NAME, "getIconForExtension error: ", e); - return null; - } - } - - private static Drawable getDrawableForExtension(PackageManager pm, String aExt) { - Intent intent = new Intent(Intent.ACTION_VIEW); - MimeTypeMap mtm = MimeTypeMap.getSingleton(); - String mimeType = mtm.getMimeTypeFromExtension(aExt); - if (mimeType != null && mimeType.length() > 0) - intent.setType(mimeType); - else - return null; - - List<ResolveInfo> list = pm.queryIntentActivities(intent, 0); - if (list.size() == 0) - return null; - - ResolveInfo resolveInfo = list.get(0); - - if (resolveInfo == null) - return null; - - ActivityInfo activityInfo = resolveInfo.activityInfo; - - return activityInfo.loadIcon(pm); - } - - public static boolean getShowPasswordSetting() { - try { - int showPassword = - Settings.System.getInt(GeckoApp.mAppContext.getContentResolver(), - Settings.System.TEXT_SHOW_PASSWORD, 1); - return (showPassword > 0); - } - catch (Exception e) { - return true; - } - } - - public static void addPluginView(final View view, - final double x, final double y, - final double w, final double h) { - - Log.i("GeckoAppShell", "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h ) ; - - getMainHandler().post(new Runnable() { - public void run() { - AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams((int)w, - (int)h, - (int)x, - (int)y); - - if (GeckoApp.mainLayout.indexOfChild(view) == -1) { - view.setWillNotDraw(true); - GeckoApp.mainLayout.addView(view, lp); - } - else - { - try { - GeckoApp.mainLayout.updateViewLayout(view, lp); - } catch (IllegalArgumentException e) { - Log.i("updateViewLayout - IllegalArgumentException", "e:" + e); - // it can be the case where we - // get an update before the view - // is actually attached. - } - } - } - }); - } - - public static void removePluginView(final View view) { - Log.i("GeckoAppShell", "remove view:" + view); - getMainHandler().post(new Runnable() { - public void run() { - try { - GeckoApp.mainLayout.removeView(view); - } catch (Exception e) {} - } - }); - } - - public static Class<?> loadPluginClass(String className, String libName) { - Log.i("GeckoAppShell", "in loadPluginClass... attempting to access className, then libName....."); - Log.i("GeckoAppShell", "className: " + className); - Log.i("GeckoAppShell", "libName: " + libName); - - try { - String[] split = libName.split("/"); - String packageName = split[split.length - 3]; - Log.i("GeckoAppShell", "load \"" + className + "\" from \"" + packageName + - "\" for \"" + libName + "\""); - Context pluginContext = - GeckoApp.mAppContext.createPackageContext(packageName, - Context.CONTEXT_INCLUDE_CODE | - Context.CONTEXT_IGNORE_SECURITY); - ClassLoader pluginCL = pluginContext.getClassLoader(); - return pluginCL.loadClass(className); - } catch (java.lang.ClassNotFoundException cnfe) { - Log.i("GeckoAppShell", "class not found", cnfe); - } catch (android.content.pm.PackageManager.NameNotFoundException nnfe) { - Log.i("GeckoAppShell", "package not found", nnfe); - } - Log.e("GeckoAppShell", "couldn't find class"); - return null; - } - - public static SurfaceInfo getSurfaceInfo(SurfaceView sview) - { - Log.i("GeckoAppShell", "getSurfaceInfo " + sview); - if (sview == null) - return null; - - int format = -1; - try { - Field privateFormatField = SurfaceView.class.getDeclaredField("mFormat"); - privateFormatField.setAccessible(true); - format = privateFormatField.getInt(sview); - } catch (Exception e) { - Log.i("GeckoAppShell", "mFormat is not a field of sview: ", e); - } - - int n = 0; - if (format == PixelFormat.RGB_565) { - n = 2; - } else if (format == PixelFormat.RGBA_8888) { - n = 4; - } else { - Log.i("GeckoAppShell", "Unknown pixel format: " + format); - return null; - } - - SurfaceInfo info = new SurfaceInfo(); - - Rect r = sview.getHolder().getSurfaceFrame(); - info.width = r.right; - info.height = r.bottom; - info.format = format; - - return info; - } - - public static Class getSurfaceInfoClass() { - Log.i("GeckoAppShell", "class name: " + SurfaceInfo.class.getName()); - return SurfaceInfo.class; - } - - public static android.hardware.Camera sCamera = null; - - static native void cameraCallbackBridge(byte[] data); - - static int kPreferedFps = 25; - static byte[] sCameraBuffer = null; - - static int[] initCamera(String aContentType, int aCamera, int aWidth, int aHeight) { - Log.i("GeckoAppJava", "initCamera(" + aContentType + ", " + aWidth + "x" + aHeight + ") on thread " + Thread.currentThread().getId()); - - getMainHandler().post(new Runnable() { - public void run() { - try { - GeckoApp.mAppContext.enableCameraView(); - } catch (Exception e) {} - } - }); - - // [0] = 0|1 (failure/success) - // [1] = width - // [2] = height - // [3] = fps - int[] result = new int[4]; - result[0] = 0; - - if (Build.VERSION.SDK_INT >= 9) { - if (android.hardware.Camera.getNumberOfCameras() == 0) - return result; - } - - try { - // no front/back camera before API level 9 - if (Build.VERSION.SDK_INT >= 9) - sCamera = android.hardware.Camera.open(aCamera); - else - sCamera = android.hardware.Camera.open(); - - android.hardware.Camera.Parameters params = sCamera.getParameters(); - params.setPreviewFormat(ImageFormat.NV21); - - // use the preview fps closest to 25 fps. - int fpsDelta = 1000; - try { - Iterator<Integer> it = params.getSupportedPreviewFrameRates().iterator(); - while (it.hasNext()) { - int nFps = it.next(); - if (Math.abs(nFps - kPreferedFps) < fpsDelta) { - fpsDelta = Math.abs(nFps - kPreferedFps); - params.setPreviewFrameRate(nFps); - } - } - } catch(Exception e) { - params.setPreviewFrameRate(kPreferedFps); - } - - // set up the closest preview size available - Iterator<android.hardware.Camera.Size> sit = params.getSupportedPreviewSizes().iterator(); - int sizeDelta = 10000000; - int bufferSize = 0; - while (sit.hasNext()) { - android.hardware.Camera.Size size = sit.next(); - if (Math.abs(size.width * size.height - aWidth * aHeight) < sizeDelta) { - sizeDelta = Math.abs(size.width * size.height - aWidth * aHeight); - params.setPreviewSize(size.width, size.height); - bufferSize = size.width * size.height; - } - } - - try { - sCamera.setPreviewDisplay(GeckoApp.cameraView.getHolder()); - } catch(IOException e) { - Log.e("GeckoAppJava", "Error setPreviewDisplay:", e); - } catch(RuntimeException e) { - Log.e("GeckoAppJava", "Error setPreviewDisplay:", e); - } - - sCamera.setParameters(params); - sCameraBuffer = new byte[(bufferSize * 12) / 8]; - sCamera.addCallbackBuffer(sCameraBuffer); - sCamera.setPreviewCallbackWithBuffer(new android.hardware.Camera.PreviewCallback() { - public void onPreviewFrame(byte[] data, android.hardware.Camera camera) { - cameraCallbackBridge(data); - if (sCamera != null) - sCamera.addCallbackBuffer(sCameraBuffer); - } - }); - sCamera.startPreview(); - params = sCamera.getParameters(); - Log.i("GeckoAppJava", "Camera: " + params.getPreviewSize().width + "x" + params.getPreviewSize().height + - " @ " + params.getPreviewFrameRate() + "fps. format is " + params.getPreviewFormat()); - result[0] = 1; - result[1] = params.getPreviewSize().width; - result[2] = params.getPreviewSize().height; - result[3] = params.getPreviewFrameRate(); - - Log.i("GeckoAppJava", "Camera preview started"); - } catch(RuntimeException e) { - Log.e("GeckoAppJava", "initCamera RuntimeException : ", e); - result[0] = result[1] = result[2] = result[3] = 0; - } - return result; - } - - static synchronized void closeCamera() { - Log.i("GeckoAppJava", "closeCamera() on thread " + Thread.currentThread().getId()); - getMainHandler().post(new Runnable() { - public void run() { - try { - GeckoApp.mAppContext.disableCameraView(); - } catch (Exception e) {} - } - }); - if (sCamera != null) { - sCamera.stopPreview(); - sCamera.release(); - sCamera = null; - sCameraBuffer = null; - } - } - - // unused - static void checkUriVisited(String uri) {} - // unused - static void markUriVisited(final String uri) {} - - /* - * Battery API related methods. - */ - public static void enableBatteryNotifications() { - GeckoBatteryManager.enableNotifications(); - } - - public static String handleGeckoMessage(String message) { - // { - // "type": "value", - // "event_specific": "value", - // ... - try { - JSONObject json = new JSONObject(message); - String type = json.getString("type"); - - if (type.equals("Gecko:Ready")) { - onAppShellReady(); - } - } catch (Exception e) { - Log.i(LOG_FILE_NAME, "handleGeckoMessage throws " + e); - } - - return ""; - } - - public static void disableBatteryNotifications() { - GeckoBatteryManager.disableNotifications(); - } - - public static double[] getCurrentBatteryInformation() { - return GeckoBatteryManager.getCurrentInformation(); - } - - /* - * WebSMS related methods. - */ - public static void sendMessage(String aNumber, String aMessage, int aRequestId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().send(aNumber, aMessage, aRequestId); - } - - public static void getMessage(int aMessageId, int aRequestId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().getMessage(aMessageId, aRequestId); - } - - public static void deleteMessage(int aMessageId, int aRequestId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().deleteMessage(aMessageId, aRequestId); - } - - public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().createMessageList(aStartDate, aEndDate, aNumbers, aNumbersCount, aDeliveryState, aReverse, aRequestId); - } - - public static void getNextMessageInList(int aListId, int aRequestId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().getNextMessageInList(aListId, aRequestId); - } - - public static void clearMessageList(int aListId) { - if (SmsManager.getInstance() == null) { - return; - } - - SmsManager.getInstance().clearMessageList(aListId); - } - - public static boolean isTablet() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - Configuration config = GeckoApp.mAppContext.getResources().getConfiguration(); - // xlarge is defined by android as screens larger than 960dp x 720dp - // and should include most devices ~7in and up. - // http://developer.android.com/guide/practices/screens_support.html - if ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE) { - return true; - } - } - return false; - } - - public static double[] getCurrentNetworkInformation() { - return GeckoNetworkManager.getInstance().getCurrentInformation(); - } - - public static void enableNetworkNotifications() { - GeckoNetworkManager.getInstance().enableNotifications(); - } - - public static void disableNetworkNotifications() { - GeckoNetworkManager.getInstance().disableNotifications(); - } - - // This is only used in Native Fennec. - public static void notifyDefaultPrevented(boolean defaultPrevented) { } - - public static short getScreenOrientation() { - return GeckoScreenOrientationListener.getInstance().getScreenOrientation(); - } - - public static void enableScreenOrientationNotifications() { - GeckoScreenOrientationListener.getInstance().enableNotifications(); - } - - public static void disableScreenOrientationNotifications() { - GeckoScreenOrientationListener.getInstance().disableNotifications(); - } - - public static void lockScreenOrientation(int aOrientation) { - GeckoScreenOrientationListener.getInstance().lockScreenOrientation(aOrientation); - } - - public static void unlockScreenOrientation() { - GeckoScreenOrientationListener.getInstance().unlockScreenOrientation(); - } - - static native void notifyFilePickerResult(String filePath, long id); - - /* Stubbed out because this is called from AndroidBridge for Native Fennec */ - public static void showFilePickerAsync(String aMimeType, long id) { - } - - public static void notifyWakeLockChanged(String topic, String state) { - } - - public static String getGfxInfoData() { - return null; - } - - public static void registerSurfaceTextureFrameListener(Object surfaceTexture, final int id) { - } - - public static void unregisterSurfaceTextureFrameListener(Object surfaceTexture) { - } -}
deleted file mode 100644 --- a/embedding/android/GeckoBatteryManager.java +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.lang.Math; -import java.util.Date; - -import android.util.Log; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import android.os.BatteryManager; - -public class GeckoBatteryManager - extends BroadcastReceiver -{ - // Those constants should be keep in sync with the ones in: - // dom/battery/Constants.h - private final static double kDefaultLevel = 1.0; - private final static boolean kDefaultCharging = true; - private final static double kDefaultRemainingTime = -1.0; - private final static double kUnknownRemainingTime = -1.0; - - private static Date sLastLevelChange = new Date(0); - private static boolean sNotificationsEnabled = false; - private static double sLevel = kDefaultLevel; - private static boolean sCharging = kDefaultCharging; - private static double sRemainingTime = kDefaultRemainingTime;; - - @Override - public void onReceive(Context context, Intent intent) { - if (!intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { - Log.e("GeckoBatteryManager", "Got an unexpected intent!"); - return; - } - - boolean previousCharging = isCharging(); - double previousLevel = getLevel(); - - if (intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false)) { - int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); - if (plugged == -1) { - sCharging = kDefaultCharging; - Log.e("GeckoBatteryManager", "Failed to get the plugged status!"); - } else { - // Likely, if plugged > 0, it's likely plugged and charging but the doc - // isn't clear about that. - sCharging = plugged != 0; - } - - if (sCharging != previousCharging) { - sRemainingTime = kUnknownRemainingTime; - // The new remaining time is going to take some time to show up but - // it's the best way to show a not too wrong value. - sLastLevelChange = new Date(0); - } - - // We need two doubles because sLevel is a double. - double current = (double)intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - double max = (double)intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - if (current == -1 || max == -1) { - Log.e("GeckoBatteryManager", "Failed to get battery level!"); - sLevel = kDefaultLevel; - } else { - sLevel = current / max; - } - - if (sLevel == 1.0 && sCharging) { - sRemainingTime = 0.0; - } else if (sLevel != previousLevel) { - // Estimate remaining time. - if (sLastLevelChange.getTime() != 0) { - Date currentTime = new Date(); - long dt = (currentTime.getTime() - sLastLevelChange.getTime()) / 1000; - double dLevel = sLevel - previousLevel; - - if (sCharging) { - if (dLevel < 0) { - Log.w("GeckoBatteryManager", "When charging, level should increase!"); - sRemainingTime = kUnknownRemainingTime; - } else { - sRemainingTime = Math.round(dt / dLevel * (1.0 - sLevel)); - } - } else { - if (dLevel > 0) { - Log.w("GeckoBatteryManager", "When discharging, level should decrease!"); - sRemainingTime = kUnknownRemainingTime; - } else { - sRemainingTime = Math.round(dt / -dLevel * sLevel); - } - } - - sLastLevelChange = currentTime; - } else { - // That's the first time we got an update, we can't do anything. - sLastLevelChange = new Date(); - } - } - } else { - sLevel = kDefaultLevel; - sCharging = kDefaultCharging; - sRemainingTime = kDefaultRemainingTime; - } - - /* - * We want to inform listeners if the following conditions are fulfilled: - * - we have at least one observer; - * - the charging state or the level has changed. - * - * Note: no need to check for a remaining time change given that it's only - * updated if there is a level change or a charging change. - * - * The idea is to prevent doing all the way to the DOM code in the child - * process to finally not send an event. - */ - if (sNotificationsEnabled && - (previousCharging != isCharging() || previousLevel != getLevel())) { - GeckoAppShell.notifyBatteryChange(getLevel(), isCharging(), getRemainingTime()); - } - } - - public static boolean isCharging() { - return sCharging; - } - - public static double getLevel() { - return sLevel; - } - - public static double getRemainingTime() { - return sRemainingTime; - } - - public static void enableNotifications() { - sNotificationsEnabled = true; - } - - public static void disableNotifications() { - sNotificationsEnabled = false; - } - - public static double[] getCurrentInformation() { - return new double[] { getLevel(), isCharging() ? 1.0 : 0.0, getRemainingTime() }; - } -}
deleted file mode 100644 --- a/embedding/android/GeckoConnectivityReceiver.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import android.content.*; -import android.net.*; - -public class GeckoConnectivityReceiver - extends BroadcastReceiver -{ - @Override - public void onReceive(Context context, Intent intent) { - String status; - ConnectivityManager cm = (ConnectivityManager) - context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = cm.getActiveNetworkInfo(); - if (info == null) - status = "unknown"; - else if (!info.isConnected()) - status = "down"; - else - status = "up"; - - if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) - GeckoAppShell.onChangeNetworkLinkStatus(status); - } -}
deleted file mode 100644 --- a/embedding/android/GeckoEvent.java +++ /dev/null @@ -1,400 +0,0 @@ -/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import android.os.*; -import android.app.*; -import android.view.*; -import android.content.*; -import android.graphics.*; -import android.widget.*; -import android.hardware.*; -import android.location.*; -import android.util.FloatMath; -import android.util.DisplayMetrics; -import java.nio.ByteBuffer; - -import android.util.Log; - -/* We're not allowed to hold on to most events given to us - * so we save the parts of the events we want to use in GeckoEvent. - * Fields have different meanings depending on the event type. - */ - -public class GeckoEvent { - // these constants should match the ones in mobile/android/base/GeckoEvent.java - // as much as possible - public static final int INVALID = -1; - public static final int NATIVE_POKE = 0; - public static final int KEY_EVENT = 1; - public static final int MOTION_EVENT = 2; - public static final int SENSOR_EVENT = 3; - public static final int LOCATION_EVENT = 5; - public static final int IME_EVENT = 6; - public static final int DRAW = 7; - public static final int SIZE_CHANGED = 8; - public static final int ACTIVITY_STOPPING = 9; - public static final int ACTIVITY_PAUSING = 10; - public static final int ACTIVITY_SHUTDOWN = 11; - public static final int LOAD_URI = 12; - public static final int SURFACE_CREATED = 13; - public static final int SURFACE_DESTROYED = 14; - public static final int GECKO_EVENT_SYNC = 15; - public static final int ACTIVITY_START = 17; - public static final int SAVE_STATE = 18; - public static final int BROADCAST = 19; - public static final int VIEWPORT = 20; - public static final int VISITED = 21; - public static final int NETWORK_CHANGED = 22; - public static final int SCREENORIENTATION_CHANGED = 27; - - /** - * These DOM_KEY_LOCATION constants mirror the DOM KeyboardEvent's constants. - * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants - */ - private static final int DOM_KEY_LOCATION_STANDARD = 0; - private static final int DOM_KEY_LOCATION_LEFT = 1; - private static final int DOM_KEY_LOCATION_RIGHT = 2; - private static final int DOM_KEY_LOCATION_NUMPAD = 3; - private static final int DOM_KEY_LOCATION_MOBILE = 4; - private static final int DOM_KEY_LOCATION_JOYSTICK = 5; - - public static final int IME_COMPOSITION_END = 0; - public static final int IME_COMPOSITION_BEGIN = 1; - public static final int IME_SET_TEXT = 2; - public static final int IME_GET_TEXT = 3; - public static final int IME_DELETE_TEXT = 4; - public static final int IME_SET_SELECTION = 5; - public static final int IME_GET_SELECTION = 6; - public static final int IME_ADD_RANGE = 7; - - public static final int IME_RANGE_CARETPOSITION = 1; - public static final int IME_RANGE_RAWINPUT = 2; - public static final int IME_RANGE_SELECTEDRAWTEXT = 3; - public static final int IME_RANGE_CONVERTEDTEXT = 4; - public static final int IME_RANGE_SELECTEDCONVERTEDTEXT = 5; - - public static final int IME_RANGE_UNDERLINE = 1; - public static final int IME_RANGE_FORECOLOR = 2; - public static final int IME_RANGE_BACKCOLOR = 4; - - public int mType; - public int mAction; - public long mTime; - public Point[] mPoints; - public int[] mPointIndicies; - public int mPointerIndex; - public float[] mOrientations; - public float[] mPressures; - public Point[] mPointRadii; - public Rect mRect; - public double mX, mY, mZ; - - public int mMetaState, mFlags; - public int mKeyCode, mUnicodeChar; - public int mRepeatCount; - public int mOffset, mCount; - public String mCharacters, mCharactersExtra; - public int mRangeType, mRangeStyles; - public int mRangeForeColor, mRangeBackColor; - public Location mLocation; - public Address mAddress; - public int mDomKeyLocation; - - public double mBandwidth; - public boolean mCanBeMetered; - - public short mScreenOrientation; - - public int mNativeWindow; - - public ByteBuffer mBuffer; - - public GeckoEvent() { - mType = NATIVE_POKE; - } - - public GeckoEvent(int evType) { - mType = evType; - } - - public GeckoEvent(KeyEvent k) { - mType = KEY_EVENT; - mAction = k.getAction(); - mTime = k.getEventTime(); - mMetaState = k.getMetaState(); - mFlags = k.getFlags(); - mKeyCode = k.getKeyCode(); - mUnicodeChar = k.getUnicodeChar(); - mRepeatCount = k.getRepeatCount(); - mCharacters = k.getCharacters(); - mDomKeyLocation = isJoystickButton(mKeyCode) ? DOM_KEY_LOCATION_JOYSTICK : DOM_KEY_LOCATION_MOBILE; - } - - /** - * This method tests if a key is one of the described in: - * https://bugzilla.mozilla.org/show_bug.cgi?id=756504#c0 - * @param keyCode int with the key code (Android key constant from KeyEvent) - * @return true if the key is one of the listed above, false otherwise. - */ - private static boolean isJoystickButton(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_DPAD_CENTER: - case KeyEvent.KEYCODE_DPAD_LEFT: - case KeyEvent.KEYCODE_DPAD_RIGHT: - case KeyEvent.KEYCODE_DPAD_DOWN: - case KeyEvent.KEYCODE_DPAD_UP: - return true; - default: - if (Build.VERSION.SDK_INT >= 12) { - return KeyEvent.isGamepadButton(keyCode); - } - return GeckoEvent.isGamepadButton(keyCode); - } - } - - /** - * This method is a replacement for the the KeyEvent.isGamepadButton method to be - * compatible with Build.VERSION.SDK_INT < 12. This is an implementantion of the - * same method isGamepadButton available after SDK 12. - * @param keyCode int with the key code (Android key constant from KeyEvent). - * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}. - */ - private static boolean isGamepadButton(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_BUTTON_A: - case KeyEvent.KEYCODE_BUTTON_B: - case KeyEvent.KEYCODE_BUTTON_C: - case KeyEvent.KEYCODE_BUTTON_X: - case KeyEvent.KEYCODE_BUTTON_Y: - case KeyEvent.KEYCODE_BUTTON_Z: - case KeyEvent.KEYCODE_BUTTON_L1: - case KeyEvent.KEYCODE_BUTTON_R1: - case KeyEvent.KEYCODE_BUTTON_L2: - case KeyEvent.KEYCODE_BUTTON_R2: - case KeyEvent.KEYCODE_BUTTON_THUMBL: - case KeyEvent.KEYCODE_BUTTON_THUMBR: - case KeyEvent.KEYCODE_BUTTON_START: - case KeyEvent.KEYCODE_BUTTON_SELECT: - case KeyEvent.KEYCODE_BUTTON_MODE: - case KeyEvent.KEYCODE_BUTTON_1: - case KeyEvent.KEYCODE_BUTTON_2: - case KeyEvent.KEYCODE_BUTTON_3: - case KeyEvent.KEYCODE_BUTTON_4: - case KeyEvent.KEYCODE_BUTTON_5: - case KeyEvent.KEYCODE_BUTTON_6: - case KeyEvent.KEYCODE_BUTTON_7: - case KeyEvent.KEYCODE_BUTTON_8: - case KeyEvent.KEYCODE_BUTTON_9: - case KeyEvent.KEYCODE_BUTTON_10: - case KeyEvent.KEYCODE_BUTTON_11: - case KeyEvent.KEYCODE_BUTTON_12: - case KeyEvent.KEYCODE_BUTTON_13: - case KeyEvent.KEYCODE_BUTTON_14: - case KeyEvent.KEYCODE_BUTTON_15: - case KeyEvent.KEYCODE_BUTTON_16: - return true; - default: - return false; - } - } - public GeckoEvent(MotionEvent m) { - mType = MOTION_EVENT; - mAction = m.getAction(); - mTime = m.getEventTime(); - mMetaState = m.getMetaState(); - - switch (mAction & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_POINTER_DOWN: - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_MOVE: { - mCount = m.getPointerCount(); - mPoints = new Point[mCount]; - mPointIndicies = new int[mCount]; - mOrientations = new float[mCount]; - mPressures = new float[mCount]; - mPointRadii = new Point[mCount]; - mPointerIndex = (mAction & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - for (int i = 0; i < mCount; i++) { - addMotionPoint(i, i, m); - } - break; - } - default: { - mCount = 0; - mPointerIndex = -1; - mPoints = new Point[mCount]; - mPointIndicies = new int[mCount]; - mOrientations = new float[mCount]; - mPressures = new float[mCount]; - mPointRadii = new Point[mCount]; - } - } - } - - public void addMotionPoint(int index, int eventIndex, MotionEvent event) { - PointF geckoPoint = new PointF(event.getX(eventIndex), event.getY(eventIndex)); - - mPoints[index] = new Point((int)Math.round(geckoPoint.x), (int)Math.round(geckoPoint.y)); - mPointIndicies[index] = event.getPointerId(eventIndex); - // getToolMajor, getToolMinor and getOrientation are API Level 9 features - if (Build.VERSION.SDK_INT >= 9) { - double radians = event.getOrientation(eventIndex); - mOrientations[index] = (float) Math.toDegrees(radians); - // w3c touchevents spec does not allow orientations == 90 - // this shifts it to -90, which will be shifted to zero below - if (mOrientations[index] == 90) - mOrientations[index] = -90; - - // w3c touchevent radius are given by an orientation between 0 and 90 - // the radius is found by removing the orientation and measuring the x and y - // radius of the resulting ellipse - // for android orientations >= 0 and < 90, the major axis should correspond to - // just reporting the y radius as the major one, and x as minor - // however, for a radius < 0, we have to shift the orientation by adding 90, and - // reverse which radius is major and minor - if (mOrientations[index] < 0) { - mOrientations[index] += 90; - mPointRadii[index] = new Point((int)event.getToolMajor(eventIndex)/2, - (int)event.getToolMinor(eventIndex)/2); - } else { - mPointRadii[index] = new Point((int)event.getToolMinor(eventIndex)/2, - (int)event.getToolMajor(eventIndex)/2); - } - } else { - float size = event.getSize(eventIndex); - DisplayMetrics displaymetrics = new DisplayMetrics(); - GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); - size = size*Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels); - mPointRadii[index] = new Point((int)size,(int)size); - mOrientations[index] = 0; - } - mPressures[index] = event.getPressure(eventIndex); - } - - public GeckoEvent(SensorEvent s) { - int sensor_type = s.sensor.getType(); - - switch(sensor_type) { - case Sensor.TYPE_ACCELEROMETER: - mType = SENSOR_EVENT; - mFlags = 1; // hal::SENSOR_ACCELERATION - mX = s.values[0]; - mY = s.values[1]; - mZ = s.values[2]; - break; - - case Sensor.TYPE_ORIENTATION: - mType = SENSOR_EVENT; - mFlags = 0; // hal::SENSOR_ORIENTATION - mX = s.values[0]; - mY = s.values[1]; - mZ = s.values[2]; - Log.i("GeckoEvent", "SensorEvent type = " + s.sensor.getType() + " " + s.sensor.getName() + " " + mX + " " + mY + " " + mZ ); - break; - - case Sensor.TYPE_PROXIMITY: - mType = SENSOR_EVENT; - mFlags = 2; // hal:SENSOR_PROXIMITY - mX = s.values[0]; - mY = 0; - mZ = s.sensor.getMaximumRange(); - Log.i("GeckoEvent", "SensorEvent type = " + s.sensor.getType() + - " " + s.sensor.getName() + " " + mX); - break; - } - } - - public GeckoEvent(Location l) { - mType = LOCATION_EVENT; - mLocation = l; - } - - public GeckoEvent(int imeAction, int offset, int count) { - mType = IME_EVENT; - mAction = imeAction; - mOffset = offset; - mCount = count; - } - - private void InitIMERange(int action, int offset, int count, - int rangeType, int rangeStyles, - int rangeForeColor, int rangeBackColor) { - mType = IME_EVENT; - mAction = action; - mOffset = offset; - mCount = count; - mRangeType = rangeType; - mRangeStyles = rangeStyles; - mRangeForeColor = rangeForeColor; - mRangeBackColor = rangeBackColor; - return; - } - - public GeckoEvent(int offset, int count, - int rangeType, int rangeStyles, - int rangeForeColor, int rangeBackColor, String text) { - InitIMERange(IME_SET_TEXT, offset, count, rangeType, rangeStyles, - rangeForeColor, rangeBackColor); - mCharacters = text; - } - - public GeckoEvent(int offset, int count, - int rangeType, int rangeStyles, - int rangeForeColor, int rangeBackColor) { - InitIMERange(IME_ADD_RANGE, offset, count, rangeType, rangeStyles, - rangeForeColor, rangeBackColor); - } - - public GeckoEvent(int etype, Rect dirty) { - if (etype != DRAW) { - mType = INVALID; - return; - } - - mType = etype; - mRect = dirty; - } - - public GeckoEvent(int etype, int w, int h, int screenw, int screenh) { - if (etype != SIZE_CHANGED) { - mType = INVALID; - return; - } - - mType = etype; - - mPoints = new Point[3]; - mPoints[0] = new Point(w, h); - mPoints[1] = new Point(screenw, screenh); - mPoints[2] = new Point(0, 0); - } - - public GeckoEvent(String subject, String data) { - mType = BROADCAST; - mCharacters = subject; - mCharactersExtra = data; - } - - public GeckoEvent(String uri) { - mType = LOAD_URI; - mCharacters = uri; - } - - public GeckoEvent(double bandwidth, boolean canBeMetered) { - mType = NETWORK_CHANGED; - mBandwidth = bandwidth; - mCanBeMetered = canBeMetered; - } - - public GeckoEvent(short aScreenOrientation) { - mType = SCREENORIENTATION_CHANGED; - mScreenOrientation = aScreenOrientation; - } -}
deleted file mode 100644 --- a/embedding/android/GeckoInputConnection.java +++ /dev/null @@ -1,701 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; - -import android.os.*; -import android.app.*; -import android.text.*; -import android.text.style.*; -import android.view.*; -import android.view.inputmethod.*; -import android.content.*; -import android.R; - -import android.util.*; - -public class GeckoInputConnection - extends BaseInputConnection - implements TextWatcher -{ - private class ChangeNotification { - public String mText; - public int mStart; - public int mEnd; - public int mNewEnd; - - ChangeNotification(String text, int start, int oldEnd, int newEnd) { - mText = text; - mStart = start; - mEnd = oldEnd; - mNewEnd = newEnd; - } - - ChangeNotification(int start, int end) { - mText = null; - mStart = start; - mEnd = end; - mNewEnd = 0; - } - } - - public GeckoInputConnection (View targetView) { - super(targetView, true); - mQueryResult = new SynchronousQueue<String>(); - } - - @Override - public boolean beginBatchEdit() { - //Log.d("GeckoAppJava", "IME: beginBatchEdit"); - mBatchMode = true; - return true; - } - - @Override - public boolean commitCompletion(CompletionInfo text) { - //Log.d("GeckoAppJava", "IME: commitCompletion"); - - return commitText(text.getText(), 1); - } - - @Override - public boolean commitText(CharSequence text, int newCursorPosition) { - //Log.d("GeckoAppJava", "IME: commitText"); - - setComposingText(text, newCursorPosition); - finishComposingText(); - - return true; - } - - @Override - public boolean deleteSurroundingText(int leftLength, int rightLength) { - //Log.d("GeckoAppJava", "IME: deleteSurroundingText"); - if (leftLength == 0 && rightLength == 0) - return true; - - /* deleteSurroundingText is supposed to ignore the composing text, - so we cancel any pending composition, delete the text, and then - restart the composition */ - - if (mComposing) { - // Cancel current composition - GeckoAppShell.sendEventToGecko( - new GeckoEvent(0, 0, 0, 0, 0, 0, null)); - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0)); - } - - // Select text to be deleted - int delStart, delLen; - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_SELECTION, 0, 0)); - try { - mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: deleteSurroundingText interrupted", e); - return false; - } - delStart = mSelectionStart > leftLength ? - mSelectionStart - leftLength : 0; - delLen = mSelectionStart + rightLength - delStart; - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, delStart, delLen)); - - // Restore composition / delete text - if (mComposing) { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0)); - if (mComposingText.length() > 0) { - /* IME_SET_TEXT doesn't work well with empty strings */ - GeckoAppShell.sendEventToGecko( - new GeckoEvent(0, mComposingText.length(), - GeckoEvent.IME_RANGE_RAWINPUT, - GeckoEvent.IME_RANGE_UNDERLINE, 0, 0, - mComposingText.toString())); - } - } else { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_DELETE_TEXT, 0, 0)); - } - return true; - } - - @Override - public boolean endBatchEdit() { - //Log.d("GeckoAppJava", "IME: endBatchEdit"); - - mBatchMode = false; - - if (!mBatchChanges.isEmpty()) { - InputMethodManager imm = (InputMethodManager) - GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - for (ChangeNotification n : mBatchChanges) { - if (n.mText != null) - notifyTextChange(imm, n.mText, n.mStart, n.mEnd, n.mNewEnd); - else - notifySelectionChange(imm, n.mStart, n.mEnd); - } - } - mBatchChanges.clear(); - } - return true; - } - - @Override - public boolean finishComposingText() { - //Log.d("GeckoAppJava", "IME: finishComposingText"); - - if (mComposing) { - // Set style to none - GeckoAppShell.sendEventToGecko( - new GeckoEvent(0, mComposingText.length(), - GeckoEvent.IME_RANGE_RAWINPUT, 0, 0, 0, - mComposingText)); - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0)); - mComposing = false; - mComposingText = ""; - - if (!mBatchMode) { - // Make sure caret stays at the same position - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, - mCompositionStart + mCompositionSelStart, 0)); - } - } - return true; - } - - @Override - public int getCursorCapsMode(int reqModes) { - //Log.d("GeckoAppJava", "IME: getCursorCapsMode"); - - return 0; - } - - @Override - public Editable getEditable() { - Log.w("GeckoAppJava", "IME: getEditable called from " + - Thread.currentThread().getStackTrace()[0].toString()); - - return null; - } - - @Override - public boolean performContextMenuAction(int id) { - //Log.d("GeckoAppJava", "IME: performContextMenuAction"); - - // First we need to ask Gecko to tell us the full contents of the - // text field we're about to operate on. - String text; - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_TEXT, 0, Integer.MAX_VALUE)); - try { - text = mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: performContextMenuAction interrupted", e); - return false; - } - - switch (id) { - case R.id.selectAll: - setSelection(0, text.length()); - break; - case R.id.cut: - // Fill the clipboard - GeckoAppShell.setClipboardText(text); - // If GET_TEXT returned an empty selection, we'll select everything - if (mSelectionLength <= 0) - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, 0, text.length())); - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_DELETE_TEXT, 0, 0)); - break; - case R.id.paste: - commitText(GeckoAppShell.getClipboardText(), 1); - break; - case R.id.copy: - // If there is no selection set, we must be doing "Copy All", - // otherwise, we need to get the selection from Gecko - if (mSelectionLength > 0) { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_SELECTION, 0, 0)); - try { - text = mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: performContextMenuAction interrupted", e); - return false; - } - } - GeckoAppShell.setClipboardText(text); - break; - } - return true; - } - - @Override - public ExtractedText getExtractedText(ExtractedTextRequest req, int flags) { - if (req == null) - return null; - - // Bail out here if gecko isn't running, otherwise we deadlock - // below when waiting for the reply to IME_GET_SELECTION. - if (!GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) - return null; - - //Log.d("GeckoAppJava", "IME: getExtractedText"); - - ExtractedText extract = new ExtractedText(); - extract.flags = 0; - extract.partialStartOffset = -1; - extract.partialEndOffset = -1; - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_SELECTION, 0, 0)); - try { - mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: getExtractedText interrupted", e); - return null; - } - extract.selectionStart = mSelectionStart; - extract.selectionEnd = mSelectionStart + mSelectionLength; - - // bug 617298 - IME_GET_TEXT sometimes gives the wrong result due to - // a stale cache. Use a set of three workarounds: - // 1. Sleep for 20 milliseconds and hope the child updates us with the new text. - // Very evil and, consequentially, most effective. - try { - Thread.sleep(20); - } catch (InterruptedException e) {} - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_TEXT, 0, Integer.MAX_VALUE)); - try { - extract.startOffset = 0; - extract.text = mQueryResult.take(); - - // 2. Make a guess about what the text actually is - if (mComposing && extract.selectionEnd > extract.text.length()) - extract.text = extract.text.subSequence(0, Math.min(extract.text.length(), mCompositionStart)) + mComposingText; - - // 3. If all else fails, make sure our selection indexes make sense - extract.selectionStart = Math.min(extract.selectionStart, extract.text.length()); - extract.selectionEnd = Math.min(extract.selectionEnd, extract.text.length()); - - if ((flags & GET_EXTRACTED_TEXT_MONITOR) != 0) - mUpdateRequest = req; - return extract; - - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: getExtractedText interrupted", e); - return null; - } - } - - @Override - public CharSequence getTextAfterCursor(int length, int flags) { - //Log.d("GeckoAppJava", "IME: getTextAfterCursor"); - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_SELECTION, 0, 0)); - try { - mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: getTextBefore/AfterCursor interrupted", e); - return null; - } - - /* Compatible with both positive and negative length - (no need for separate code for getTextBeforeCursor) */ - int textStart = mSelectionStart; - int textLength = length; - - if (length < 0) { - textStart += length; - textLength = -length; - if (textStart < 0) { - textStart = 0; - textLength = mSelectionStart; - } - } - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_TEXT, textStart, textLength)); - try { - return mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: getTextBefore/AfterCursor: Interrupted!", e); - return null; - } - } - - @Override - public CharSequence getTextBeforeCursor(int length, int flags) { - //Log.d("GeckoAppJava", "IME: getTextBeforeCursor"); - - return getTextAfterCursor(-length, flags); - } - - @Override - public boolean setComposingText(CharSequence text, int newCursorPosition) { - //Log.d("GeckoAppJava", "IME: setComposingText"); - - // Set new composing text - mComposingText = text != null ? text.toString() : ""; - - if (!mComposing) { - if (mComposingText.length() == 0) { - // Some IMEs such as iWnn sometimes call with empty composing - // text. (See bug 664364) - // If composing text is empty, ignore this and don't start - // compositing. - return true; - } - - // Get current selection - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_SELECTION, 0, 0)); - try { - mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: setComposingText interrupted", e); - return false; - } - // Make sure we are in a composition - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0)); - mComposing = true; - mCompositionStart = mSelectionLength >= 0 ? - mSelectionStart : mSelectionStart + mSelectionLength; - } - - // Set new selection - // New selection should be within the composition - mCompositionSelStart = newCursorPosition > 0 ? mComposingText.length() : 0; - mCompositionSelLen = 0; - - // Handle composition text styles - if (text != null && text instanceof Spanned) { - Spanned span = (Spanned) text; - int spanStart = 0, spanEnd = 0; - boolean pastSelStart = false, pastSelEnd = false; - - do { - int rangeType = GeckoEvent.IME_RANGE_CONVERTEDTEXT; - int rangeStyles = 0, rangeForeColor = 0, rangeBackColor = 0; - - // Find next offset where there is a style transition - spanEnd = span.nextSpanTransition(spanStart + 1, text.length(), - CharacterStyle.class); - - // We need to count the selection as a transition - if (mCompositionSelLen >= 0) { - if (!pastSelStart && spanEnd >= mCompositionSelStart) { - spanEnd = mCompositionSelStart; - pastSelStart = true; - } else if (!pastSelEnd && spanEnd >= - mCompositionSelStart + mCompositionSelLen) { - spanEnd = mCompositionSelStart + mCompositionSelLen; - pastSelEnd = true; - rangeType = GeckoEvent.IME_RANGE_SELECTEDRAWTEXT; - } - } else { - if (!pastSelEnd && spanEnd >= - mCompositionSelStart + mCompositionSelLen) { - spanEnd = mCompositionSelStart + mCompositionSelLen; - pastSelEnd = true; - } else if (!pastSelStart && - spanEnd >= mCompositionSelStart) { - spanEnd = mCompositionSelStart; - pastSelStart = true; - rangeType = GeckoEvent.IME_RANGE_SELECTEDRAWTEXT; - } - } - // Empty range, continue - if (spanEnd <= spanStart) - continue; - - // Get and iterate through list of span objects within range - CharacterStyle styles[] = span.getSpans( - spanStart, spanEnd, CharacterStyle.class); - - for (CharacterStyle style : styles) { - if (style instanceof UnderlineSpan) { - // Text should be underlined - rangeStyles |= GeckoEvent.IME_RANGE_UNDERLINE; - - } else if (style instanceof ForegroundColorSpan) { - // Text should be of a different foreground color - rangeStyles |= GeckoEvent.IME_RANGE_FORECOLOR; - rangeForeColor = - ((ForegroundColorSpan)style).getForegroundColor(); - - } else if (style instanceof BackgroundColorSpan) { - // Text should be of a different background color - rangeStyles |= GeckoEvent.IME_RANGE_BACKCOLOR; - rangeBackColor = - ((BackgroundColorSpan)style).getBackgroundColor(); - } - } - - // Add range to array, the actual styles are - // applied when IME_SET_TEXT is sent - GeckoAppShell.sendEventToGecko( - new GeckoEvent(spanStart, spanEnd - spanStart, - rangeType, rangeStyles, - rangeForeColor, rangeBackColor)); - - spanStart = spanEnd; - } while (spanStart < text.length()); - } else { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(0, text == null ? 0 : text.length(), - GeckoEvent.IME_RANGE_RAWINPUT, - GeckoEvent.IME_RANGE_UNDERLINE, 0, 0)); - } - - // Change composition (treating selection end as where the caret is) - GeckoAppShell.sendEventToGecko( - new GeckoEvent(mCompositionSelStart + mCompositionSelLen, 0, - GeckoEvent.IME_RANGE_CARETPOSITION, 0, 0, 0, - mComposingText)); - - return true; - } - - @Override - public boolean setComposingRegion(int start, int end) { - //Log.d("GeckoAppJava", "IME: setComposingRegion(start=" + start + ", end=" + end + ")"); - if (start < 0 || end < start) - return true; - - CharSequence text = null; - if (start == mCompositionStart && end - start == mComposingText.length()) { - // Use mComposingText to avoid extra call to Gecko - text = mComposingText; - } - - finishComposingText(); - - if (text == null && start < end) { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_GET_TEXT, start, end - start)); - try { - text = mQueryResult.take(); - } catch (InterruptedException e) { - Log.e("GeckoAppJava", "IME: setComposingRegion interrupted", e); - return false; - } - } - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, end - start)); - - // Call setComposingText with the same text to start composition and let Gecko know about new composing region - setComposingText(text, 1); - - return true; - } - - @Override - public boolean setSelection(int start, int end) { - //Log.d("GeckoAppJava", "IME: setSelection"); - - if (mComposing) { - /* Translate to fake selection positions */ - start -= mCompositionStart; - end -= mCompositionStart; - - if (start < 0) - start = 0; - else if (start > mComposingText.length()) - start = mComposingText.length(); - - if (end < 0) - end = 0; - else if (end > mComposingText.length()) - end = mComposingText.length(); - - mCompositionSelStart = start; - mCompositionSelLen = end - start; - } else { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, - start, end - start)); - } - return true; - } - - public boolean onKeyDel() { - // Some IMEs don't update us on deletions - // In that case we are not updated when a composition - // is destroyed, and Bad Things happen - - if (!mComposing) - return false; - - if (mComposingText.length() > 0) { - mComposingText = mComposingText.substring(0, - mComposingText.length() - 1); - if (mComposingText.length() > 0) - return false; - } - - commitText(null, 1); - return true; - } - - public void notifyTextChange(InputMethodManager imm, String text, - int start, int oldEnd, int newEnd) { - // Log.d("GeckoAppShell", String.format("IME: notifyTextChange: text=%s s=%d ne=%d oe=%d", - // text, start, newEnd, oldEnd)); - - if (mBatchMode) { - mBatchChanges.add(new ChangeNotification(text, start, oldEnd, newEnd)); - return; - } - - mNumPendingChanges = Math.max(mNumPendingChanges - 1, 0); - - // If there are pending changes, that means this text is not the most up-to-date version - // and we'll step on ourselves if we change the editable right now. - if (mNumPendingChanges == 0 && !text.contentEquals(GeckoApp.surfaceView.mEditable)) - GeckoApp.surfaceView.setEditable(text); - - if (mUpdateRequest == null) - return; - - mUpdateExtract.flags = 0; - - // We update from (0, oldEnd) to (0, newEnd) because some Android IMEs - // assume that updates start at zero, according to jchen. - mUpdateExtract.partialStartOffset = 0; - mUpdateExtract.partialEndOffset = oldEnd; - - // Faster to not query for selection - mUpdateExtract.selectionStart = newEnd; - mUpdateExtract.selectionEnd = newEnd; - - mUpdateExtract.text = text.substring(0, newEnd); - mUpdateExtract.startOffset = 0; - - imm.updateExtractedText(GeckoApp.surfaceView, - mUpdateRequest.token, mUpdateExtract); - } - - public void notifySelectionChange(InputMethodManager imm, - int start, int end) { - // Log.d("GeckoAppJava", String.format("IME: notifySelectionChange: s=%d e=%d", start, end)); - if (mBatchMode) { - mBatchChanges.add(new ChangeNotification(start, end)); - return; - } - - if (mComposing) - imm.updateSelection(GeckoApp.surfaceView, - mCompositionStart + mCompositionSelStart, - mCompositionStart + mCompositionSelStart + mCompositionSelLen, - mCompositionStart, - mCompositionStart + mComposingText.length()); - else - imm.updateSelection(GeckoApp.surfaceView, start, end, -1, -1); - - // We only change the selection if we are relatively sure that the text we have is - // up-to-date. Bail out if we are stil expecting changes. - if (mNumPendingChanges > 0) - return; - - int maxLen = GeckoApp.surfaceView.mEditable.length(); - Selection.setSelection(GeckoApp.surfaceView.mEditable, - Math.min(start, maxLen), - Math.min(end, maxLen)); - } - - public void reset() { - mComposing = false; - mComposingText = ""; - mUpdateRequest = null; - mNumPendingChanges = 0; - mBatchMode = false; - mBatchChanges.clear(); - } - - // TextWatcher - public void onTextChanged(CharSequence s, int start, int before, int count) - { - // Log.d("GeckoAppShell", String.format("IME: onTextChanged: t=%s s=%d b=%d l=%d", - // s, start, before, count)); - - mNumPendingChanges++; - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, before)); - - if (count == 0) { - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_DELETE_TEXT, 0, 0)); - } else { - // Start and stop composition to force UI updates. - finishComposingText(); - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0)); - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(0, count, - GeckoEvent.IME_RANGE_RAWINPUT, 0, 0, 0, - s.subSequence(start, start + count).toString())); - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0)); - - GeckoAppShell.sendEventToGecko( - new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start + count, 0)); - } - - // Block this thread until all pending events are processed - GeckoAppShell.geckoEventSync(); - } - - public void afterTextChanged(Editable s) - { - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) - { - } - - // Is a composition active? - boolean mComposing; - // Composition text when a composition is active - String mComposingText = ""; - // Start index of the composition within the text body - int mCompositionStart; - /* During a composition, we should not alter the real selection, - therefore we keep our own offsets to emulate selection */ - // Start of fake selection, relative to start of composition - int mCompositionSelStart; - // Length of fake selection - int mCompositionSelLen; - // Number of in flight changes - int mNumPendingChanges; - - boolean mBatchMode; - private CopyOnWriteArrayList<ChangeNotification> mBatchChanges = - new CopyOnWriteArrayList<ChangeNotification>(); - - ExtractedTextRequest mUpdateRequest; - final ExtractedText mUpdateExtract = new ExtractedText(); - - int mSelectionStart, mSelectionLength; - SynchronousQueue<String> mQueryResult; -} -
deleted file mode 100644 --- a/embedding/android/GeckoNetworkManager.java +++ /dev/null @@ -1,303 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.lang.Math; - -import android.util.Log; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -import android.telephony.TelephonyManager; - -/* - * A part of the work of GeckoNetworkManager is to give an estimation of the - * download speed of the current connection. For known to be fast connection, we - * simply use a predefined value (we don't care about being precise). For mobile - * connections, we sort them in groups (generations) and estimate the average - * real life download speed of that specific generation. This value comes from - * researches (eg. Wikipedia articles) or is simply an arbitrary estimation. - * Precision isn't important, we mostly need an order of magnitude. - * - * Each group is composed with networks represented by the constant from - * Android's ConnectivityManager and the description comming from the same - * class. - * - * 2G (15 bk/s): - * int NETWORK_TYPE_IDEN Current network is iDen - * int NETWORK_TYPE_CDMA Current network is CDMA: Either IS95A or IS95B - * - * 2.5G (60 kb/s) - * int NETWORK_TYPE_GPRS Current network is GPRS - * int NETWORK_TYPE_1xRTT Current network is 1xRTT - * - * 2.75G (200 kb/s) - * int NETWORK_TYPE_EDGE Current network is EDGE - * - * 3G (300 kb/s) - * int NETWORK_TYPE_UMTS Current network is UMTS - * int NETWORK_TYPE_EVDO_0 Current network is EVDO revision 0 - * - * 3.5G (7 Mb/s) - * int NETWORK_TYPE_HSPA Current network is HSPA - * int NETWORK_TYPE_HSDPA Current network is HSDPA - * int NETWORK_TYPE_HSUPA Current network is HSUPA - * int NETWORK_TYPE_EVDO_A Current network is EVDO revision A - * int NETWORK_TYPE_EVDO_B Current network is EVDO revision B - * int NETWORK_TYPE_EHRPD Current network is eHRPD - * - * 3.75G (20 Mb/s) - * int NETWORK_TYPE_HSPAP Current network is HSPA+ - * - * 3.9G (50 Mb/s) - * int NETWORK_TYPE_LTE Current network is LTE - */ - -public class GeckoNetworkManager - extends BroadcastReceiver -{ - static private final GeckoNetworkManager sInstance = new GeckoNetworkManager(); - - static private final double kDefaultBandwidth = -1.0; - static private final boolean kDefaultCanBeMetered = false; - - static private final double kMaxBandwidth = 20.0; - - static private final double kNetworkSpeedEthernet = 20.0; // 20 Mb/s - static private final double kNetworkSpeedWifi = 20.0; // 20 Mb/s - static private final double kNetworkSpeedWiMax = 40.0; // 40 Mb/s - static private final double kNetworkSpeed_2_G = 15.0 / 1024.0; // 15 kb/s - static private final double kNetworkSpeed_2_5_G = 60.0 / 1024.0; // 60 kb/s - static private final double kNetworkSpeed_2_75_G = 200.0 / 1024.0; // 200 kb/s - static private final double kNetworkSpeed_3_G = 300.0 / 1024.0; // 300 kb/s - static private final double kNetworkSpeed_3_5_G = 7.0; // 7 Mb/s - static private final double kNetworkSpeed_3_75_G = 20.0; // 20 Mb/s - static private final double kNetworkSpeed_3_9_G = 50.0; // 50 Mb/s - - private enum NetworkType { - NETWORK_NONE, - NETWORK_ETHERNET, - NETWORK_WIFI, - NETWORK_WIMAX, - NETWORK_2_G, // 2G - NETWORK_2_5_G, // 2.5G - NETWORK_2_75_G, // 2.75G - NETWORK_3_G, // 3G - NETWORK_3_5_G, // 3.5G - NETWORK_3_75_G, // 3.75G - NETWORK_3_9_G, // 3.9G - NETWORK_UNKNOWN - } - - private NetworkType mNetworkType = NetworkType.NETWORK_NONE; - private IntentFilter mNetworkFilter = new IntentFilter(); - // Whether the manager should be listening to Network Information changes. - private boolean mShouldBeListening = false; - // Whether the manager should notify Gecko that a change in Network - // Information happened. - private boolean mShouldNotify = false; - - public static GeckoNetworkManager getInstance() { - return sInstance; - } - - @Override - public void onReceive(Context aContext, Intent aIntent) { - updateNetworkType(); - } - - public void init() { - mNetworkFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - - mNetworkType = getNetworkType(); - } - - public void start() { - mShouldBeListening = true; - updateNetworkType(); - - if (mShouldNotify) { - startListening(); - } - } - - private void startListening() { - GeckoApp.mAppContext.registerReceiver(sInstance, mNetworkFilter); - } - - public void stop() { - mShouldBeListening = false; - - if (mShouldNotify) { - stopListening(); - } - } - - private void stopListening() { - GeckoApp.mAppContext.unregisterReceiver(sInstance); - } - - private void updateNetworkType() { - NetworkType previousNetworkType = mNetworkType; - mNetworkType = getNetworkType(); - - if (mNetworkType == previousNetworkType || !mShouldNotify) { - return; - } - - GeckoAppShell.sendEventToGecko(new GeckoEvent(getNetworkSpeed(mNetworkType), - isNetworkUsuallyMetered(mNetworkType))); - } - - public double[] getCurrentInformation() { - return new double[] { getNetworkSpeed(mNetworkType), - isNetworkUsuallyMetered(mNetworkType) ? 1.0 : 0.0 }; - } - - public void enableNotifications() { - // We set mShouldNotify *after* calling updateNetworkType() to make sure we - // don't notify an eventual change in mNetworkType. - updateNetworkType(); - mShouldNotify = true; - - if (mShouldBeListening) { - startListening(); - } - } - - public void disableNotifications() { - mShouldNotify = false; - - if (mShouldBeListening) { - stopListening(); - } - } - - private static NetworkType getNetworkType() { - ConnectivityManager cm = - (ConnectivityManager)GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE); - - if (cm == null) { - Log.w("GeckoNetworkManager", "Could not access Connectivity service"); - return NetworkType.NETWORK_NONE; - } - - NetworkInfo ni = cm.getActiveNetworkInfo(); - - if (ni == null) { - return NetworkType.NETWORK_NONE; - } - - switch (ni.getType()) { - case ConnectivityManager.TYPE_ETHERNET: - return NetworkType.NETWORK_ETHERNET; - case ConnectivityManager.TYPE_WIFI: - return NetworkType.NETWORK_WIFI; - case ConnectivityManager.TYPE_WIMAX: - return NetworkType.NETWORK_WIMAX; - case ConnectivityManager.TYPE_MOBILE: - break; // We will handle sub-types after the switch. - default: - Log.w("GeckoNetworkManager", "Ignoring the current network type."); - return NetworkType.NETWORK_UNKNOWN; - } - - TelephonyManager tm = - (TelephonyManager)GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE); - - if (tm == null) { - Log.w("GeckoNetworkManager", "Could not access Telephony service"); - return NetworkType.NETWORK_UNKNOWN; - } - - switch (tm.getNetworkType()) { - case TelephonyManager.NETWORK_TYPE_IDEN: - case TelephonyManager.NETWORK_TYPE_CDMA: - return NetworkType.NETWORK_2_G; - case TelephonyManager.NETWORK_TYPE_GPRS: - case TelephonyManager.NETWORK_TYPE_1xRTT: - return NetworkType.NETWORK_2_5_G; - case TelephonyManager.NETWORK_TYPE_EDGE: - return NetworkType.NETWORK_2_75_G; - case TelephonyManager.NETWORK_TYPE_UMTS: - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return NetworkType.NETWORK_3_G; - case TelephonyManager.NETWORK_TYPE_HSPA: - case TelephonyManager.NETWORK_TYPE_HSDPA: - case TelephonyManager.NETWORK_TYPE_HSUPA: - case TelephonyManager.NETWORK_TYPE_EVDO_A: - case TelephonyManager.NETWORK_TYPE_EVDO_B: - case TelephonyManager.NETWORK_TYPE_EHRPD: - return NetworkType.NETWORK_3_5_G; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return NetworkType.NETWORK_3_75_G; - case TelephonyManager.NETWORK_TYPE_LTE: - return NetworkType.NETWORK_3_9_G; - case TelephonyManager.NETWORK_TYPE_UNKNOWN: - default: - Log.w("GeckoNetworkManager", "Connected to an unknown mobile network!"); - return NetworkType.NETWORK_UNKNOWN; - } - } - - private static double getNetworkSpeed(NetworkType aType) { - switch (aType) { - case NETWORK_NONE: - return 0.0; - case NETWORK_ETHERNET: - return kNetworkSpeedEthernet; - case NETWORK_WIFI: - return kNetworkSpeedWifi; - case NETWORK_WIMAX: - return kNetworkSpeedWiMax; - case NETWORK_2_G: - return kNetworkSpeed_2_G; - case NETWORK_2_5_G: - return kNetworkSpeed_2_5_G; - case NETWORK_2_75_G: - return kNetworkSpeed_2_75_G; - case NETWORK_3_G: - return kNetworkSpeed_3_G; - case NETWORK_3_5_G: - return kNetworkSpeed_3_5_G; - case NETWORK_3_75_G: - return kNetworkSpeed_3_75_G; - case NETWORK_3_9_G: - return kNetworkSpeed_3_9_G; - case NETWORK_UNKNOWN: - default: - return kDefaultBandwidth; - } - } - - private static boolean isNetworkUsuallyMetered(NetworkType aType) { - switch (aType) { - case NETWORK_NONE: - case NETWORK_UNKNOWN: - case NETWORK_ETHERNET: - case NETWORK_WIFI: - case NETWORK_WIMAX: - return false; - case NETWORK_2_G: - case NETWORK_2_5_G: - case NETWORK_2_75_G: - case NETWORK_3_G: - case NETWORK_3_5_G: - case NETWORK_3_75_G: - case NETWORK_3_9_G: - return true; - default: - Log.e("GeckoNetworkManager", "Got an unexpected network type!"); - return false; - } - } -}
deleted file mode 100644 --- a/embedding/android/GeckoScreenOrientationListener.java +++ /dev/null @@ -1,161 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import android.content.Context; -import android.util.Log; -import android.view.OrientationEventListener; -import android.view.Surface; -import android.content.pm.ActivityInfo; - -public class GeckoScreenOrientationListener -{ - private static final String LOGTAG = "GeckoScreenOrientationListener"; - - static class OrientationEventListenerImpl extends OrientationEventListener { - public OrientationEventListenerImpl(Context c) { - super(c); - } - - @Override - public void onOrientationChanged(int aOrientation) { - GeckoScreenOrientationListener.getInstance().updateScreenOrientation(); - } - } - - static private GeckoScreenOrientationListener sInstance = null; - - // Make sure that any change in dom/base/ScreenOrientation.h happens here too. - static public final short eScreenOrientation_None = 0; - static public final short eScreenOrientation_PortraitPrimary = 1; // PR_BIT(0) - static public final short eScreenOrientation_PortraitSecondary = 2; // PR_BIT(1) - static public final short eScreenOrientation_LandscapePrimary = 4; // PR_BIT(2) - static public final short eScreenOrientation_LandscapeSecondary = 8; // PR_BIT(3) - - private short mOrientation; - private OrientationEventListenerImpl mListener = null; - - // Whether the listener should be listening to changes. - private boolean mShouldBeListening = false; - // Whether the listener should notify Gecko that a change happened. - private boolean mShouldNotify = false; - - private GeckoScreenOrientationListener() { - mListener = new OrientationEventListenerImpl(GeckoApp.mAppContext); - } - - public static GeckoScreenOrientationListener getInstance() { - if (sInstance == null) { - sInstance = new GeckoScreenOrientationListener(); - } - - return sInstance; - } - - public void start() { - mShouldBeListening = true; - updateScreenOrientation(); - - if (mShouldNotify) { - startListening(); - } - } - - public void stop() { - mShouldBeListening = false; - - if (mShouldNotify) { - stopListening(); - } - } - - public void enableNotifications() { - updateScreenOrientation(); - mShouldNotify = true; - - if (mShouldBeListening) { - startListening(); - } - } - - public void disableNotifications() { - mShouldNotify = false; - - if (mShouldBeListening) { - stopListening(); - } - } - - private void startListening() { - mListener.enable(); - } - - private void stopListening() { - mListener.disable(); - } - - // NOTE: this is public so OrientationEventListenerImpl can access it. - // Unfortunately, Java doesn't know about friendship. - public void updateScreenOrientation() { - int rotation = GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getRotation(); - short previousOrientation = mOrientation; - - if (rotation == Surface.ROTATION_0) { - mOrientation = eScreenOrientation_PortraitPrimary; - } else if (rotation == Surface.ROTATION_180) { - mOrientation = eScreenOrientation_PortraitSecondary; - } else if (rotation == Surface.ROTATION_270) { - mOrientation = eScreenOrientation_LandscapeSecondary; - } else if (rotation == Surface.ROTATION_90) { - mOrientation = eScreenOrientation_LandscapePrimary; - } else { - Log.e(LOGTAG, "Unexpected value received! (" + rotation + ")"); - return; - } - - if (mShouldNotify && mOrientation != previousOrientation) { - GeckoAppShell.sendEventToGecko(new GeckoEvent(mOrientation)); - } - } - - public short getScreenOrientation() { - return mOrientation; - } - - public void lockScreenOrientation(int aOrientation) { - int orientation = 0; - - switch (aOrientation) { - case eScreenOrientation_PortraitPrimary: - orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; - break; - case eScreenOrientation_PortraitSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; - break; - case eScreenOrientation_PortraitPrimary | eScreenOrientation_PortraitSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; - break; - case eScreenOrientation_LandscapePrimary: - orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; - break; - case eScreenOrientation_LandscapeSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; - break; - case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary: - orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; - break; - default: - Log.e(LOGTAG, "Unexpected value received! (" + aOrientation + ")"); - } - - GeckoApp.mAppContext.setRequestedOrientation(orientation); - updateScreenOrientation(); - } - - public void unlockScreenOrientation() { - GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); - updateScreenOrientation(); - } -}
deleted file mode 100644 --- a/embedding/android/GeckoSurfaceView.java +++ /dev/null @@ -1,777 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.concurrent.atomic.*; -import java.util.zip.*; -import java.nio.*; - -import android.os.*; -import android.app.*; -import android.text.*; -import android.text.method.*; -import android.view.*; -import android.view.inputmethod.*; -import android.content.*; -import android.graphics.*; -import android.widget.*; -import android.hardware.*; -import android.location.*; -import android.graphics.drawable.*; -import android.content.res.*; - -import android.util.*; - -/* - * GeckoSurfaceView implements a GL surface view, - * similar to GLSurfaceView. However, since we - * already have a thread for Gecko, we don't really want - * a separate renderer thread that GLSurfaceView provides. - */ -class GeckoSurfaceView - extends SurfaceView - implements SurfaceHolder.Callback, SensorEventListener, LocationListener -{ - private static final String LOG_FILE_NAME = "GeckoSurfaceView"; - - public GeckoSurfaceView(Context context) { - super(context); - - getHolder().addCallback(this); - inputConnection = new GeckoInputConnection(this); - setFocusable(true); - setFocusableInTouchMode(true); - - DisplayMetrics metrics = new DisplayMetrics(); - GeckoApp.mAppContext.getWindowManager(). - getDefaultDisplay().getMetrics(metrics); - mWidth = metrics.widthPixels; - mHeight = metrics.heightPixels; - mBufferWidth = 0; - mBufferHeight = 0; - - mSurfaceLock = new ReentrantLock(); - - mEditableFactory = Editable.Factory.getInstance(); - initEditable(""); - mIMEState = IME_STATE_DISABLED; - mIMETypeHint = ""; - mIMEModeHint = ""; - mIMEActionHint = ""; - } - - protected void finalize() throws Throwable { - super.finalize(); - } - - void drawSplashScreen() { - this.drawSplashScreen(getHolder(), mWidth, mHeight); - } - - void drawSplashScreen(SurfaceHolder holder, int width, int height) { - // No splash screen for Honeycomb or greater - if (Build.VERSION.SDK_INT >= 11) { - Log.i(LOG_FILE_NAME, "skipping splash screen"); - return; - } - - Canvas c = holder.lockCanvas(); - if (c == null) { - Log.i(LOG_FILE_NAME, "canvas is null"); - return; - } - - Resources res = getResources(); - - File watchDir = new File(GeckoApp.sGREDir, "components"); - if (watchDir.exists() == false) { - // Just show the simple splash screen for "new profile" startup - c.drawColor(res.getColor(R.color.splash_background)); - Drawable drawable = res.getDrawable(R.drawable.splash); - int w = drawable.getIntrinsicWidth(); - int h = drawable.getIntrinsicHeight(); - int x = (width - w) / 2; - int y = (height - h) / 2 - 16; - drawable.setBounds(x, y, x + w, y + h); - drawable.draw(c); - - Paint p = new Paint(); - p.setTextAlign(Paint.Align.CENTER); - p.setTextSize(32f); - p.setAntiAlias(true); - p.setColor(res.getColor(R.color.splash_msgfont)); - c.drawText(res.getString(R.string.splash_firstrun), width / 2, y + h + 16, p); - } else { - // Show the static UI for normal startup - DisplayMetrics metrics = new DisplayMetrics(); - GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - // Default to DENSITY_HIGH sizes - int toolbarHeight = 80; - int faviconOffset = 25; - float urlHeight = 24f; - int urlOffsetX = 80; - int urlOffsetY = 48; - if (metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM) { - toolbarHeight = 53; - faviconOffset = 10; - urlHeight = 16f; - urlOffsetX = 53; - urlOffsetY = 32; - } - - c.drawColor(res.getColor(R.color.splash_content)); - Drawable toolbar = res.getDrawable(Build.VERSION.SDK_INT > 8 ? - R.drawable.splash_v9 : - R.drawable.splash_v8); - toolbar.setBounds(0, 0, width, toolbarHeight); - toolbar.draw(c); - - // XUL/CSS always uses 32px width and height for favicon - Drawable favicon = res.getDrawable(R.drawable.favicon32); - favicon.setBounds(faviconOffset, faviconOffset, 32 + faviconOffset, 32 + faviconOffset); - favicon.draw(c); - - if (GeckoSurfaceView.mSplashURL != "") { - TextPaint p = new TextPaint(); - p.setTextAlign(Paint.Align.LEFT); - p.setTextSize(urlHeight); - p.setAntiAlias(true); - p.setColor(res.getColor(R.color.splash_urlfont)); - String url = TextUtils.ellipsize(GeckoSurfaceView.mSplashURL, p, width - urlOffsetX * 2, TextUtils.TruncateAt.END).toString(); - c.drawText(url, urlOffsetX, urlOffsetY, p); - } - } - holder.unlockCanvasAndPost(c); - } - - /* - * Called on main thread - */ - - public void draw(SurfaceHolder holder, ByteBuffer buffer) { - if (buffer == null || buffer.capacity() != (mWidth * mHeight * 2)) - return; - - synchronized (mSoftwareBuffer) { - if (buffer != mSoftwareBuffer || mSoftwareBufferCopy == null) - return; - - Canvas c = holder.lockCanvas(); - if (c == null) - return; - mSoftwareBufferCopy.copyPixelsFromBuffer(buffer); - c.drawBitmap(mSoftwareBufferCopy, 0, 0, null); - holder.unlockCanvasAndPost(c); - } - } - - public void draw(SurfaceHolder holder, Bitmap bitmap) { - if (bitmap == null || - bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) - return; - - synchronized (mSoftwareBitmap) { - if (bitmap != mSoftwareBitmap) - return; - - Canvas c = holder.lockCanvas(); - if (c == null) - return; - c.drawBitmap(bitmap, 0, 0, null); - holder.unlockCanvasAndPost(c); - } - } - - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - - // On pre-Honeycomb, force exactly one frame of the previous size - // to render because the surface change is only seen by GLES after we - // have swapped the back buffer (i.e. the buffer size only changes - // after the next swap buffer). We need to make sure Gecko's view - // resizes when Android's buffer resizes. - // In Honeycomb, the buffer size changes immediately, so rendering a - // frame of the previous size is unnecessary (and wrong). - if (mDrawMode == DRAW_GLES_2 && - (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)) { - // When we get a surfaceChange event, we have 0 to n paint events - // waiting in the Gecko event queue. We will make the first - // succeed and the abort the others. - mDrawSingleFrame = true; - if (!mInDrawing) { - // Queue at least one paint event in case none are queued. - GeckoAppShell.scheduleRedraw(); - } - GeckoAppShell.geckoEventSync(); - mDrawSingleFrame = false; - mAbortDraw = false; - } - - if (mShowingSplashScreen) - drawSplashScreen(holder, width, height); - - mSurfaceLock.lock(); - - if (mInDrawing) { - Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!"); - } - - boolean invalidSize; - - if (width == 0 || height == 0) { - mSoftwareBitmap = null; - mSoftwareBuffer = null; - mSoftwareBufferCopy = null; - invalidSize = true; - } else { - invalidSize = false; - } - - boolean doSyncDraw = - mDrawMode == DRAW_2D && - !invalidSize && - GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning); - mSyncDraw = doSyncDraw; - - mFormat = format; - mWidth = width; - mHeight = height; - mSurfaceValid = true; - - Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height); - - try { - DisplayMetrics metrics = new DisplayMetrics(); - GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height, - metrics.widthPixels, metrics.heightPixels); - GeckoAppShell.sendEventToGecko(e); - } finally { - mSurfaceLock.unlock(); - } - - if (doSyncDraw) { - GeckoAppShell.scheduleRedraw(); - - Object syncDrawObject = null; - try { - syncDrawObject = mSyncDraws.take(); - } catch (InterruptedException ie) { - Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie); - } - if (syncDrawObject != null) { - if (syncDrawObject instanceof Bitmap) - draw(holder, (Bitmap)syncDrawObject); - else - draw(holder, (ByteBuffer)syncDrawObject); - } else { - Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null"); - } - } else if (!mShowingSplashScreen) { - // Make sure a frame is drawn before we return - // otherwise we see artifacts or a black screen - GeckoAppShell.scheduleRedraw(); - GeckoAppShell.geckoEventSync(); - } - } - - public void surfaceCreated(SurfaceHolder holder) { - Log.i(LOG_FILE_NAME, "surface created"); - GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED); - GeckoAppShell.sendEventToGecko(e); - if (mShowingSplashScreen) - drawSplashScreen(); - } - - public void surfaceDestroyed(SurfaceHolder holder) { - Log.i(LOG_FILE_NAME, "surface destroyed"); - mSurfaceValid = false; - mSoftwareBuffer = null; - mSoftwareBufferCopy = null; - mSoftwareBitmap = null; - GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED); - if (mDrawMode == DRAW_GLES_2) { - // Ensure GL cleanup occurs before we return. - GeckoAppShell.sendEventToGeckoSync(e); - } else { - GeckoAppShell.sendEventToGecko(e); - } - } - - public Bitmap getSoftwareDrawBitmap() { - if (mSoftwareBitmap == null || - mSoftwareBitmap.getHeight() != mHeight || - mSoftwareBitmap.getWidth() != mWidth) { - mSoftwareBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565); - } - - mDrawMode = DRAW_2D; - return mSoftwareBitmap; - } - - public ByteBuffer getSoftwareDrawBuffer() { - // We store pixels in 565 format, so two bytes per pixel (explaining - // the * 2 in the following check/allocation) - if (mSoftwareBuffer == null || - mSoftwareBuffer.capacity() != (mWidth * mHeight * 2)) { - mSoftwareBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 2); - } - - if (mSoftwareBufferCopy == null || - mSoftwareBufferCopy.getHeight() != mHeight || - mSoftwareBufferCopy.getWidth() != mWidth) { - mSoftwareBufferCopy = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565); - } - - mDrawMode = DRAW_2D; - return mSoftwareBuffer; - } - - public Surface getSurface() { - return getHolder().getSurface(); - } - - /* - * Called on Gecko thread - */ - - public static final int DRAW_ERROR = 0; - public static final int DRAW_GLES_2 = 1; - public static final int DRAW_2D = 2; - // Drawing is disable when the surface buffer - // has changed size but we haven't yet processed the - // resize event. - public static final int DRAW_DISABLED = 3; - - public int beginDrawing() { - if (mInDrawing) { - Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!"); - return DRAW_ERROR; - } - - // Once we drawn our first frame after resize we can ignore - // the other draw events until we handle the resize events. - if (mAbortDraw) { - return DRAW_DISABLED; - } - - /* Grab the lock, which we'll hold while we're drawing. - * It gets released in endDrawing(), and is also used in surfaceChanged - * to make sure that we don't change our surface details while - * we're in the middle of drawing (and especially in the middle of - * executing beginDrawing/endDrawing). - * - * We might not need to hold this lock in between - * beginDrawing/endDrawing, and might just be able to make - * surfaceChanged, beginDrawing, and endDrawing synchronized, - * but this way is safer for now. - */ - mSurfaceLock.lock(); - - if (!mSurfaceValid) { - Log.e(LOG_FILE_NAME, "Surface not valid"); - mSurfaceLock.unlock(); - return DRAW_ERROR; - } - - mInDrawing = true; - mDrawMode = DRAW_GLES_2; - return DRAW_GLES_2; - } - - public void endDrawing() { - if (!mInDrawing) { - Log.e(LOG_FILE_NAME, "endDrawing without beginDrawing!"); - return; - } - - if (mDrawSingleFrame) - mAbortDraw = true; - - try { - if (!mSurfaceValid) { - Log.e(LOG_FILE_NAME, "endDrawing with false mSurfaceValid"); - return; - } - } finally { - mInDrawing = false; - - if (!mSurfaceLock.isHeldByCurrentThread()) - Log.e(LOG_FILE_NAME, "endDrawing while mSurfaceLock not held by current thread!"); - - mSurfaceLock.unlock(); - } - } - - /* How this works: - * Whenever we want to draw, we want to be sure that we do not lock - * the canvas unless we're sure we can draw. Locking the canvas clears - * the canvas to black in most cases, causing a black flash. - * At the same time, the surface can resize/disappear at any moment - * unless the canvas is locked. - * Draws originate from a different thread so the surface could change - * at any moment while we try to draw until we lock the canvas. - * - * Also, never try to lock the canvas while holding the surface lock - * unless you're in SurfaceChanged, in which case the canvas was already - * locked. Surface lock -> Canvas lock will lead to AB-BA deadlocks. - */ - public void draw2D(Bitmap bitmap, int width, int height) { - // mSurfaceLock ensures that we get mSyncDraw/mSoftwareBitmap/etc. - // set correctly before determining whether we should do a sync draw - mSurfaceLock.lock(); - try { - if (mSyncDraw) { - if (bitmap != mSoftwareBitmap || width != mWidth || height != mHeight) - return; - mSyncDraw = false; - try { - mSyncDraws.put(bitmap); - } catch (InterruptedException ie) { - Log.e(LOG_FILE_NAME, "Threw exception while getting sync draws queue: ", ie); - } - return; - } - } finally { - mSurfaceLock.unlock(); - } - - draw(getHolder(), bitmap); - } - - public void draw2D(ByteBuffer buffer, int stride) { - mSurfaceLock.lock(); - try { - if (mSyncDraw) { - if (buffer != mSoftwareBuffer || stride != (mWidth * 2)) - return; - mSyncDraw = false; - try { - mSyncDraws.put(buffer); - } catch (InterruptedException ie) { - Log.e(LOG_FILE_NAME, "Threw exception while getting sync bitmaps queue: ", ie); - } - return; - } - } finally { - mSurfaceLock.unlock(); - } - - draw(getHolder(), buffer); - } - - @Override - public boolean onCheckIsTextEditor () { - return false; - } - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - outAttrs.inputType = InputType.TYPE_CLASS_TEXT; - outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE; - outAttrs.actionLabel = null; - mKeyListener = TextKeyListener.getInstance(); - - if (mIMEState == IME_STATE_PASSWORD) - outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD; - else if (mIMETypeHint.equalsIgnoreCase("url")) - outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_URI; - else if (mIMETypeHint.equalsIgnoreCase("email")) - outAttrs.inputType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; - else if (mIMETypeHint.equalsIgnoreCase("search")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH; - else if (mIMETypeHint.equalsIgnoreCase("tel")) - outAttrs.inputType = InputType.TYPE_CLASS_PHONE; - else if (mIMETypeHint.equalsIgnoreCase("number") || - mIMETypeHint.equalsIgnoreCase("range")) - outAttrs.inputType = InputType.TYPE_CLASS_NUMBER; - else if (mIMETypeHint.equalsIgnoreCase("datetime") || - mIMETypeHint.equalsIgnoreCase("datetime-local")) - outAttrs.inputType = InputType.TYPE_CLASS_DATETIME | - InputType.TYPE_DATETIME_VARIATION_NORMAL; - else if (mIMETypeHint.equalsIgnoreCase("date")) - outAttrs.inputType = InputType.TYPE_CLASS_DATETIME | - InputType.TYPE_DATETIME_VARIATION_DATE; - else if (mIMETypeHint.equalsIgnoreCase("time")) - outAttrs.inputType = InputType.TYPE_CLASS_DATETIME | - InputType.TYPE_DATETIME_VARIATION_TIME; - else if (mIMEModeHint.equalsIgnoreCase("numeric")) - outAttrs.inputType = InputType.TYPE_CLASS_NUMBER | - InputType.TYPE_NUMBER_FLAG_SIGNED | - InputType.TYPE_NUMBER_FLAG_DECIMAL; - else if (mIMEModeHint.equalsIgnoreCase("digit")) - outAttrs.inputType = InputType.TYPE_CLASS_NUMBER; - else if (mIMEModeHint.equalsIgnoreCase("uppercase")) - outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; - else if (mIMEModeHint.equalsIgnoreCase("lowercase")) - outAttrs.inputType = InputType.TYPE_CLASS_TEXT; - else if (mIMEModeHint.equalsIgnoreCase("titlecase")) - outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS; - else if (mIMEModeHint.equalsIgnoreCase("autocapitalized")) - outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; - - if (mIMEActionHint.equalsIgnoreCase("go")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_GO; - else if (mIMEActionHint.equalsIgnoreCase("done")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE; - else if (mIMEActionHint.equalsIgnoreCase("next")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT; - else if (mIMEActionHint.equalsIgnoreCase("search")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH; - else if (mIMEActionHint.equalsIgnoreCase("send")) - outAttrs.imeOptions = EditorInfo.IME_ACTION_SEND; - else if (mIMEActionHint != null && mIMEActionHint.length() != 0) - outAttrs.actionLabel = mIMEActionHint; - - if (mIMELandscapeFS == false) - outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI; - - inputConnection.reset(); - return inputConnection; - } - - public void setEditable(String contents) - { - mEditable.removeSpan(inputConnection); - mEditable.replace(0, mEditable.length(), contents); - mEditable.setSpan(inputConnection, 0, contents.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - Selection.setSelection(mEditable, contents.length()); - } - - public void initEditable(String contents) - { - mEditable = mEditableFactory.newEditable(contents); - mEditable.setSpan(inputConnection, 0, contents.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - Selection.setSelection(mEditable, contents.length()); - } - - // accelerometer - public void onAccuracyChanged(Sensor sensor, int accuracy) - { - } - - public void onSensorChanged(SensorEvent event) - { - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - } - - // geolocation - public void onLocationChanged(Location location) - { - GeckoAppShell.sendEventToGecko(new GeckoEvent(location)); - } - - public void onProviderDisabled(String provider) - { - } - - public void onProviderEnabled(String provider) - { - } - - public void onStatusChanged(String provider, int status, Bundle extras) - { - } - - // event stuff - public boolean onTouchEvent(MotionEvent event) { - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (event.isSystem()) - return super.onKeyPreIme(keyCode, event); - - switch (event.getAction()) { - case KeyEvent.ACTION_DOWN: - return processKeyDown(keyCode, event, true); - case KeyEvent.ACTION_UP: - return processKeyUp(keyCode, event, true); - case KeyEvent.ACTION_MULTIPLE: - return onKeyMultiple(keyCode, event.getRepeatCount(), event); - } - return super.onKeyPreIme(keyCode, event); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - return processKeyDown(keyCode, event, false); - } - - private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - if (event.getRepeatCount() == 0) { - event.startTracking(); - return true; - } else { - return false; - } - case KeyEvent.KEYCODE_MENU: - if (event.getRepeatCount() == 0) { - event.startTracking(); - break; - } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) { - break; - } - // Ignore repeats for KEYCODE_MENU; they confuse the widget code. - return false; - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_SEARCH: - return false; - case KeyEvent.KEYCODE_DEL: - // See comments in GeckoInputConnection.onKeyDel - if (inputConnection != null && - inputConnection.onKeyDel()) { - return true; - } - break; - case KeyEvent.KEYCODE_ENTER: - if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 && - mIMEActionHint.equalsIgnoreCase("next")) - event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB); - break; - default: - break; - } - - if (isPreIme && mIMEState != IME_STATE_DISABLED && - (event.getMetaState() & KeyEvent.META_ALT_ON) == 0) - // Let active IME process pre-IME key events - return false; - - // KeyListener returns true if it handled the event for us. - if (mIMEState == IME_STATE_DISABLED || - keyCode == KeyEvent.KEYCODE_ENTER || - keyCode == KeyEvent.KEYCODE_DEL || - (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || - !mKeyListener.onKeyDown(this, mEditable, keyCode, event)) - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - return processKeyUp(keyCode, event, false); - } - - private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - if (!event.isTracking() || event.isCanceled()) - return false; - break; - default: - break; - } - - if (isPreIme && mIMEState != IME_STATE_DISABLED && - (event.getMetaState() & KeyEvent.META_ALT_ON) == 0) - // Let active IME process pre-IME key events - return false; - - if (mIMEState == IME_STATE_DISABLED || - keyCode == KeyEvent.KEYCODE_ENTER || - keyCode == KeyEvent.KEYCODE_DEL || - (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || - !mKeyListener.onKeyUp(this, mEditable, keyCode, event)) - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - } - - @Override - public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - } - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - case KeyEvent.KEYCODE_MENU: - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.toggleSoftInputFromWindow(getWindowToken(), - imm.SHOW_FORCED, 0); - return true; - default: - break; - } - return false; - } - - // Is this surface valid for drawing into? - boolean mSurfaceValid; - - // Are we actively between beginDrawing/endDrawing? - boolean mInDrawing; - - // Used to finish the current buffer before changing the surface size - boolean mDrawSingleFrame = false; - boolean mAbortDraw = false; - - // Are we waiting for a buffer to draw in surfaceChanged? - boolean mSyncDraw; - - // True if gecko requests a buffer - int mDrawMode; - - static boolean mShowingSplashScreen = true; - static String mSplashURL = ""; - - // let's not change stuff around while we're in the middle of - // starting drawing, ending drawing, or changing surface - // characteristics - ReentrantLock mSurfaceLock; - - // Surface format, from surfaceChanged. Largely - // useless. - int mFormat; - - // the dimensions of the surface - int mWidth; - int mHeight; - - // the dimensions of the buffer we're using for drawing, - // that is the software buffer or the EGLSurface - int mBufferWidth; - int mBufferHeight; - - // IME stuff - public static final int IME_STATE_DISABLED = 0; - public static final int IME_STATE_ENABLED = 1; - public static final int IME_STATE_PASSWORD = 2; - public static final int IME_STATE_PLUGIN = 3; - - GeckoInputConnection inputConnection; - KeyListener mKeyListener; - Editable mEditable; - Editable.Factory mEditableFactory; - int mIMEState; - String mIMETypeHint; - String mIMEModeHint; - String mIMEActionHint; - boolean mIMELandscapeFS; - - // Software rendering - Bitmap mSoftwareBitmap; - ByteBuffer mSoftwareBuffer; - Bitmap mSoftwareBufferCopy; - - final SynchronousQueue<Object> mSyncDraws = new SynchronousQueue<Object>(); -} -
deleted file mode 100644 --- a/embedding/android/LauncherShortcuts.java.in +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#filter substitution -package @ANDROID_PACKAGE_NAME@; - -import java.io.*; -import java.util.*; - -import org.json.*; - -import org.mozilla.gecko.*; - -import android.os.*; -import android.content.*; -import android.app.*; -import android.text.*; -import android.util.*; -import android.widget.*; -import android.database.sqlite.*; -import android.database.*; -import android.view.*; -import android.net.Uri; -import android.graphics.*; - - -public class LauncherShortcuts extends Activity { - - private ArrayList <HashMap<String, String>> mWebappsList; - private File mWebappsFolder; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(R.layout.launch_app_list); - - final Intent intent = getIntent(); - final String action = intent.getAction(); - - if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) { - // Doing it as a background task, as it involves file access - new FetchWebApps().execute(); - } - } - - public void onListItemClick(int id) { - HashMap<String, String> map = mWebappsList.get(id); - - String uri = map.get("uri").toString(); - String title = map.get("title").toString(); - String appKey = map.get("appKey").toString(); - String favicon = map.get("favicon").toString(); - - File manifestFile = new File(mWebappsFolder, appKey + "/manifest.json"); - - // Parse the contents into a string - String manifestJson = new String(); - try { - BufferedReader in = new BufferedReader(new FileReader(manifestFile)); - String line = new String(); - - while ((line = in.readLine()) != null) { - manifestJson += line; - } - } catch (IOException e) { } - - try { - JSONObject manifest = (JSONObject) new JSONTokener(manifestJson).nextValue(); - uri += manifest.getString("launch_path"); - } catch (JSONException e) { } - - Intent shortcutintent = new Intent("org.mozilla.gecko.WEBAPP"); - shortcutintent.setClass(this, App.class); - shortcutintent.putExtra("args", "--webapp=" + uri); - - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutintent); - - DisplayMetrics dm = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(dm); - int size; - switch (dm.densityDpi) { - case DisplayMetrics.DENSITY_MEDIUM: - size = 48; - break; - case DisplayMetrics.DENSITY_HIGH: - size = 72; - break; - default: - size = 72; - } - - Bitmap bitmap = BitmapFactory.decodeFile(favicon); - if (bitmap != null) { - Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, scaledBitmap); - } - - // Now, return the result to the launcher - setResult(RESULT_OK, intent); - finish(); - } - - private class FetchWebApps extends AsyncTask<Void, Void, Void> { - - @Override - protected Void doInBackground(Void... unused) { - mWebappsList = null; - - Context context = getApplicationContext(); - - File home = new File(context.getFilesDir(), "mozilla"); - if (!home.exists()) - home = new File(context.getExternalFilesDir(null).getPath(), "mozilla"); - - if (!home.exists()) - return null; - - File profile = null; - String[] files = home.list(); - for (String file : files) { - if (file.endsWith(".default")) { - profile = new File(home, file); - break; - } - } - - if (profile == null) - return null; - - // Save the folder path to be used during click event - mWebappsFolder = new File(profile, "webapps"); - if (!mWebappsFolder.exists()) - return null; - - File webapps = new File(mWebappsFolder, "webapps.json"); - if (!webapps.exists()) - return null; - - // Parse the contents into a string - String webappsJson = new String(); - try { - BufferedReader in = new BufferedReader(new FileReader(webapps)); - String line = new String(); - - while ((line = in.readLine()) != null) { - webappsJson += line; - } - } catch (IOException e) { } - - if (webappsJson.length() == 0) - return null; - - mWebappsList = new ArrayList<HashMap<String, String>>(); - - try { - JSONObject webApps = (JSONObject) new JSONTokener(webappsJson).nextValue(); - - Iterator<Object> appKeys = webApps.keys(); - HashMap<String, String> map; - - while (appKeys.hasNext()) { - String appKey = appKeys.next().toString(); - JSONObject app = webApps.getJSONObject(appKey); - - map = new HashMap<String, String>(); - map.put("appKey", appKey); - map.put("favicon", mWebappsFolder.getPath() + "/" + appKey + "/icon.png"); - map.put("title", app.getString("title")); - map.put("uri", app.getString("appURI")); - - mWebappsList.add(map); - } - - } catch (JSONException e) {} - - return null; - } - - @Override - protected void onPostExecute(Void unused) { - if (mWebappsList != null) { - AlertDialog.Builder builder; - - if (android.os.Build.VERSION.SDK_INT >= 11) { - builder = new AlertDialog.Builder(LauncherShortcuts.this, AlertDialog.THEME_HOLO_LIGHT); - } else { - builder = new AlertDialog.Builder(LauncherShortcuts.this); - } - - builder.setTitle(R.string.launcher_shortcuts_title); - builder.setAdapter(new SimpleAdapter( - LauncherShortcuts.this, - mWebappsList, - R.layout.launch_app_listitem, - new String[] { "favicon", "title" }, - new int[] { R.id.favicon, R.id.title } - ), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.dismiss(); - onListItemClick(id); - finish(); - } - }); - - builder.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - dialog.dismiss(); - finish(); - } - }); - - builder.create().show(); - } else { - Toast.makeText(LauncherShortcuts.this, R.string.launcher_shortcuts_empty, Toast.LENGTH_LONG).show(); - finish(); - } - } - } -}
deleted file mode 100644 --- a/embedding/android/Makefile.in +++ /dev/null @@ -1,170 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk -include $(topsrcdir)/ipc/app/defs.mk - -JAVAFILES = \ - GeckoApp.java \ - GeckoAppShell.java \ - GeckoConnectivityReceiver.java \ - GeckoEvent.java \ - GeckoSurfaceView.java \ - GeckoInputConnection.java \ - AlertNotification.java \ - SurfaceInfo.java \ - GeckoBatteryManager.java \ - VideoPlayer.java \ - GeckoNetworkManager.java \ - GeckoScreenOrientationListener.java \ - $(NULL) - -ifdef MOZ_WEBSMS_BACKEND -JAVAFILES += GeckoSmsManager.java -endif - -PROCESSEDJAVAFILES = \ - App.java \ - Restarter.java \ - NotificationHandler.java \ - LauncherShortcuts.java \ - SmsManager.java \ - $(NULL) - - -ifneq (,$(findstring -march=armv7,$(OS_CFLAGS))) -MIN_CPU_VERSION=7 -else -MIN_CPU_VERSION=5 -endif - -ifeq (,$(ANDROID_VERSION_CODE)) -# increment the version code by 1 so xul fennec will win any compatability ties -ANDROID_VERSION_CODE=$(shell echo `$(PYTHON) $(topsrcdir)/toolkit/xre/make-platformini.py --print-buildid | cut -c1-10` + 1 | bc) -endif - -DEFINES += \ - -DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \ - -DMOZ_APP_DISPLAYNAME="$(MOZ_APP_DISPLAYNAME)" \ - -DMOZ_APP_NAME=$(MOZ_APP_NAME) \ - -DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \ - -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) \ - -DMOZ_MIN_CPU_VERSION=$(MIN_CPU_VERSION) \ - -DMOZ_CRASHREPORTER=$(MOZ_CRASHREPORTER) \ - -DANDROID_VERSION_CODE=$(ANDROID_VERSION_CODE) \ - -DMOZILLA_OFFICIAL=$(MOZILLA_OFFICIAL) \ - $(NULL) - -GARBAGE += \ - AndroidManifest.xml \ - classes.dex \ - $(PROCESSEDJAVAFILES) \ - gecko.ap_ \ - res/values/strings.xml \ - R.java \ - $(NULL) - -# Bug 567884 - Need a way to find appropriate icons during packaging -ifeq ($(MOZ_APP_NAME),fennec) -ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_48x48.png -ICON_PATH_HDPI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_72x72.png - -# we released these builds to the public with shared IDs and need to keep them -ifeq (org.mozilla.firefox,$(ANDROID_PACKAGE_NAME)) -DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.firefox.sharedID" -else ifeq (org.mozilla.firefox_beta,$(ANDROID_PACKAGE_NAME)) -DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.firefox.sharedID" -else ifeq (org.mozilla.fennec_aurora,$(ANDROID_PACKAGE_NAME)) -DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.fennec.sharedID" -else ifeq (org.mozilla.fennec,$(ANDROID_PACKAGE_NAME)) -DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.fennec.sharedID" -endif - -else -ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon48.png -ICON_PATH_HDPI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon64.png -DEFINES += -DMOZ_ANDROID_SHARED_ID="$(ANDROID_PACKAGE_NAME).sharedID" -endif - -RES_LAYOUT = \ - res/layout/notification_progress.xml \ - res/layout/notification_progress_text.xml \ - res/layout/notification_icon_text.xml \ - res/layout/launch_app_list.xml \ - res/layout/launch_app_listitem.xml \ - res/layout/videoplayer.xml \ - $(NULL) - -RES_VALUES = res/values/colors.xml res/values/themes.xml - -JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar - -ifdef MOZ_CRASHREPORTER -PROCESSEDJAVAFILES += CrashReporter.java -MOZ_ANDROID_DRAWABLES += embedding/android/resources/drawable/crash_reporter.png -RES_LAYOUT += res/layout/crash_reporter.xml -endif - -MOZ_ANDROID_DRAWABLES += embedding/android/resources/drawable/desktop_notification.png - -MOZ_ANDROID_DRAWABLES += $(shell if test -e $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn; then cat $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn | tr '\n' ' '; fi) - -RESOURCES=$(RES_LAYOUT) $(RES_VALUES) - -RES_DIRS= \ - res/layout \ - res/values \ - $(NULL) - -include $(topsrcdir)/config/rules.mk - -# Override the Java settings with some specific android settings -include $(topsrcdir)/config/android-common.mk - -# Note that we're going to set up a dependency directly between embed_android.dex and the java files -# Instead of on the .class files, since more than one .class file might be produced per .java file -classes.dex: $(JAVAFILES) $(PROCESSEDJAVAFILES) R.java - $(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES)) $(PROCESSEDJAVAFILES) R.java - $(DX) --dex --output=$@ classes - -AndroidManifest.xml $(PROCESSEDJAVAFILES): % : %.in - $(PYTHON) $(topsrcdir)/config/Preprocessor.py \ - $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@ - -res/drawable/icon.png: $(MOZ_APP_ICON) - $(NSINSTALL) -D res/drawable - cp $(ICON_PATH) $@ - -res/drawable-hdpi/icon.png: $(MOZ_APP_ICON) - $(NSINSTALL) -D res/drawable-hdpi - cp $(ICON_PATH_HDPI) $@ - -$(RES_DIRS): - rm -rf $@ - $(NSINSTALL) -D $@ - -RES_DRAWABLE = $(addprefix res/drawable/,$(notdir $(MOZ_ANDROID_DRAWABLES))) - -$(RES_DRAWABLE): $(addprefix $(topsrcdir)/,$(MOZ_ANDROID_DRAWABLES)) - $(NSINSTALL) -D res/drawable - $(NSINSTALL) $^ res/drawable/ - -$(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES)) - @echo "creating $@" - $(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@) - - -R.java: $(MOZ_APP_ICON) $(RES_LAYOUT) $(RES_DRAWABLE) $(RES_VALUES) res/drawable/icon.png res/drawable-hdpi/icon.png AndroidManifest.xml chrome - $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -J . --custom-package org.mozilla.gecko - -gecko.ap_: AndroidManifest.xml res/drawable/icon.png res/drawable-hdpi/icon.png $(RES_LAYOUT) $(RES_DRAWABLE) $(RES_VALUES) res/values/strings.xml FORCE - $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@ - -libs:: classes.dex - $(INSTALL) classes.dex $(FINAL_TARGET)
deleted file mode 100644 --- a/embedding/android/NotificationHandler.java.in +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#filter substitution -package @ANDROID_PACKAGE_NAME@; - -import android.app.NotificationManager; -import android.content.Intent; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.os.Bundle; -import android.util.Log; -import android.net.Uri; - -public class NotificationHandler - extends BroadcastReceiver -{ - @Override - public void onReceive(Context context, Intent intent) { - if (intent != null) - handleIntent(context, intent); - } - - protected void handleIntent(Context context, Intent notificationIntent) { - String action = notificationIntent.getAction(); - String alertName = ""; - String alertCookie = ""; - Uri data = notificationIntent.getData(); - if (data != null) { - alertName = data.getSchemeSpecificPart(); - alertCookie = data.getFragment(); - if (alertCookie == null) - alertCookie = ""; - } - - Log.i("GeckoAppJava", "NotificationHandler.handleIntent\n" + - "- action = '" + action + "'\n" + - "- alertName = '" + alertName + "'\n" + - "- alertCookie = '" + alertCookie + "'"); - - int notificationID = alertName.hashCode(); - - Log.i("GeckoAppJava", "Handle notification ID " + notificationID); - - if (App.mAppContext != null) { - // This should call the observer, if any - App.mAppContext.handleNotification(action, alertName, alertCookie); - } else { - // The app is not running, just cancel this notification - NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(notificationID); - } - - if (App.ACTION_ALERT_CLICK.equals(action)) { - // Start or bring to front the main activity - Intent appIntent = new Intent(Intent.ACTION_MAIN); - appIntent.setClassName(context, "@ANDROID_PACKAGE_NAME@.App"); - appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - appIntent.putExtra("args", "-alert " + alertName + (alertCookie.length() > 0 ? "#" + alertCookie : "")); - try { - Log.i("GeckoAppJava", "startActivity with intent: Action='" + appIntent.getAction() + "'" + - ", args='" + appIntent.getStringExtra("args") + "'" ); - context.startActivity(appIntent); - } catch (ActivityNotFoundException e) { - Log.e("GeckoAppJava", "NotificationHandler Exception: ", e); - } - } - } -}
deleted file mode 100644 --- a/embedding/android/Restarter.java.in +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#filter substitution -package @ANDROID_PACKAGE_NAME@; - -import android.app.*; -import android.content.*; -import android.util.*; -import android.os.*; -import java.io.*; -import org.mozilla.gecko.GeckoAppShell; - -public class Restarter extends Activity { - - @Override - public void onCreate(Bundle savedInstanceState) { - Log.i("Restarter", "trying to restart @MOZ_APP_NAME@"); - try { - int countdown = 40; - while (GeckoAppShell.checkForGeckoProcs() && --countdown > 0) { - // Wait for the old process to die before we continue - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException ie) {} - } - - if (countdown <= 0) { - // if the countdown expired, something is hung - GeckoAppShell.killAnyZombies(); - countdown = 10; - // wait for the kill to take effect - while (GeckoAppShell.checkForGeckoProcs() && --countdown > 0) { - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException ie) {} - } - } - } catch (Exception e) { - Log.i("Restarter", e.toString()); - } - try { - String action = "android.intent.action.MAIN"; - Intent intent = new Intent(action); - intent.setClassName("@ANDROID_PACKAGE_NAME@", - "@ANDROID_PACKAGE_NAME@.App"); - Bundle b = getIntent().getExtras(); - if (b != null) - intent.putExtras(b); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - Log.i("GeckoAppJava", intent.toString()); - startActivity(intent); - } catch (Exception e) { - Log.i("Restarter", e.toString()); - } - // Give the new process time to start before we die - GeckoAppShell.waitForAnotherGeckoProc(); - System.exit(0); - } -};
deleted file mode 100644 --- a/embedding/android/SmsManager.java.in +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -#ifdef MOZ_WEBSMS_BACKEND -import org.mozilla.gecko.GeckoSmsManager; -#endif - -class SmsManager -{ - static private ISmsManager sInstance = null; - - static public ISmsManager getInstance() { -#ifdef MOZ_WEBSMS_BACKEND - if (sInstance == null) { - sInstance = new GeckoSmsManager(); - } -#endif - return sInstance; - } -} - -interface ISmsManager -{ - public void start(); - public void stop(); - public void shutdown(); - - public void send(String aNumber, String aMessage, int aRequestId); - public void getMessage(int aMessageId, int aRequestId); - public void deleteMessage(int aMessageId, int aRequestId); - public void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId); - public void getNextMessageInList(int aListId, int aRequestId); - public void clearMessageList(int aListId); -}
deleted file mode 100644 --- a/embedding/android/SurfaceInfo.java +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -public class SurfaceInfo { - public int format; - public int width; - public int height; -}
deleted file mode 100644 --- a/embedding/android/locales/Makefile.in +++ /dev/null @@ -1,42 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ -relativesrcdir = @relativesrcdir@ - -include $(DEPTH)/config/autoconf.mk - -# special case some locale codes, he and id -# http://code.google.com/p/android/issues/detail?id=3639 -AB_rCD = $(if $(filter he, $(AB_CD)),iw,$(if $(filter id, $(AB_CD)),in,$(subst -,-r,$(AB_CD)))) - -STRINGSPATH = $(call core_abspath,$(call MERGE_FILE,android_strings.dtd)) -ifeq (,$(XPI_NAME)) -BRANDPATH = $(call core_abspath,$(DEPTH)/dist/bin/chrome/$(AB_CD)/locale/branding/brand.dtd) -else -BRANDPATH = $(call core_abspath,$(DIST)/xpi-stage/$(XPI_NAME)/chrome/$(AB_CD)/locale/branding/brand.dtd) -endif - -DEFINES += -DAB_CD=$(AB_CD) - -libs realchrome:: ../res/values/strings.xml ; - -chrome-%:: AB_CD=$* -chrome-%:: - @$(MAKE) ../res/values-$(AB_rCD)/strings.xml AB_CD=$* - -%/strings.xml: FORCE - $(NSINSTALL) -D $* - # we don't have branding yet, but we need it. Call it explicitly - @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales realchrome - $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) \ - -DBRANDPATH="$(BRANDPATH)" \ - -DSTRINGSPATH="$(STRINGSPATH)" \ - $(srcdir)/../strings.xml.in \ - > $@ - -include $(topsrcdir)/config/rules.mk
deleted file mode 100644 --- a/embedding/android/locales/en-US/android_strings.dtd +++ /dev/null @@ -1,25 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - -<!ENTITY splash_firstrun "Setting up &brandShortName;\u2026"> - -<!ENTITY no_space_to_start_error "There is not enough space available for &brandShortName; to start."> -<!ENTITY error_loading_file "An error occurred when trying to load files required to run &brandShortName;"> - -<!ENTITY crash_reporter_title "&brandShortName; Crash Reporter"> -<!ENTITY crash_message "&brandShortName; has crashed. Your tabs should be listed on the &brandShortName; Start page when you restart."> -<!ENTITY crash_help_message "Please help us fix this problem!"> -<!ENTITY crash_send_report_message "Send Mozilla a crash report"> -<!ENTITY crash_include_url "Include page address"> -<!ENTITY crash_close_label "Close"> -<!ENTITY crash_restart_label "Restart &brandShortName;"> -<!ENTITY sending_crash_report "Sending crash report\u2026"> -<!ENTITY exit_label "Exit"> -<!ENTITY continue_label "Continue"> - -<!ENTITY launcher_shortcuts_title "&brandShortName; Web Apps"> -<!ENTITY launcher_shortcuts_empty "No web apps were found"> - -<!ENTITY choose_file "Choose File">
deleted file mode 100644 --- a/embedding/android/locales/l10n.ini +++ /dev/null @@ -1,9 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -[general] -depth = ../../.. - -[compare] -dirs = embedding/android
deleted file mode 100644 --- a/embedding/android/locales/moz.build +++ /dev/null @@ -1,5 +0,0 @@ -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -
deleted file mode 100644 --- a/embedding/android/moz.build +++ /dev/null @@ -1,6 +0,0 @@ -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DIRS += ['locales']
deleted file mode 100644 index 5804e08a772e010f0c986460898fa18f321c9311..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 2c557bf46d1e57590cd0ace752e5b26756e2865f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 --- a/embedding/android/resources/layout/crash_reporter.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:padding="10px" > - <TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="10px" - android:textStyle="bold" - android:text="@string/crash_message"/> - <TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="10px" - android:text="@string/crash_help_message"/> - <CheckBox android:id="@+id/send_report" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:checked="true" - android:text="@string/crash_send_report_message" /> - <CheckBox android:id="@+id/include_url" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/crash_include_url" /> - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - android:padding="10px" - android:gravity="center_horizontal" > - <Button android:id="@+id/close" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginRight="10px" - android:minWidth="120sp" - android:onClick="onCloseClick" - android:text="@string/crash_close_label" /> - <Button android:id="@+id/restart" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="10px" - android:minWidth="120sp" - android:onClick="onRestartClick" - android:text="@string/crash_restart_label" /> - </LinearLayout> -</LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/layout/launch_app_list.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="3dip" - android:orientation="vertical" - android:windowIsFloating="true"> - </LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/layout/launch_app_listitem.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeight" - android:paddingLeft="16dip" - android:paddingRight="16dip" - android:orientation="horizontal" - android:gravity="left"> - <ImageView - android:id="@+id/favicon" - android:layout_width="48dip" - android:layout_height="48dip" - android:layout_marginRight="12dip" - android:layout_gravity="center_vertical" - android:adjustViewBounds="true" - android:scaleType="fitCenter"/> - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="center_vertical" - android:textAppearance="?android:attr/textAppearanceLargeInverse" - android:ellipsize="marquee" - android:fadingEdge="horizontal"/> - </LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/layout/notification_icon_text.xml +++ /dev/null @@ -1,38 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:paddingLeft="5dp" - > - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <ImageView android:id="@+id/notificationImage" - android:layout_width="25dp" - android:layout_height="25dp" - android:scaleType="fitCenter" /> - <TextView android:id="@+id/notificationTitle" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:paddingLeft="4dp" - /> - </LinearLayout> - <TextView android:id="@+id/notificationText" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:paddingLeft="4dp" - /> -</LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/layout/notification_progress.xml +++ /dev/null @@ -1,57 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:paddingTop="7dp" - android:paddingLeft="5dp" - > - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <ImageView android:id="@+id/notificationImage" - android:layout_width="25dp" - android:layout_height="25dp" - android:scaleType="fitCenter" /> - <TextView android:id="@+id/notificationTitle" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:paddingLeft="10dp" - /> - </LinearLayout> - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <TextView android:id="@+id/notificationText" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="3dp" - /> - - <ProgressBar android:id="@+id/notificationProgressbar" - style="?android:attr/progressBarStyleHorizontal" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_marginTop="1dip" - android:layout_marginBottom="1dip" - android:layout_marginLeft="4dip" - android:layout_marginRight="10dip" - android:layout_centerHorizontal="true" /> - </LinearLayout> - -</LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/layout/notification_progress_text.xml +++ /dev/null @@ -1,50 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical" - android:paddingLeft="5dp" - > - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="horizontal" - > - <ImageView android:id="@+id/notificationImage" - android:layout_width="25dp" - android:layout_height="25dp" - android:scaleType="fitCenter" /> - <TextView android:id="@+id/notificationTitle" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:singleLine="true" - android:ellipsize="marquee" - android:fadingEdge="horizontal" - android:paddingLeft="4dp" - /> - </LinearLayout> - - <ProgressBar android:id="@+id/notificationProgressbar" - style="?android:attr/progressBarStyleHorizontal" - android:layout_width="fill_parent" - android:layout_height="16dip" - android:layout_marginTop="1dip" - android:layout_marginBottom="1dip" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip" - android:layout_centerHorizontal="true" /> - - <TextView android:id="@+id/notificationText" - android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:paddingLeft="4dp" - /> - -</LinearLayout>
deleted file mode 100644 --- a/embedding/android/resources/values/colors.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<resources> - <color name="splash_background">#000000</color> - <color name="splash_msgfont">#ffffff</color> - <color name="splash_urlfont">#000000</color> - <color name="splash_content">#ffffff</color> -</resources> -
deleted file mode 100644 --- a/embedding/android/resources/values/themes.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<resources> - <style name="GreyTheme" parent="@android:style/Theme.Light.NoTitleBar"> - <item name="android:windowBackground">@color/splash_background</item> - </style> -</resources>
deleted file mode 100644 --- a/embedding/android/strings.xml.in +++ /dev/null @@ -1,31 +0,0 @@ -#filter substitution -<?xml version="1.0" encoding="utf-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE resources [ -#includesubst @BRANDPATH@ -#includesubst @STRINGSPATH@ -]> -<resources> - <string name="splash_firstrun">&splash_firstrun;</string> - <string name="no_space_to_start_error">&no_space_to_start_error;</string> - <string name="error_loading_file">&error_loading_file;</string> - - <string name="crash_reporter_title">&crash_reporter_title;</string> - <string name="crash_message">&crash_message;</string> - <string name="crash_help_message">&crash_help_message;</string> - <string name="crash_send_report_message">&crash_send_report_message;</string> - <string name="crash_include_url">&crash_include_url;</string> - <string name="crash_close_label">&crash_close_label;</string> - <string name="crash_restart_label">&crash_restart_label;</string> - <string name="sending_crash_report">&sending_crash_report;</string> - <string name="exit_label">&exit_label;</string> - <string name="continue_label">&continue_label;</string> - - <string name="launcher_shortcuts_title">&launcher_shortcuts_title;</string> - <string name="launcher_shortcuts_empty">&launcher_shortcuts_empty;</string> - - <string name="choose_file">&choose_file;</string> -</resources>
--- a/mobile/locales/l10n.ini +++ b/mobile/locales/l10n.ini @@ -12,9 +12,8 @@ depth = ../.. all = mobile/android/locales/all-locales [compare] dirs = mobile mobile/android mobile/android/base [includes] toolkit = toolkit/locales/l10n.ini services_sync = services/sync/locales/l10n.ini -embedding_android = embedding/android/locales/l10n.ini