mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Patch from https://github.com/snorp/mozilla-central faster branch.
This commit is contained in:
parent
0e5f5831f8
commit
952b4094a1
@ -4343,7 +4343,7 @@ MOZ_RDF=1
|
||||
MOZ_REFLOW_PERF=
|
||||
MOZ_SAFE_BROWSING=
|
||||
MOZ_HELP_VIEWER=
|
||||
MOZ_SPELLCHECK=1
|
||||
MOZ_SPELLCHECK=
|
||||
MOZ_SVG_DLISTS=
|
||||
MOZ_TOOLKIT_SEARCH=1
|
||||
MOZ_UI_LOCALE=en-US
|
||||
|
@ -249,6 +249,10 @@
|
||||
#include "nsLocation.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
#if defined(ANDROID) && defined(DEBUG)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gDOMLeakPRLog;
|
||||
#endif
|
||||
@ -4525,6 +4529,9 @@ nsGlobalWindow::Dump(const nsAString& aStr)
|
||||
nsMemory::Free(cstr);
|
||||
}
|
||||
|
||||
#if defined(ANDROID) && defined(DEBUG)
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoDump", "%s", cstr);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,13 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#ifdef MOZ_SPELLCHECK
|
||||
#include "mozISpellCheckingEngine.h"
|
||||
#include "nsIEditorSpellCheck.h"
|
||||
#include "mozInlineSpellChecker.h"
|
||||
#include "nsIInlineSpellChecker.h"
|
||||
#endif
|
||||
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -107,7 +111,6 @@
|
||||
#include "nsEditorUtils.h"
|
||||
#include "nsEditorEventListener.h"
|
||||
#include "nsISelectionDisplay.h"
|
||||
#include "nsIInlineSpellChecker.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIParserService.h"
|
||||
@ -308,12 +311,14 @@ nsEditor::PostCreate()
|
||||
NotifyDocumentListeners(eDocumentCreated);
|
||||
NotifyDocumentListeners(eDocumentStateChanged);
|
||||
|
||||
#ifdef MOZ_SPELLCHECK
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||
PR_FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// update nsTextStateManager and caret if we have focus
|
||||
@ -426,11 +431,13 @@ nsEditor::PreDestroy(bool aDestroyingFrames)
|
||||
if (mDidPreDestroy)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef MOZ_SPELLCHECK
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let spellchecker clean up its observers etc. It is important not to
|
||||
// actually free the spellchecker here, since the spellchecker could have
|
||||
@ -1294,6 +1301,7 @@ nsEditor::MarkNodeDirty(nsIDOMNode* aNode)
|
||||
NS_IMETHODIMP nsEditor::GetInlineSpellChecker(bool autoCreate,
|
||||
nsIInlineSpellChecker ** aInlineSpellChecker)
|
||||
{
|
||||
#ifdef MOZ_SPELLCHECK
|
||||
NS_ENSURE_ARG_POINTER(aInlineSpellChecker);
|
||||
|
||||
if (mDidPreDestroy) {
|
||||
@ -1326,11 +1334,15 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(bool autoCreate,
|
||||
NS_IF_ADDREF(*aInlineSpellChecker = mInlineSpellChecker);
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::Observe(nsISupports* aSubj, const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
#ifdef MOZ_SPELLCHECK
|
||||
NS_ASSERTION(!strcmp(aTopic,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION),
|
||||
"Unexpected observer topic");
|
||||
@ -1354,6 +1366,9 @@ NS_IMETHODIMP nsEditor::Observe(nsISupports* aSubj, const char *aTopic,
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
|
||||
|
@ -123,5 +123,6 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="org.mozilla.gecko.AwesomeBar"></activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
211
embedding/android/AwesomeBar.java
Normal file
211
embedding/android/AwesomeBar.java
Normal file
@ -0,0 +1,211 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Wes Johnston <wjohnston@mozilla.com>
|
||||
* Mark Finkle <mfinkle@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
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 AwesomeBar extends ListActivity {
|
||||
public static final String URL_KEY = "url";
|
||||
public static final String TITLE_KEY = "title";
|
||||
public static final String CURRENT_URL_KEY = "currenturl";
|
||||
|
||||
public class AwesomeBarCursorAdapter extends SimpleCursorAdapter {
|
||||
private Cursor _cursor;
|
||||
private Context _context;
|
||||
|
||||
public AwesomeBarCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
|
||||
// Using the older, deprecated constructor so we can work on API < 11
|
||||
super(context, layout, c, from, to);
|
||||
_cursor = c;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
super.bindView(view, context, cursor);
|
||||
|
||||
// ImageView imageView = (ImageView) view.findViewById(R.id.favicon);
|
||||
// byte[] raw = cursor.getBlob(cursor.getColumnIndexOrThrow("favicon"));
|
||||
// Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(raw, 0, raw.length), 48, 48, true);
|
||||
// imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
private Cursor mCursor;
|
||||
private SQLiteDatabase mDb;
|
||||
private AwesomeBarCursorAdapter adapter;
|
||||
|
||||
private String getProfilePath() {
|
||||
File home = new File(getFilesDir(), "mozilla");
|
||||
if (!home.exists())
|
||||
return null;
|
||||
|
||||
File profile = null;
|
||||
String[] files = home.list();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].endsWith(".default")) {
|
||||
profile = new File(home, files[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (profile == null)
|
||||
return null;
|
||||
|
||||
File webapps = new File(profile, "places.sqlite");
|
||||
if (!webapps.exists())
|
||||
return null;
|
||||
|
||||
return webapps.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Log.d("AwesomeBar", "creating awesomebar");
|
||||
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
setContentView(R.layout.awesomebar_search);
|
||||
|
||||
// Load the list using a custom adapter so we can create the bitmaps
|
||||
adapter = new AwesomeBarCursorAdapter(
|
||||
this,
|
||||
R.layout.awesomebar_row,
|
||||
null,
|
||||
new String[] { TITLE_KEY, URL_KEY },
|
||||
new int[] { android.R.id.text1, android.R.id.text2 }
|
||||
);
|
||||
setListAdapter(adapter);
|
||||
|
||||
final EditText text = (EditText)findViewById(R.id.awesomebar_text);
|
||||
|
||||
String currentUrl = getIntent().getStringExtra(CURRENT_URL_KEY);
|
||||
if (currentUrl != null) {
|
||||
text.setText(currentUrl);
|
||||
text.selectAll();
|
||||
}
|
||||
|
||||
text.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
public void afterTextChanged(Editable s) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void beforeTextChanged(CharSequence s, int start, int count,
|
||||
int after) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence s, int start, int before,
|
||||
int count) {
|
||||
adapter.getFilter().filter(s.toString());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
text.setOnKeyListener(new View.OnKeyListener() {
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode != KeyEvent.KEYCODE_ENTER)
|
||||
return false;
|
||||
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(URL_KEY, text.getText().toString());
|
||||
setResult(Activity.RESULT_OK, resultIntent);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
DatabaseHelper dbHelper = new DatabaseHelper(this);
|
||||
mDb = dbHelper.getReadableDatabase();
|
||||
|
||||
adapter.setFilterQueryProvider(new FilterQueryProvider() {
|
||||
@Override
|
||||
public Cursor runQuery(CharSequence constraint) {
|
||||
|
||||
// _id column required for CursorAdapter; provide a dummy here
|
||||
mCursor = mDb.rawQuery(
|
||||
"SELECT 0 AS _id, title, url "
|
||||
+ "FROM moz_places "
|
||||
+ "WHERE (url LIKE ? OR title LIKE ?) "
|
||||
+ "LIMIT 12",
|
||||
new String[] {"%" + constraint.toString() + "%", "%" + constraint.toString() + "%",});
|
||||
|
||||
return mCursor;
|
||||
}
|
||||
});
|
||||
|
||||
// show unfiltered results initially
|
||||
adapter.getFilter().filter("");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mCursor != null) mCursor.close();
|
||||
if (mDb != null) mDb.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
Cursor cursor = (Cursor)l.getItemAtPosition(position);
|
||||
String url = cursor.getString(cursor.getColumnIndexOrThrow(URL_KEY));
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(URL_KEY, url);
|
||||
setResult(Activity.RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}
|
||||
}
|
174
embedding/android/DatabaseHelper.java
Normal file
174
embedding/android/DatabaseHelper.java
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.util.*;
|
||||
|
||||
class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final String CREATE_MOZ_PLACES =
|
||||
"CREATE TABLE moz_places ( " +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", url LONGVARCHAR UNIQUE" +
|
||||
", title LONGVARCHAR" +
|
||||
", rev_host LONGVARCHAR" +
|
||||
", visit_count INTEGER DEFAULT 0" +
|
||||
", hidden INTEGER DEFAULT 0 NOT NULL" +
|
||||
", typed INTEGER DEFAULT 0 NOT NULL" +
|
||||
", favicon_id INTEGER" +
|
||||
", frecency INTEGER DEFAULT -1 NOT NULL" +
|
||||
", last_visit_date INTEGER " +
|
||||
", guid TEXT" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_HISTORYVISITS =
|
||||
"CREATE TABLE moz_historyvisits (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", from_visit INTEGER" +
|
||||
", place_id INTEGER" +
|
||||
", visit_date INTEGER" +
|
||||
", visit_type INTEGER" +
|
||||
", session INTEGER" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_INPUTHISTORY =
|
||||
"CREATE TABLE moz_inputhistory (" +
|
||||
" place_id INTEGER NOT NULL" +
|
||||
", input LONGVARCHAR NOT NULL" +
|
||||
", use_count INTEGER" +
|
||||
", PRIMARY KEY (place_id, input)" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_ANNOS =
|
||||
"CREATE TABLE moz_annos (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", place_id INTEGER NOT NULL" +
|
||||
", anno_attribute_id INTEGER" +
|
||||
", mime_type VARCHAR(32) DEFAULT NULL" +
|
||||
", content LONGVARCHAR" +
|
||||
", flags INTEGER DEFAULT 0" +
|
||||
", expiration INTEGER DEFAULT 0" +
|
||||
", type INTEGER DEFAULT 0" +
|
||||
", dateAdded INTEGER DEFAULT 0" +
|
||||
", lastModified INTEGER DEFAULT 0" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_ANNO_ATTRIBUTES =
|
||||
"CREATE TABLE moz_anno_attributes (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", name VARCHAR(32) UNIQUE NOT NULL" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_ITEMS_ANNOS =
|
||||
"CREATE TABLE moz_items_annos (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", item_id INTEGER NOT NULL" +
|
||||
", anno_attribute_id INTEGER" +
|
||||
", mime_type VARCHAR(32) DEFAULT NULL" +
|
||||
", content LONGVARCHAR" +
|
||||
", flags INTEGER DEFAULT 0" +
|
||||
", expiration INTEGER DEFAULT 0" +
|
||||
", type INTEGER DEFAULT 0" +
|
||||
", dateAdded INTEGER DEFAULT 0" +
|
||||
", lastModified INTEGER DEFAULT 0" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_FAVICONS =
|
||||
"CREATE TABLE moz_favicons (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", url LONGVARCHAR UNIQUE" +
|
||||
", data BLOB" +
|
||||
", mime_type VARCHAR(32)" +
|
||||
", expiration LONG" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_BOOKMARKS =
|
||||
"CREATE TABLE moz_bookmarks (" +
|
||||
" id INTEGER PRIMARY KEY" +
|
||||
", type INTEGER" +
|
||||
", fk INTEGER DEFAULT NULL" +
|
||||
", parent INTEGER" +
|
||||
", position INTEGER" +
|
||||
", title LONGVARCHAR" +
|
||||
", keyword_id INTEGER" +
|
||||
", folder_type TEXT" +
|
||||
", dateAdded INTEGER" +
|
||||
", lastModified INTEGER" +
|
||||
", guid TEXT" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_BOOKMARKS_ROOTS =
|
||||
"CREATE TABLE moz_bookmarks_roots (" +
|
||||
" root_name VARCHAR(16) UNIQUE" +
|
||||
", folder_id INTEGER" +
|
||||
")";
|
||||
|
||||
private static final String CREATE_MOZ_KEYWORDS =
|
||||
"CREATE TABLE moz_keywords (" +
|
||||
" id INTEGER PRIMARY KEY AUTOINCREMENT" +
|
||||
", keyword TEXT UNIQUE" +
|
||||
")";
|
||||
|
||||
private static final String DATABASE_NAME = "places";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_MOZ_PLACES);
|
||||
db.execSQL(CREATE_MOZ_HISTORYVISITS);
|
||||
db.execSQL(CREATE_MOZ_BOOKMARKS);
|
||||
db.execSQL(CREATE_MOZ_BOOKMARKS_ROOTS);
|
||||
db.execSQL(CREATE_MOZ_FAVICONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w("DatabaseHelper", "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
db.execSQL("DROP TABLE IF EXISTS places");
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
}
|
@ -61,6 +61,7 @@ import android.hardware.*;
|
||||
import android.util.*;
|
||||
import android.net.*;
|
||||
import android.database.*;
|
||||
import android.database.sqlite.*;
|
||||
import android.provider.*;
|
||||
import android.content.pm.*;
|
||||
import android.content.pm.PackageManager.*;
|
||||
@ -77,21 +78,37 @@ abstract public class GeckoApp
|
||||
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 LinearLayout mainLayout;
|
||||
public static AbsoluteLayout geckoLayout;
|
||||
public static GeckoSurfaceView surfaceView;
|
||||
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;
|
||||
public static EditText mAwesomeBar;
|
||||
public static ProgressBar mProgressBar;
|
||||
private static SQLiteDatabase mDb;
|
||||
private static DatabaseHelper mDbHelper;
|
||||
private static Stack<HistoryEntry> sessionHistory;
|
||||
|
||||
enum LaunchState {PreLaunch, Launching, WaitForDebugger,
|
||||
enum LaunchState {Launching, WaitButton,
|
||||
Launched, GeckoRunning, GeckoExiting};
|
||||
private static LaunchState sLaunchState = LaunchState.PreLaunch;
|
||||
private static LaunchState sLaunchState = LaunchState.Launching;
|
||||
private static boolean sTryCatchAttached = false;
|
||||
|
||||
private static final int FILE_PICKER_REQUEST = 1;
|
||||
private static final int AWESOMEBAR_REQUEST = 2;
|
||||
|
||||
public static class HistoryEntry {
|
||||
public String uri;
|
||||
public String title;
|
||||
public HistoryEntry(String uri, String title) {
|
||||
this.uri = uri;
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean checkLaunchState(LaunchState checkState) {
|
||||
synchronized(sLaunchState) {
|
||||
@ -150,6 +167,8 @@ abstract public class GeckoApp
|
||||
|
||||
String[] getPluginDirectories() {
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - start of getPluginDirectories");
|
||||
|
||||
ArrayList<String> directories = new ArrayList<String>();
|
||||
PackageManager pm = this.mAppContext.getPackageManager();
|
||||
List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION),
|
||||
@ -265,7 +284,9 @@ abstract public class GeckoApp
|
||||
}
|
||||
}
|
||||
|
||||
return directories.toArray(new String[directories.size()]);
|
||||
String [] result = directories.toArray(new String[directories.size()]);
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - end of getPluginDirectories");
|
||||
return result;
|
||||
}
|
||||
|
||||
Class<?> getPluginClass(String packageName, String className)
|
||||
@ -280,6 +301,8 @@ abstract public class GeckoApp
|
||||
// Returns true when the intent is going to be handled by gecko launch
|
||||
boolean launch(Intent intent)
|
||||
{
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - launch");
|
||||
|
||||
if (!checkAndSetLaunchState(LaunchState.Launching, LaunchState.Launched))
|
||||
return false;
|
||||
|
||||
@ -288,37 +311,35 @@ abstract public class GeckoApp
|
||||
final Intent i = intent;
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
if (mLibLoadThread != null)
|
||||
mLibLoadThread.join();
|
||||
} catch (InterruptedException ie) {}
|
||||
File cacheFile = GeckoAppShell.getCacheDir();
|
||||
File libxulFile = new File(cacheFile, "libxul.so");
|
||||
|
||||
// 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();
|
||||
if ((!libxulFile.exists() ||
|
||||
new File(getApplication().getPackageResourcePath()).lastModified() >= libxulFile.lastModified())) {
|
||||
File[] libs = cacheFile.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".so");
|
||||
}
|
||||
});
|
||||
if (libs != null) {
|
||||
for (int i = 0; i < libs.length; i++) {
|
||||
libs[i].delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
||||
// 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;
|
||||
}
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - runGecko");
|
||||
|
||||
// and then fire us up
|
||||
try {
|
||||
@ -337,11 +358,62 @@ abstract public class GeckoApp
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
final Activity self = this;
|
||||
|
||||
MenuItem quitItem = menu.add("Quit");
|
||||
quitItem.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
quitItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
quit();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private void quit() {
|
||||
Log.i(LOG_FILE_NAME, "pleaseKillMe");
|
||||
if (surfaceView != null)
|
||||
surfaceView.saveLast();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - onCreate");
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getWindow().setFlags(mFullscreen ?
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||
|
||||
setContentView(R.layout.gecko_app);
|
||||
mAppContext = this;
|
||||
|
||||
// setup gecko layout
|
||||
geckoLayout = (AbsoluteLayout) findViewById(R.id.geckoLayout);
|
||||
surfaceView = new GeckoSurfaceView(this);
|
||||
geckoLayout.addView(surfaceView,
|
||||
new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.MATCH_PARENT,
|
||||
AbsoluteLayout.LayoutParams.MATCH_PARENT,
|
||||
0,
|
||||
0));
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - UI almost up");
|
||||
|
||||
if (sGREDir == null)
|
||||
sGREDir = new File(this.getApplicationInfo().dataDir);
|
||||
|
||||
mDbHelper = new DatabaseHelper(this);
|
||||
|
||||
sessionHistory = new Stack<HistoryEntry>();
|
||||
|
||||
mMainHandler = new Handler();
|
||||
|
||||
if (!sTryCatchAttached) {
|
||||
@ -362,63 +434,79 @@ abstract public class GeckoApp
|
||||
});
|
||||
}
|
||||
|
||||
SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
|
||||
String localeCode = settings.getString(getPackageName() + ".locale", "");
|
||||
if (localeCode != null && localeCode.length() > 0)
|
||||
GeckoAppShell.setSelectedLocale(localeCode);
|
||||
mainLayout = (LinearLayout) findViewById(R.id.mainLayout);
|
||||
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
|
||||
Log.i(LOG_FILE_NAME, "create");
|
||||
super.onCreate(savedInstanceState);
|
||||
// setup awesome bar
|
||||
mAwesomeBar = (EditText) findViewById(R.id.awesomeBar);
|
||||
mAwesomeBar.setOnClickListener(new EditText.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
onSearchRequested();
|
||||
}
|
||||
});
|
||||
|
||||
if (sGREDir == null)
|
||||
sGREDir = new File(this.getApplicationInfo().dataDir);
|
||||
|
||||
getWindow().setFlags(mFullscreen ?
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
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));
|
||||
ImageButton reload = (ImageButton) findViewById(R.id.reload);
|
||||
reload.setOnClickListener(new ImageButton.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
doReload();
|
||||
}
|
||||
});
|
||||
|
||||
mConnectivityFilter = new IntentFilter();
|
||||
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
mConnectivityReceiver = new GeckoConnectivityReceiver();
|
||||
|
||||
if (!checkAndSetLaunchState(LaunchState.PreLaunch,
|
||||
LaunchState.Launching))
|
||||
return;
|
||||
|
||||
checkAndLaunchUpdate();
|
||||
mLibLoadThread = new Thread(new Runnable() {
|
||||
mMainHandler.post(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();
|
||||
surfaceView.loadStartupBitmap();
|
||||
}
|
||||
});
|
||||
|
||||
final GeckoApp self = this;
|
||||
|
||||
mMainHandler.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - pre checkLaunchState");
|
||||
|
||||
SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
|
||||
String localeCode = settings.getString(getPackageName() + ".locale", "");
|
||||
if (localeCode != null && localeCode.length() > 0)
|
||||
GeckoAppShell.setSelectedLocale(localeCode);
|
||||
|
||||
if (!checkLaunchState(LaunchState.Launched)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (false) {
|
||||
checkAndLaunchUpdate();
|
||||
}
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
|
||||
public static void addHistoryEntry(final HistoryEntry entry) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
Log.d("GeckoApp", "adding uri=" + entry.uri + ", title=" + entry.title + " to history");
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("url", entry.uri);
|
||||
values.put("title", entry.title);
|
||||
if (sessionHistory.empty() || !sessionHistory.peek().uri.equals(entry.uri))
|
||||
sessionHistory.push(entry);
|
||||
mDb = mDbHelper.getWritableDatabase();
|
||||
long id = mDb.insertWithOnConflict("moz_places", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
values = new ContentValues();
|
||||
values.put("place_id", id);
|
||||
mDb.insertWithOnConflict("moz_historyvisits", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - onNewIntent");
|
||||
|
||||
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
|
||||
@ -427,19 +515,21 @@ abstract public class GeckoApp
|
||||
}
|
||||
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");
|
||||
checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitButton)) {
|
||||
final Button launchButton = new Button(this);
|
||||
launchButton.setText("Launch"); // don't need to localize
|
||||
launchButton.setOnClickListener(new Button.OnClickListener() {
|
||||
public void onClick (View v) {
|
||||
// hide the button so we can't be launched again
|
||||
mainLayout.removeView(launchButton);
|
||||
setLaunchState(LaunchState.Launching);
|
||||
launch(null);
|
||||
}
|
||||
}, 1000 * 5 /* 5 seconds */);
|
||||
Log.i(LOG_FILE_NAME, "Intent : ACTION_DEBUG - waiting 5s before launching");
|
||||
});
|
||||
mainLayout.addView(launchButton, 300, 200);
|
||||
return;
|
||||
}
|
||||
if (checkLaunchState(LaunchState.WaitForDebugger) || launch(intent))
|
||||
if (checkLaunchState(LaunchState.WaitButton) || launch(intent))
|
||||
return;
|
||||
|
||||
if (Intent.ACTION_MAIN.equals(action)) {
|
||||
@ -492,8 +582,7 @@ abstract public class GeckoApp
|
||||
super.onResume();
|
||||
|
||||
// Just in case. Normally we start in onNewIntent
|
||||
if (checkLaunchState(LaunchState.PreLaunch) ||
|
||||
checkLaunchState(LaunchState.Launching))
|
||||
if (checkLaunchState(LaunchState.Launching))
|
||||
onNewIntent(getIntent());
|
||||
|
||||
registerReceiver(mConnectivityReceiver, mConnectivityFilter);
|
||||
@ -531,6 +620,8 @@ abstract public class GeckoApp
|
||||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - onStart");
|
||||
|
||||
Log.i(LOG_FILE_NAME, "start");
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_START));
|
||||
super.onStart();
|
||||
@ -540,6 +631,10 @@ abstract public class GeckoApp
|
||||
public void onDestroy()
|
||||
{
|
||||
Log.i(LOG_FILE_NAME, "destroy");
|
||||
|
||||
if (mDb != null)
|
||||
mDb.close();
|
||||
|
||||
// Tell Gecko to shutting down; we'll end up calling System.exit()
|
||||
// in onXreExit.
|
||||
if (isFinishing())
|
||||
@ -568,97 +663,6 @@ abstract public class GeckoApp
|
||||
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);
|
||||
}
|
||||
unpackFile(zip, buf, null, "application.ini");
|
||||
unpackFile(zip, buf, null, getContentProcessName());
|
||||
try {
|
||||
unpackFile(zip, buf, null, "update.locale");
|
||||
} catch (Exception e) {/* this is non-fatal */}
|
||||
|
||||
// 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();
|
||||
@ -767,8 +771,6 @@ abstract public class GeckoApp
|
||||
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);
|
||||
@ -793,59 +795,115 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
@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);
|
||||
public boolean onSearchRequested() {
|
||||
Intent searchIntent = new Intent(getBaseContext(), AwesomeBar.class);
|
||||
searchIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
if (!sessionHistory.empty())
|
||||
searchIntent.putExtra(AwesomeBar.CURRENT_URL_KEY, sessionHistory.peek().uri);
|
||||
|
||||
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);
|
||||
startActivityForResult(searchIntent, AWESOMEBAR_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean doReload() {
|
||||
Log.i("GeckoApp", "Reload requested");
|
||||
if (sessionHistory.empty())
|
||||
return false;
|
||||
String currUri = sessionHistory.peek().uri;
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(currUri));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (sessionHistory.size() > 1) {
|
||||
sessionHistory.pop();
|
||||
String uri = sessionHistory.peek().uri;
|
||||
Log.i("GeckoApp", "going back to page: " + uri);
|
||||
loadUrl(uri);
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case FILE_PICKER_REQUEST:
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case AWESOMEBAR_REQUEST:
|
||||
|
||||
if (data != null) {
|
||||
String url = data.getStringExtra(AwesomeBar.URL_KEY);
|
||||
if (url != null && url.length() > 0) {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
mProgressBar.setIndeterminate(true);
|
||||
loadUrl(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void loadUrl(String url) {
|
||||
mAwesomeBar.setText(url);
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(url));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,6 +71,9 @@ 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";
|
||||
@ -1046,10 +1049,6 @@ public class GeckoAppShell
|
||||
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() {
|
||||
@ -1354,17 +1353,17 @@ public class GeckoAppShell
|
||||
(int)x,
|
||||
(int)y);
|
||||
|
||||
if (GeckoApp.mainLayout.indexOfChild(view) == -1) {
|
||||
if (GeckoApp.geckoLayout.indexOfChild(view) == -1) {
|
||||
view.setWillNotDraw(false);
|
||||
if(view instanceof SurfaceView)
|
||||
((SurfaceView)view).setZOrderOnTop(true);
|
||||
|
||||
GeckoApp.mainLayout.addView(view, lp);
|
||||
GeckoApp.geckoLayout.addView(view, lp);
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
GeckoApp.mainLayout.updateViewLayout(view, lp);
|
||||
GeckoApp.geckoLayout.updateViewLayout(view, lp);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.i("updateViewLayout - IllegalArgumentException", "e:" + e);
|
||||
// it can be the case where we
|
||||
@ -1381,7 +1380,7 @@ public class GeckoAppShell
|
||||
getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
GeckoApp.mainLayout.removeView(view);
|
||||
GeckoApp.geckoLayout.removeView(view);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
});
|
||||
@ -1620,4 +1619,79 @@ public class GeckoAppShell
|
||||
sCameraBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleGeckoMessage(String message) {
|
||||
//
|
||||
// {"gecko": {
|
||||
// "type": "value",
|
||||
// "event_specific": "value",
|
||||
// ....
|
||||
try {
|
||||
JSONObject json = new JSONObject(message);
|
||||
JSONObject geckoObject = json.getJSONObject("gecko");
|
||||
String type = geckoObject.getString("type");
|
||||
|
||||
if (type.equals("DOMContentLoaded")) {
|
||||
final String uri = geckoObject.getString("uri");
|
||||
final String title = geckoObject.getString("title");
|
||||
final String stat = geckoObject.getString("stat");
|
||||
final CharSequence titleText = title;
|
||||
getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
GeckoApp.mAwesomeBar.setText(titleText);
|
||||
GeckoApp.addHistoryEntry(new GeckoApp.HistoryEntry(uri, title));
|
||||
GeckoApp.mProgressBar.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
Log.i("GeckoShell", "URI - " + uri + ", title - " + title + ", status - " + stat);
|
||||
}
|
||||
else if (type.equals("log")) {
|
||||
// generic log listener
|
||||
final String msg = geckoObject.getString("msg");
|
||||
Log.i("GeckoShell", "Log: " + msg);
|
||||
}
|
||||
else if (type.equals("onLocationChange")) {
|
||||
final String uri = geckoObject.getString("uri");
|
||||
final CharSequence uriText = uri;
|
||||
Log.i("GeckoShell", "URI - " + uri);
|
||||
getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
GeckoApp.mAwesomeBar.setText(uriText);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (type.equals("onStateChange")) {
|
||||
String state = geckoObject.getString("state");
|
||||
String stateIs = geckoObject.getString("stateIs");
|
||||
|
||||
if (state == "start") {
|
||||
GeckoApp.mProgressBar.setVisibility(View.VISIBLE);
|
||||
GeckoApp.mProgressBar.setIndeterminate(true);
|
||||
}
|
||||
}
|
||||
else if (type.equals("onProgressChange")) {
|
||||
final int current = geckoObject.getInt("current");
|
||||
final int total = geckoObject.getInt("total");
|
||||
|
||||
getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
if (total == -1) {
|
||||
GeckoApp.mProgressBar.setIndeterminate(true);
|
||||
} else if (current < total) {
|
||||
GeckoApp.mProgressBar.setIndeterminate(false);
|
||||
GeckoApp.mProgressBar.setMax(total);
|
||||
GeckoApp.mProgressBar.setProgress(current);
|
||||
}
|
||||
else {
|
||||
GeckoApp.mProgressBar.setIndeterminate(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Log.i("GeckoShell", "progress - " + current + "/" + total);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i("GeckoShell", "handleGeckoMessage throws "+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public class GeckoEvent {
|
||||
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 IME_COMPOSITION_END = 0;
|
||||
public static final int IME_COMPOSITION_BEGIN = 1;
|
||||
|
@ -102,91 +102,48 @@ class GeckoSurfaceView
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
void drawSplashScreen() {
|
||||
this.drawSplashScreen(getHolder(), mWidth, mHeight);
|
||||
/*
|
||||
* Called on main thread
|
||||
*/
|
||||
|
||||
public String getStartupBitmapFilePath() {
|
||||
File file = new File(Environment.getExternalStorageDirectory(),
|
||||
"lastScreen.png");
|
||||
return file.toString();
|
||||
}
|
||||
|
||||
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;
|
||||
public void loadStartupBitmap() {
|
||||
try {
|
||||
String filePath = getStartupBitmapFilePath();
|
||||
mStartupBitmap = BitmapFactory.decodeFile(filePath);
|
||||
} catch (Exception e) {
|
||||
Log.e(LOG_FILE_NAME, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void drawStartupBitmap(SurfaceHolder holder, int width, int height) {
|
||||
if (mStartupBitmap == null) {
|
||||
Log.e(LOG_FILE_NAME, "!!! NO STARTUP BITMAP !!!");
|
||||
loadStartupBitmap();
|
||||
if (mStartupBitmap == null) {
|
||||
mShowingLoadScreen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Canvas c = holder.lockCanvas();
|
||||
if (c == null) {
|
||||
Log.i(LOG_FILE_NAME, "canvas is null");
|
||||
Log.e(LOG_FILE_NAME, "!!! NO CANVAS !!!");
|
||||
mShowingLoadScreen = false;
|
||||
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);
|
||||
}
|
||||
}
|
||||
Drawable drawable = new BitmapDrawable(mStartupBitmap);
|
||||
drawable.setBounds(0, 0, width, height);
|
||||
drawable.draw(c);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called on main thread
|
||||
*/
|
||||
|
||||
public void draw(SurfaceHolder holder, ByteBuffer buffer) {
|
||||
if (buffer == null || buffer.capacity() != (mWidth * mHeight * 2))
|
||||
return;
|
||||
@ -199,7 +156,7 @@ class GeckoSurfaceView
|
||||
if (c == null)
|
||||
return;
|
||||
mSoftwareBufferCopy.copyPixelsFromBuffer(buffer);
|
||||
c.drawBitmap(mSoftwareBufferCopy, 0, 0, null);
|
||||
c.drawBitmap(mLastBitmap = mSoftwareBufferCopy, 0, 0, null);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
@ -216,12 +173,23 @@ class GeckoSurfaceView
|
||||
Canvas c = holder.lockCanvas();
|
||||
if (c == null)
|
||||
return;
|
||||
c.drawBitmap(bitmap, 0, 0, null);
|
||||
c.drawBitmap(mLastBitmap = bitmap, 0, 0, null);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
|
||||
|
||||
mFormat = format;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
if (mShowingLoadScreen) {
|
||||
drawStartupBitmap(holder, width, height);
|
||||
if (mStartupBitmap != null)
|
||||
return;
|
||||
}
|
||||
|
||||
// Force exactly one frame to render
|
||||
// because the surface change is only seen after we
|
||||
@ -243,9 +211,6 @@ class GeckoSurfaceView
|
||||
mAbortDraw = false;
|
||||
}
|
||||
|
||||
if (mShowingSplashScreen)
|
||||
drawSplashScreen(holder, width, height);
|
||||
|
||||
mSurfaceLock.lock();
|
||||
|
||||
if (mInDrawing) {
|
||||
@ -269,9 +234,6 @@ class GeckoSurfaceView
|
||||
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);
|
||||
@ -304,7 +266,7 @@ class GeckoSurfaceView
|
||||
} else {
|
||||
Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null");
|
||||
}
|
||||
} else if (!mShowingSplashScreen) {
|
||||
} else if (!mShowingLoadScreen) {
|
||||
// Make sure a frame is drawn before we return
|
||||
// otherwise we see artifacts or a black screen
|
||||
GeckoAppShell.scheduleRedraw();
|
||||
@ -316,16 +278,26 @@ class GeckoSurfaceView
|
||||
Log.i(LOG_FILE_NAME, "surface created");
|
||||
GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED);
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
if (mShowingSplashScreen)
|
||||
drawSplashScreen();
|
||||
}
|
||||
|
||||
public void saveLast() {
|
||||
GeckoEvent event = new GeckoEvent();
|
||||
event.mType = GeckoEvent.SAVE_STATE;
|
||||
event.mCharacters = getStartupBitmapFilePath();
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
Log.i(LOG_FILE_NAME, "surface destroyed");
|
||||
saveLast();
|
||||
mShowingLoadScreen = true;
|
||||
mStartupBitmap = mLastBitmap;
|
||||
|
||||
mSurfaceValid = false;
|
||||
mSoftwareBuffer = null;
|
||||
mSoftwareBufferCopy = null;
|
||||
mSoftwareBitmap = null;
|
||||
mLastBitmap = null;
|
||||
GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED);
|
||||
if (mDrawMode == DRAW_GLES_2) {
|
||||
// Ensure GL cleanup occurs before we return.
|
||||
@ -381,6 +353,8 @@ class GeckoSurfaceView
|
||||
public static final int DRAW_DISABLED = 3;
|
||||
|
||||
public int beginDrawing() {
|
||||
mStartupBitmap = null;
|
||||
|
||||
if (mInDrawing) {
|
||||
Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!");
|
||||
return DRAW_ERROR;
|
||||
@ -635,6 +609,12 @@ class GeckoSurfaceView
|
||||
|
||||
// event stuff
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
this.requestFocus(FOCUS_UP, null);
|
||||
|
||||
if (mShowingLoadScreen == true) {
|
||||
mShowingLoadScreen = false;
|
||||
surfaceChanged(getHolder(), mFormat, mWidth, mHeight);
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
|
||||
return true;
|
||||
}
|
||||
@ -670,13 +650,6 @@ class GeckoSurfaceView
|
||||
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:
|
||||
@ -723,7 +696,11 @@ class GeckoSurfaceView
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (!event.isTracking() || event.isCanceled())
|
||||
return false;
|
||||
break;
|
||||
GeckoApp.mAppContext.onBackPressed();
|
||||
return true;
|
||||
case KeyEvent.KEYCODE_SEARCH:
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -782,8 +759,7 @@ class GeckoSurfaceView
|
||||
// True if gecko requests a buffer
|
||||
int mDrawMode;
|
||||
|
||||
static boolean mShowingSplashScreen = true;
|
||||
static String mSplashURL = "";
|
||||
static boolean mShowingLoadScreen = true;
|
||||
|
||||
// let's not change stuff around while we're in the middle of
|
||||
// starting drawing, ending drawing, or changing surface
|
||||
@ -822,6 +798,8 @@ class GeckoSurfaceView
|
||||
Bitmap mSoftwareBitmap;
|
||||
ByteBuffer mSoftwareBuffer;
|
||||
Bitmap mSoftwareBufferCopy;
|
||||
Bitmap mStartupBitmap;
|
||||
Bitmap mLastBitmap;
|
||||
|
||||
Geocoder mGeocoder;
|
||||
Address mLastGeoAddress;
|
||||
|
@ -54,6 +54,8 @@ JAVAFILES = \
|
||||
GeckoInputConnection.java \
|
||||
AlertNotification.java \
|
||||
SurfaceLockInfo.java \
|
||||
AwesomeBar.java \
|
||||
DatabaseHelper.java \
|
||||
$(NULL)
|
||||
|
||||
PROCESSEDJAVAFILES = \
|
||||
@ -120,11 +122,14 @@ DEFINES += -DMOZ_ANDROID_SHARED_ID="$(ANDROID_PACKAGE_NAME).sharedID"
|
||||
endif
|
||||
|
||||
RES_LAYOUT = \
|
||||
res/layout/gecko_app.xml \
|
||||
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/awesomebar_search.xml \
|
||||
res/layout/awesomebar_row.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES = res/values/colors.xml res/values/themes.xml
|
||||
@ -144,7 +149,7 @@ 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 += embedding/android/resources/drawable/desktop_notification.png embedding/android/resources/drawable/favicon.png embedding/android/resources/drawable/reload.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)
|
||||
|
||||
@ -161,7 +166,7 @@ include $(topsrcdir)/config/android-common.mk
|
||||
# Instead of on the .class files, since more than one .class file might be produced per .java file
|
||||
classes.dex: $(JAVAFILES) $(PROCESSEDJAVAFILES) R.java
|
||||
$(NSINSTALL) -D classes
|
||||
$(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES)) $(PROCESSEDJAVAFILES) R.java
|
||||
$(JAVAC) $(JAVAC_FLAGS) -Xlint:unchecked -Xlint:deprecation -d classes $(addprefix $(srcdir)/,$(JAVAFILES)) $(PROCESSEDJAVAFILES) R.java
|
||||
$(DX) --dex --output=$@ classes
|
||||
|
||||
AndroidManifest.xml $(PROCESSEDJAVAFILES): % : %.in
|
||||
|
BIN
embedding/android/resources/drawable/favicon.png
Normal file
BIN
embedding/android/resources/drawable/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 268 B |
BIN
embedding/android/resources/drawable/reload.png
Normal file
BIN
embedding/android/resources/drawable/reload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 567 B |
32
embedding/android/resources/layout/awesomebar_row.xml
Normal file
32
embedding/android/resources/layout/awesomebar_row.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/favicon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="6dip"/>
|
||||
|
||||
<TextView android:id="@android:id/text1"
|
||||
android:layout_marginTop="1dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/favicon"
|
||||
android:textColor="#fff"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView android:id="@android:id/text2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/text1"
|
||||
android:layout_alignLeft="@android:id/text1"
|
||||
android:paddingBottom="4dip"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#8ac"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="normal" />
|
||||
|
||||
</TwoLineListItem>
|
11
embedding/android/resources/layout/awesomebar_search.xml
Normal file
11
embedding/android/resources/layout/awesomebar_search.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:weightSum="1">
|
||||
<EditText android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/awesomebar_text">
|
||||
<requestFocus/>
|
||||
</EditText>
|
||||
<ListView android:layout_height="fill_parent" android:id="@android:id/list" android:layout_width="match_parent"></ListView>
|
||||
</LinearLayout>
|
45
embedding/android/resources/layout/gecko_app.xml
Normal file
45
embedding/android/resources/layout/gecko_app.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+android:id/mainLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ProgressBar android:id="@+android:id/progressBar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="10dip"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<LinearLayout android:id="@+android:id/addressBar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton android:id="@+android:id/favicon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/favicon"/>
|
||||
|
||||
<EditText android:id="@+android:id/awesomeBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:imeOptions="actionGo"
|
||||
android:inputType="textNoSuggestions|textFilter"/>
|
||||
|
||||
<ImageButton android:id="@+android:id/reload"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/reload"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<AbsoluteLayout android:id="@+android:id/geckoLayout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
@ -674,7 +674,7 @@ pref("browser.firstrun.show.localepicker", true);
|
||||
// $ adb shell stop
|
||||
// $ adb shell setprop log.redirect-stdio true
|
||||
// $ adb shell start
|
||||
pref("browser.dom.window.dump.enabled", false);
|
||||
pref("browser.dom.window.dump.enabled", true);
|
||||
|
||||
// controls if we want camera support
|
||||
pref("device.camera.enabled", true);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,780 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is Mozilla Mobile Browser.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2008
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Brad Lassey <blassey@mozilla.com>
|
||||
- Mark Finkle <mfinkle@mozila.com>
|
||||
- Matt Brubeck <mbrubeck@mozila.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://browser/skin/platform.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/forms.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
|
||||
%globalDTD;
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
|
||||
%browserDTD;
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/preferences.dtd">
|
||||
%prefsDTD;
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/sync.dtd">
|
||||
%syncDTD;
|
||||
#endif
|
||||
]>
|
||||
|
||||
<window id="main-window"
|
||||
onload="Browser.startup();"
|
||||
onunload="Browser.shutdown();"
|
||||
onclose="return Browser.closing();"
|
||||
onload="startup();"
|
||||
windowtype="navigator:browser"
|
||||
chromedir="&locale.dir;"
|
||||
title="&brandShortName;"
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
sizemode="fullscreen"
|
||||
#else
|
||||
#ifndef ANDROID
|
||||
width="480"
|
||||
height="800"
|
||||
#endif
|
||||
#endif
|
||||
onkeypress="onDebugKeyPress(event);"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-ui.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-scripts.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/Util.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/input.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser.js"/>
|
||||
|
||||
<broadcasterset id="broadcasterset">
|
||||
<broadcaster id="bcast_contentShowing" disabled="false"/>
|
||||
<broadcaster id="bcast_urlbarState" mode="view" tablet_sidebar="true" persist="tablet_sidebar"/>
|
||||
<broadcaster id="bcast_uidiscovery"/>
|
||||
</broadcasterset>
|
||||
|
||||
<observerset id="observerset">
|
||||
<observes id="observe_contentShowing" element="bcast_contentShowing" attribute="disabled" onbroadcast="BrowserUI.updateUIFocus();"/>
|
||||
</observerset>
|
||||
|
||||
<commandset id="mainCommandSet">
|
||||
<!-- basic navigation -->
|
||||
<command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_forward" label="&forward.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);" observes="bcast_urlbarState"/>
|
||||
<command id="cmd_reload" label="&reload.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_forceReload" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_stop" label="&stop.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_openLocation" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- tabs -->
|
||||
<command id="cmd_showTabs" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<command id="cmd_remoteTabs" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
#endif
|
||||
<command id="cmd_undoCloseTab" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- bookmarking -->
|
||||
<command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- misc -->
|
||||
<command id="cmd_close" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_quit" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_menu" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_actions" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_opensearch" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_panel" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_bookmarks" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_history" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_sanitize" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- screen/display -->
|
||||
<command id="cmd_fullscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_zoomin" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_zoomout" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_lockscreen" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<command id="cmd_volumeLeft" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_volumeRight" observes="bcast_contentShowing" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- scrolling -->
|
||||
<command id="cmd_scrollPageUp" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- editing -->
|
||||
<command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copy" label="©.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_copylink" label="©link.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
<command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||
|
||||
<!-- forms navigation -->
|
||||
<command id="cmd_formPrevious" oncommand="FormHelperUI.goToPrevious();"/>
|
||||
<command id="cmd_formNext" oncommand="FormHelperUI.goToNext();"/>
|
||||
<command id="cmd_formClose" oncommand="FormHelperUI.hide();"/>
|
||||
|
||||
<!-- find navigation -->
|
||||
<command id="cmd_findPrevious" oncommand="FindHelperUI.goToPrevious();"/>
|
||||
<command id="cmd_findNext" oncommand="FindHelperUI.goToNext();"/>
|
||||
<command id="cmd_findClose" oncommand="FindHelperUI.hide();"/>
|
||||
<command id="cmd_find" oncommand="FindHelperUI.show();"/>
|
||||
</commandset>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
<!-- basic navigation -->
|
||||
<key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
|
||||
<key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
|
||||
#ifndef ANDROID
|
||||
<key id="key_back2" keycode="VK_BACK" command="cmd_back"/>
|
||||
<key id="key_forward2" keycode="VK_BACK" command="cmd_forward" modifiers="shift"/>
|
||||
#endif
|
||||
#ifndef MOZ_PLATFORM_MAEMO
|
||||
<key id="key_reload" keycode="VK_F5" command="cmd_reload"/>
|
||||
<key id="key_forceReload" keycode="VK_F5" modifiers="shift" command="cmd_forceReload"/>
|
||||
#else
|
||||
<key id="key_lockscreen" key="o" modifiers="accel,shift" command="cmd_lockscreen"/>
|
||||
<!-- F5 on maemo is "home" which is a task switching key -->
|
||||
#endif
|
||||
<key id="key_reload2" key="r" modifiers="accel" command="cmd_reload"/>
|
||||
<key id="key_forceReload2" key="r" modifiers="accel,shift" command="cmd_forceReload"/>
|
||||
<key id="key_focusURL" key="l" modifiers="accel" command="cmd_openLocation"/>
|
||||
|
||||
<!-- scrolling -->
|
||||
<key id="key_pageUp" keycode="VK_UP" modifiers="shift" command="cmd_scrollPageUp"/>
|
||||
<key id="key_pageDown" keycode="VK_DOWN" modifiers="shift" command="cmd_scrollPageDown"/>
|
||||
|
||||
<!-- misc -->
|
||||
<key id="key_zoomin" keycode="VK_UP" modifiers="accel" command="cmd_zoomin"/>
|
||||
<key id="key_zoomout" keycode="VK_DOWN" modifiers="accel" command="cmd_zoomout"/>
|
||||
<key id="key_find" key="f" modifiers="accel" command="cmd_find"/>
|
||||
<key id="key_quit" key="q" modifiers="accel" command="cmd_quit"/>
|
||||
<key id="key_fullscreen" keycode="VK_F6" command="cmd_fullscreen"/>
|
||||
<key id="key_zoomin2" keycode="VK_F7" command="cmd_volumeRight"/>
|
||||
<key id="key_zoomout2" keycode="VK_F8" command="cmd_volumeLeft"/>
|
||||
|
||||
<!-- tabs -->
|
||||
<key id="key_newTab" key="t" modifiers="accel" command="cmd_newTab"/>
|
||||
<key id="key_closeTab" key="w" modifiers="accel" command="cmd_closeTab"/>
|
||||
<key id="key_undoCloseTab" key="t" modifiers="accel,shift" command="cmd_undoCloseTab"/>
|
||||
</keyset>
|
||||
|
||||
<stack flex="1" id="stack">
|
||||
<scrollbox id="controls-scrollbox" style="overflow: hidden; -moz-box-orient: horizontal; position: relative;" flex="1" observes="bcast_urlbarState">
|
||||
<vbox id="tabs-sidebar" class="sidebar" observes="bcast_uidiscovery">
|
||||
<spacer class="toolbar-height" id="tabs-spacer" observes="bcast_urlbarState"/>
|
||||
<!-- Left toolbar -->
|
||||
<vbox id="tabs-container" class="panel-dark" flex="1" observes="bcast_urlbarState">
|
||||
<vbox id="tabs" flex="1" observes="bcast_urlbarState"
|
||||
onselect="BrowserUI.selectTab(this);"
|
||||
onreloadtab="BrowserUI.undoCloseTab()"
|
||||
onclosetab="BrowserUI.closeTab(this)"
|
||||
onclosereloadtab="this._container.removeTab(this)"/>
|
||||
<hbox id="tabs-controls">
|
||||
<toolbarbutton id="newtab-button" class="button-control" command="cmd_newTab" label="&newtab.label;" observes="bcast_urlbarState" crop="end"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
<!-- Page Area -->
|
||||
<stack id="page-stack" observes="bcast_urlbarState">
|
||||
<scrollbox id="page-scrollbox">
|
||||
<vbox>
|
||||
<!-- Main Toolbar -->
|
||||
<box id="toolbar-container" class="panel-dark toolbar-height">
|
||||
<box id="toolbar-moveable-container" observes="bcast_uidiscovery">
|
||||
<toolbar id="toolbar-main" class="panel-dark viewable-width" observes="bcast_urlbarState">
|
||||
<toolbarbutton id="tool-tabs" class="button-actionbar" command="cmd_showTabs" anchorPosX="0.3"/>
|
||||
<toolbarbutton id="tool-back2" class="tool-back button-actionbar" command="cmd_back"/>
|
||||
<toolbarbutton id="tool-forward2" class="tool-forward button-actionbar" command="cmd_forward"/>
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
#if MOZ_PLATFORM_MAEMO != 6
|
||||
<toolbarbutton id="tool-app-switch" oncommand="BrowserUI.switchTask();"/>
|
||||
#endif
|
||||
#endif
|
||||
<hbox id="urlbar-container" flex="1" observes="bcast_urlbarState">
|
||||
<box id="identity-box" class="urlbar-cap-button"
|
||||
onclick="getIdentityHandler().handleIdentityButtonEvent(event);"
|
||||
onkeypress="getIdentityHandler().handleIdentityButtonEvent(event);">
|
||||
<box id="urlbar-image-box" mousethrough="always">
|
||||
<image id="urlbar-throbber"/>
|
||||
<image id="urlbar-favicon" hidden="true"/>
|
||||
</box>
|
||||
</box>
|
||||
<label id="urlbar-title" class="uri-element" crop="end" flex="1"
|
||||
command="cmd_openLocation" onclick="this.doCommand();"
|
||||
placeholder="&urlbar.emptytext;"/>
|
||||
<textbox id="urlbar-edit"
|
||||
type="url"
|
||||
mozactionhint="go"
|
||||
class="uri-element"
|
||||
autocompletesearch="history"
|
||||
autocompletepopup="popup_autocomplete"
|
||||
completeselectedindex="true"
|
||||
minresultsforpopup="0"
|
||||
onsearchbegin="AwesomeScreen.updateHeader(this.controller.searchString);"
|
||||
placeholder="&urlbar.emptytext;"
|
||||
collapsed="true"
|
||||
flex="1"
|
||||
readonly="true"
|
||||
ontextentered="BrowserUI.goToURI();"
|
||||
clickSelectsAll="true"/>
|
||||
<hbox id="urlbar-icons" class="urlbar-cap-button" observes="bcast_urlbarState">
|
||||
<toolbarbutton id="tool-reload" oncommand="CommandUpdater.doCommand(event.shiftKey ? 'cmd_forceReload' : 'cmd_reload');"/>
|
||||
<toolbarbutton id="tool-stop" command="cmd_stop"/>
|
||||
<toolbarbutton id="tool-search" command="cmd_opensearch"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<toolbarbutton id="tool-star2" class="tool-star button-actionbar" command="cmd_star"/>
|
||||
<toolbarbutton id="tool-menu" class="button-actionbar" command="cmd_menu"/>
|
||||
#ifndef ANDROID
|
||||
<toolbarbutton id="tool-app-close" class="urlbar-button" command="cmd_close"/>
|
||||
#endif
|
||||
</toolbar>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<!-- Content viewport -->
|
||||
<vbox id="content-viewport" class="viewable-width viewable-height">
|
||||
<!-- Content viewport -->
|
||||
<stack>
|
||||
<deck id="browsers" flex="1" observes="bcast_uidiscovery"/>
|
||||
<!-- vertical scrollbar -->
|
||||
<box id="vertical-scroller" class="scroller" orient="vertical" end="2" top="0"/>
|
||||
</stack>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</scrollbox>
|
||||
|
||||
<!-- popup for content navigator helper -->
|
||||
<vbox id="content-navigator" top="0">
|
||||
<textbox id="find-helper-textbox" class="search-bar content-navigator-item" oncommand="FindHelperUI.search(this.value)" oninput="FindHelperUI.updateCommands(this.value);" type="search"/>
|
||||
</vbox>
|
||||
|
||||
<!-- horizontal scrollbar -->
|
||||
<box id="horizontal-scroller" class="scroller" orient="horizontal" left="0" bottom="2"/>
|
||||
</stack>
|
||||
|
||||
<!-- Right toolbar -->
|
||||
<vbox id="controls-sidebar" class="sidebar" observes="bcast_uidiscovery">
|
||||
<!-- Because of the stack + fixed position of the urlbar when it is in
|
||||
locked mode the event on the top-right part of the urlbar are
|
||||
swallow by this spacer, but not with the mousethrough attribute
|
||||
-->
|
||||
<spacer class="toolbar-height" mousethrough="always"/>
|
||||
|
||||
<vbox id="browser-controls" style="overflow: -moz-hidden-unscrollable;" class="panel-dark" flex="1">
|
||||
<toolbarbutton id="tool-star" class="tool-star button-control" command="cmd_star"/>
|
||||
<toolbarbutton id="tool-back" class="tool-back button-control" command="cmd_back"/>
|
||||
<toolbarbutton id="tool-forward" class="tool-forward button-control" command="cmd_forward"/>
|
||||
<toolbarspring/>
|
||||
<toolbarbutton id="tool-panel-open" class="button-control" command="cmd_panel"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</scrollbox>
|
||||
|
||||
<!-- Form Helper suggestions helper popup -->
|
||||
<arrowbox id="form-helper-suggestions-container" flex="1" hidden="true" offset="0" top="0" left="0">
|
||||
<arrowscrollbox id="form-helper-suggestions" align="center" flex="1" orient="horizontal" onclick="FormHelperUI.doAutoComplete(event.target);"/>
|
||||
</arrowbox>
|
||||
|
||||
<!-- Tabs sidebar helper popup -->
|
||||
<arrowbox id="tabs-popup-container" hidden="true" offset="18" type="dialog">
|
||||
<vbox id="tabs-popup-inner-container" flex="1">
|
||||
<richlistbox id="tabs-popup-list" flex="1"
|
||||
onselect="BrowserUI.selectTab(this); TabsPopup.hide();"
|
||||
onreloadtab="BrowserUI.undoCloseTab(); TabsPopup.hide();"
|
||||
onclosetab="BrowserUI.closeTab(this); TabsPopup.closeTab(this);"/>
|
||||
<button id="tabs-popup-newtab-button" class="show-text" command="cmd_newTab"/>
|
||||
</vbox>
|
||||
</arrowbox>
|
||||
|
||||
<!-- popup for site identity information -->
|
||||
<arrowbox id="identity-container" hidden="true" mode="unknownIdentity" offset="18" flex="1" type="dialog" observes="bcast_urlbarState">
|
||||
<box id="identity-popup-container" flex="1" align="top">
|
||||
<image id="identity-popup-icon"/>
|
||||
<vbox id="identity-popup-content-box" flex="1">
|
||||
<box id="identity-popup-connected-box" flex="1">
|
||||
<label id="identity-popup-connectedToLabel" value="&identity.connectedTo2;"/>
|
||||
<label id="identity-popup-connectedToLabel2" flex="1">&identity.unverifiedsite2;</label>
|
||||
<description id="identity-popup-content-host" flex="1"/>
|
||||
</box>
|
||||
<box id="identity-popup-runBy-box">
|
||||
<label id="identity-popup-runByLabel" value="&identity.runBy2;"/>
|
||||
<description id="identity-popup-content-owner"/>
|
||||
<description id="identity-popup-content-supplemental"/>
|
||||
</box>
|
||||
<description id="identity-popup-content-verifier"/>
|
||||
</vbox>
|
||||
<box id="identity-popup-encryption-box">
|
||||
<image id="identity-popup-encryption-icon"/>
|
||||
<description id="identity-popup-encryption-label"/>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<hbox id="pageactions-container" hidden="true">
|
||||
#ifndef ANDROID
|
||||
<pageaction id="pageaction-findinpage" title="&pageactions.findInPage;"
|
||||
onclick="FindHelperUI.show();"/>
|
||||
#ifdef NS_PRINTING
|
||||
<pageaction id="pageaction-saveas" title="&pageactions.saveas.pdf;"
|
||||
onclick="PageActions.savePageAsPDF();"/>
|
||||
#endif
|
||||
<pageaction id="pageaction-share" title="&pageactions.share.page;"
|
||||
onclick="SharingUI.show(getBrowser().currentURI.spec, getBrowser().contentTitle);"/>
|
||||
#endif
|
||||
<pageaction id="pageaction-password" title="&pageactions.password.forget;"
|
||||
onclick="PageActions.forgetPassword(event);"/>
|
||||
<pageaction id="pageaction-reset" title="&pageactions.reset;"
|
||||
onclick="PageActions.clearPagePermissions(event);"/>
|
||||
<pageaction id="pageaction-search" title="&pageactions.search.addNew;"/>
|
||||
<pageaction id="pageaction-charset" title="&pageactions.charEncoding;" onclick="CharsetMenu.show();"/>
|
||||
</hbox>
|
||||
</arrowbox>
|
||||
|
||||
<arrowbox id="bookmark-popup" hidden="true" align="stretch" offset="12" type="dialog">
|
||||
<hbox id="bookmark-popup-title">
|
||||
<label value="&bookmarkPopup.label;"/>
|
||||
</hbox>
|
||||
<richlistbox id="bookmark-popup-commands" class="action-buttons" onclick="BookmarkPopup.hide();" flex="1">
|
||||
<richlistitem class="action-button" id="bookmark-popup-edit" onclick="BookmarkHelper.edit();">
|
||||
<label value="&bookmarkEdit.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="action-button" id="bookmark-popup-remove" onclick="BookmarkPopup.hide(); BookmarkHelper.removeBookmarksForURI(getBrowser().currentURI);">
|
||||
<label value="&bookmarkRemove.label;"/>
|
||||
</richlistitem>
|
||||
#ifdef ANDROID
|
||||
<richlistitem class="action-button" id="bookmark-popup-shortcut" onclick="BookmarkPopup.addToHome();">
|
||||
<label value="&bookmarkShortcut.label;"/>
|
||||
</richlistitem>
|
||||
#endif
|
||||
</richlistbox>
|
||||
</arrowbox>
|
||||
|
||||
<box id="bookmark-container" class="perm-modal-block" hidden="true">
|
||||
<dialog id="bookmark-dialog" class="content-dialog" flex="1">
|
||||
<hbox id="bookmark-form-title" class="prompt-title">
|
||||
<description>&editBookmarkDialog.title;</description>
|
||||
</hbox>
|
||||
<separator id="bookmark-form-line" class="prompt-line"/>
|
||||
<scrollbox id="bookmark-form" align="start" class="prompt-message" flex="1"/>
|
||||
<hbox id="bookmark-form-buttons" pack="center" class="prompt-buttons">
|
||||
<button label="&editBookmarkDone.label;" class="prompt-button" oncommand="BookmarkHelper.save();"/>
|
||||
</hbox>
|
||||
</dialog>
|
||||
</box>
|
||||
|
||||
<!-- use an offset to remove the space taken by the invisible callout arrow -->
|
||||
<arrowbox id="appmenu-popup" hidden="true" type="dialog" offset="18">
|
||||
<box id="appmenu-popup-sitecommands"/>
|
||||
<vbox id="appmenu-popup-appcommands"/>
|
||||
</arrowbox>
|
||||
|
||||
<box id="panel-container" hidden="true" class="window-width window-height panel-dark"
|
||||
style="-moz-stack-sizing: ignore" left="10000">
|
||||
<box id="panel-container-inner" flex="1" class="panel-dark">
|
||||
<box id="panel-controls" class="panel-row-header" oncommand="BrowserUI.switchPane(event.target.getAttribute('linkedpanel'));">
|
||||
<toolbarbutton id="tool-preferences" label="&prefsHeader.label;" class="panel-row-button" type="radio" group="1" checked="true" linkedpanel="prefs-container"/>
|
||||
<toolbarbutton id="tool-downloads" label="&downloadsHeader.label;" class="panel-row-button" type="radio" group="1" linkedpanel="downloads-container"/>
|
||||
<toolbarbutton id="tool-addons" label="&addonsHeader.label;" class="panel-row-button" type="radio" group="1" linkedpanel="addons-container"/>
|
||||
<toolbarbutton id="tool-console" label="&consoleHeader.label;" class="panel-row-button" type="radio" group="1" hidden="true" linkedpanel="console-container"/>
|
||||
#ifndef ANDROID
|
||||
<spacer flex="1"/>
|
||||
<toolbarbutton id="tool-panel-close" class="panel-close" command="cmd_panel"/>
|
||||
#endif
|
||||
</box>
|
||||
<vbox flex="1">
|
||||
<deck id="panel-items" selectedIndex="2" flex="1">
|
||||
<vbox id="addons-container" flex="1">
|
||||
<notificationbox id="addons-messages" flex="1">
|
||||
<richlistbox id="addons-list" class="panel-list" flex="1" onselect="ExtensionsView.hideOnSelect(event)">
|
||||
<label id="addons-list-header" class="panel-header" value="&addonsHeader.label;"/>
|
||||
<richlistitem id="addons-local" class="section-header" align="center" nohighlight="true">
|
||||
<label value="&addonsLocal.label;" flex="1"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="addons-update-all" label="&addonsUpdate.label;" hidden="true"
|
||||
oncommand="ExtensionsView.updateAll();"/>
|
||||
</richlistitem>
|
||||
<richlistitem id="addons-repo" class="section-header" nohighlight="true">
|
||||
<label value="&addonsRepo.label;" flex="1"/>
|
||||
<textbox id="addons-search-text" flex="1" class="search-bar" placeholder="&addonsSearch2.emptytext;" type="search" searchbutton="false"
|
||||
oncommand="ExtensionsView.getAddonsFromRepo(this.value);" onkeypress="if (event.keyCode == event.DOM_VK_RETURN) this.blur();"/>
|
||||
</richlistitem>
|
||||
</richlistbox>
|
||||
</notificationbox>
|
||||
</vbox>
|
||||
|
||||
<vbox id="downloads-container" flex="1">
|
||||
<richlistbox id="downloads-list" class="panel-list" flex="1" onselect="this.ensureSelectedElementIsVisible()">
|
||||
<label id="downloads-list-header" class="panel-header" value="&downloadsHeader.label;"/>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
|
||||
<vbox id="prefs-container" flex="1">
|
||||
<notificationbox id="prefs-messages" flex="1">
|
||||
<richlistbox id="prefs-list" class="panel-list" seltype="single" flex="1" onselect="this.ensureSelectedElementIsVisible()">
|
||||
<label id="prefs-list-header" class="panel-header" value="&prefsHeader.label;"/>
|
||||
<setting title="&about.title;" type="control">
|
||||
<button id="prefs-about-button" label="&about.button;"
|
||||
#ifdef MOZ_OFFICIAL_BRANDING
|
||||
# these two point to the same page, this just matters for what shows up in the
|
||||
# URL bar
|
||||
oncommand="BrowserUI.newTab('about:firefox', Browser.selectedTab);"/>
|
||||
#else
|
||||
oncommand="BrowserUI.newTab('about:fennec', Browser.selectedTab);"/>
|
||||
#endif
|
||||
</setting>
|
||||
<setting id="prefs-uilanguage" title="&language.title;" type="control">
|
||||
<button id="prefs-uilanguage-button" label="&language.title;" onclick="PreferencesView.showLocalePicker();"/>
|
||||
</setting>
|
||||
<setting id="prefs-homepage" title="&homepage.title;" type="menulist">
|
||||
<menulist id="prefs-homepage-options" oncommand="PreferencesView.updateHomePage();">
|
||||
<menupopup onpopupshowing="PreferencesView.updateHomePageList();">
|
||||
<menuitem id="prefs-homepage-default" label="&homepage.default;" value="default"/>
|
||||
<menuitem id="prefs-homepage-none" label="&homepage.none;" value="none"/>
|
||||
<menuitem id="prefs-homepage-currentpage" label="&homepage.currentpage;" value="currentpage"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</setting>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<settings id="prefs-sync" label="&sync.title;">
|
||||
<setting id="sync-connect" title="&sync.notconnected;" type="control">
|
||||
<button label="&sync.connect;" oncommand="WeaveGlue.tryConnect();" />
|
||||
</setting>
|
||||
<setting id="sync-connected" class="setting-group" title="&sync.connected;" type="control" collapsed="true">
|
||||
<button id="sync-details" label="&sync.details;" type="checkbox" autocheck="false" checked="false" oncommand="WeaveGlue.showDetails();" />
|
||||
</setting>
|
||||
<setting id="sync-sync" class="setting-subgroup" type="control" collapsed="true">
|
||||
<button id="sync-syncButton" label="&sync.syncNow;" oncommand="WeaveGlue.sync();"/>
|
||||
</setting>
|
||||
<setting id="sync-device" class="setting-subgroup" type="string" title="&sync.deviceName;" onchange="WeaveGlue.changeName(this);" collapsed="true"/>
|
||||
<setting id="sync-disconnect" class="setting-subgroup" type="control" collapsed="true">
|
||||
<button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" />
|
||||
</setting>
|
||||
</settings>
|
||||
#endif
|
||||
<settings id="prefs-privacy" label="&privacy.title;">
|
||||
<setting pref="network.cookie.cookieBehavior" title="&allowCookies.title;" type="boolint" on="0" off="2"/>
|
||||
<setting pref="signon.rememberSignons" title="&rememberPasswords.title;" type="bool"/>
|
||||
<setting pref="privacy.donottrackheader.enabled" title="&doNotTrack.title;" type="bool"/>
|
||||
<setting id="prefs-master-password" title="&masterPassword.title;" type="bool" oncommand="MasterPasswordUI.show(this.value);"/>
|
||||
<setting title="&clearPrivateData2.title;" type="control">
|
||||
<button id="prefs-clear-data" label="&clearPrivateData.button;" command="cmd_sanitize"/>
|
||||
</setting>
|
||||
</settings>
|
||||
<settings id="prefs-content" label="&content.title;">
|
||||
<setting pref="browser.ui.zoom.reflow" title="&reflowZoom.title;" type="bool"/>
|
||||
<setting pref="permissions.default.image" title="&showImages.title;" type="boolint" on="1" off="2"/>
|
||||
<setting pref="javascript.enabled" type="bool" title="&enableJavaScript.title;"/>
|
||||
<setting pref="browser.menu.showCharacterEncoding" type="bool" localized="true" title="&showCharsetEncoding.title;"/>
|
||||
</settings>
|
||||
</richlistbox>
|
||||
</notificationbox>
|
||||
</vbox>
|
||||
|
||||
<vbox id="console-container" flex="1">
|
||||
<vbox id="console-header" class="panel-list">
|
||||
<label class="panel-header" value="&consoleHeader.label;"/>
|
||||
<hbox align="center">
|
||||
<label value="&consoleCodeEval.label;" control="console-eval-textbox"/>
|
||||
<textbox id="console-eval-textbox" class="toolbar search-bar" value="" onkeypress="ConsoleView.onEvalKeyPress(event)" flex="1"/>
|
||||
<button id="console-button-eval" class="show-text" label="&consoleEvaluate.label;" oncommand="ConsoleView.evaluateTypein()"/>
|
||||
</hbox>
|
||||
<hbox align="center" pack="end">
|
||||
<radiogroup id="console-filter" oncommand="ConsoleView.changeMode();">
|
||||
<radio id="console-filter-all" label="&consoleAll.label;" value="all" selected="true"/>
|
||||
<radio id="console-filter-messages" label="&consoleMessages.label;" value="message"/>
|
||||
<radio id="console-filter-warnings" label="&consoleWarnings.label;" value="warning"/>
|
||||
<radio id="console-filter-errors" label="&consoleErrors.label;" value="error"/>
|
||||
</radiogroup>
|
||||
<button id="console-clear" class="show-text" oncommand="ConsoleView.clearConsole();" label="&consoleClear.label;"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<richlistbox id="console-box" class="panel-list console-box" flex="1" onkeypress="ConsoleView.onConsoleBoxKeyPress(event)" oncontextmenu="ConsoleView.onContextMenu(event);"/>
|
||||
</vbox>
|
||||
</deck>
|
||||
</vbox>
|
||||
</box>
|
||||
</box>
|
||||
<vbox id="awesome-panels" hidden="true">
|
||||
<!-- Awesome header row -->
|
||||
<hbox id="awesome-header" class="panel-row-header">
|
||||
<toolbarbutton id="allpages-button" type="radio" group="awesome-header" label="&allPagesHeader.label;" command="cmd_openLocation" class="choice-all panel-row-button show-text"/>
|
||||
<toolbarbutton id="bookmarks-button" type="radio" group="awesome-header" label="&bookmarksHeader.label;" command="cmd_bookmarks" class="choice-bookmarks panel-row-button show-text"/>
|
||||
<toolbarbutton id="history-button" type="radio" group="awesome-header" label="&historyHeader.label;" command="cmd_history" class="choice-history panel-row-button show-text"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<toolbarbutton id="remotetabs-button" type="radio" group="awesome-header" label="&desktopHeader.label;" command="cmd_remoteTabs" class="choice-remotetabs panel-row-button show-text"/>
|
||||
#endif
|
||||
</hbox>
|
||||
|
||||
<!-- titlebar autocomplete results -->
|
||||
<vbox id="popup_autocomplete" class="panel-dark place-list" flex="1" onshow="BrowserUI._edit.showHistoryPopup();" hidden="true"/>
|
||||
<placelist id="bookmarks-items" class="place-list" type="bookmarks" onopen="BookmarkList.openLink(event);" onhide="BrowserUI.updateStar();" flex="1" hidden="true"/>
|
||||
<historylist id="history-items" class="place-list" onopen="HistoryList.openLink(event);" flex="1" hidden="true"/>
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<remotetabslist id="remotetabs-items" class="place-list" onopen="RemoteTabsList.openLink(event)" flex="1" hidden="true"/>
|
||||
#endif
|
||||
</vbox>
|
||||
|
||||
<!-- Form Helper form validation helper popup -->
|
||||
<arrowbox id="form-helper-validation-container" class="arrowbox-dark" flex="1" hidden="true" offset="0" top="0" left="0">
|
||||
<label/>
|
||||
</arrowbox>
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<box id="syncsetup-container" class="perm-modal-block" hidden="true">
|
||||
<dialog id="syncsetup-dialog" class="content-dialog" flex="1">
|
||||
<hbox class="prompt-title">
|
||||
<description>&sync.setup.title;</description>
|
||||
</hbox>
|
||||
<separator class="prompt-line"/>
|
||||
<vbox id="syncsetup-simple" class="syncsetup-page" flex="1">
|
||||
<scrollbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
|
||||
<description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.pair;</description>
|
||||
<description class="syncsetup-center link" flex="1" onclick="WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
|
||||
<separator/>
|
||||
<vbox align="center" flex="1">
|
||||
<description id="syncsetup-code1" class="syncsetup-code">....</description>
|
||||
<description id="syncsetup-code2" class="syncsetup-code">....</description>
|
||||
<description id="syncsetup-code3" class="syncsetup-code">....</description>
|
||||
</vbox>
|
||||
<separator/>
|
||||
<description class="syncsetup-center link" flex="1" onclick="WeaveGlue.openManual();">&sync.fallback;</description>
|
||||
<separator flex="1"/>
|
||||
</scrollbox>
|
||||
<hbox class="prompt-buttons" pack="center">
|
||||
<button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox id="syncsetup-waiting" class="syncsetup-page" flex="1" hidden="true">
|
||||
<description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.waiting;</description>
|
||||
</vbox>
|
||||
<vbox id="syncsetup-fallback" class="syncsetup-page" flex="1" hidden="true">
|
||||
<scrollbox class="prompt-message" orient="vertical" flex="1">
|
||||
<description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.manual;</description>
|
||||
<separator/>
|
||||
<textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="WeaveGlue.canConnect();"/>
|
||||
<textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="WeaveGlue.canConnect();"/>
|
||||
<textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.recoveryKey;" oninput="WeaveGlue.canConnect();"/>
|
||||
<separator class="thin"/>
|
||||
<button id="syncsetup-usecustomserver" type="checkbox" class="button-checkbox" pack="start" oncommand="WeaveGlue.toggleCustomServer();">
|
||||
<image class="button-image-icon"/>
|
||||
<description class="syncsetup-label prompt-checkbox-label" flex="1">&sync.customServer;</description>
|
||||
</button>
|
||||
<textbox id="syncsetup-customserver" class="prompt-edit" placeholder="&sync.serverURL;"/>
|
||||
<separator flex="1"/>
|
||||
</scrollbox>
|
||||
<hbox class="prompt-buttons" pack="center">
|
||||
<button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
|
||||
<separator/>
|
||||
<button id="syncsetup-button-connect" class="prompt-button" oncommand="WeaveGlue.close(); WeaveGlue.connect();">&sync.setup.connect;</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
</box>
|
||||
#endif
|
||||
|
||||
<arrowbox id="search-engines-popup" hidden="true" offset="18" flex="1" type="dialog">
|
||||
<hbox id="search-engines-list" class="action-buttons" flex="1"/>
|
||||
</arrowbox>
|
||||
|
||||
<arrowbox id="newtab-popup" class="arrowbox-dark" hidden="true" onclick="NewTabPopup.selectTab()" align="center" start="0">
|
||||
<label/>
|
||||
</arrowbox>
|
||||
|
||||
<!-- options dialog for select form field -->
|
||||
<vbox id="select-container" class="context-block" hidden="true">
|
||||
<vbox id="select-popup" class="dialog-dark">
|
||||
<hbox pack="center">
|
||||
<label id="select-title" class="options-title" align="center" crop="center" flex="1"/>
|
||||
</hbox>
|
||||
<scrollbox id="select-commands" onclick="if (event.target != this) SelectHelperUI.selectByIndex(event.target.optionIndex);" orient="vertical" flex="1"/>
|
||||
<hbox pack="center">
|
||||
<button label="&selectHelper.done;" oncommand="SelectHelperUI.hide();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
<hbox id="context-container" class="context-block" hidden="true">
|
||||
<vbox id="context-popup" class="dialog-dark">
|
||||
<hbox id="context-header">
|
||||
<label id="context-hint" crop="center" flex="1"/>
|
||||
</hbox>
|
||||
<richlistbox id="context-commands" onclick="ContextHelper.hide();" flex="1">
|
||||
<richlistitem class="context-command" id="context-copy" type="copy" onclick="ContextCommands.copy();">
|
||||
<label value="©.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-all" type="copy-all" onclick="ContextCommands.copy();">
|
||||
<label value="©All.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-paste" type="paste" onclick="ContextCommands.paste();">
|
||||
<label value="&paste.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
|
||||
<label value="&pasteAndGo.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-select-all" type="select-all" onclick="ContextCommands.selectAll();">
|
||||
<label value="&selectAll.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-openinnewtab" type="link-openable" onclick="ContextCommands.openInNewTab();">
|
||||
<label value="&contextOpenInNewTab.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-bookmark-link" type="link" onclick="ContextCommands.bookmarkLink();">
|
||||
<label value="&contextBookmarkLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
|
||||
<label value="&contextSaveImage.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
|
||||
<label value="&contextCopyLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-email" type="mailto" onclick="ContextCommands.copyEmail();">
|
||||
<label value="&contextCopyEmail.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-phone" type="callto" onclick="ContextCommands.copyPhone();">
|
||||
<label value="&contextCopyPhone.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-image-location" type="image" onclick="ContextCommands.copyImageLocation();">
|
||||
<label value="&contextCopyImageLocation.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-share-link" type="link-shareable" onclick="ContextCommands.shareLink();">
|
||||
<label value="&contextShareLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-share-image" type="image-shareable" onclick="ContextCommands.shareMedia();">
|
||||
<label value="&contextShareImage.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-play-media" type="media-paused" onclick="ContextCommands.sendCommand('play');">
|
||||
<label value="&contextPlayMedia.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-pause-video" type="media-playing" onclick="ContextCommands.sendCommand('pause');">
|
||||
<label value="&contextPauseMedia.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-fullscreen" type="video" onclick="ContextCommands.sendCommand('fullscreen');">
|
||||
<label value="&contextFullScreen.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-save-video" type="video" onclick="ContextCommands.saveImage();">
|
||||
<label value="&contextSaveVideo.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-share-video" type="video-shareable" onclick="ContextCommands.shareMedia();">
|
||||
<label value="&contextShareVideo.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-editbookmark" type="edit-bookmark" onclick="ContextCommands.editBookmark();">
|
||||
<label value="&contextEditBookmark.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-removebookmark" type="edit-bookmark" onclick="ContextCommands.removeBookmark();">
|
||||
<label value="&contextRemoveBookmark.label;"/>
|
||||
</richlistitem>
|
||||
#ifdef ANDROID
|
||||
<richlistitem class="context-command" id="context-shortcutbookmark" type="edit-bookmark" onclick="ContextCommands.shortcutBookmark();">
|
||||
<label value="&contextShortcutBookmark.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-select-input" type="input-text" onclick="ContextCommands.selectInput();">
|
||||
<label value="&inputMethod.label;"/>
|
||||
</richlistitem>
|
||||
#endif
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<toolbarbutton id="selectionhandle-start" label="^" left="0" top="0" hidden="true"/>
|
||||
<toolbarbutton id="selectionhandle-end" label="^" left="0" top="0" hidden="true"/>
|
||||
|
||||
<hbox id="menulist-container" class="context-block" hidden="true">
|
||||
<vbox id="menulist-popup" class="dialog-dark">
|
||||
<label id="menulist-title" class="options-title" crop="center" flex="1"/>
|
||||
<richlistbox id="menulist-commands" class="action-buttons" onclick="if (event.target != this) MenuListHelperUI.selectByIndex(this.selectedIndex);" flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- alerts for content -->
|
||||
<hbox id="alerts-container" hidden="true" align="start" bottom="0" onclick="AlertsHelper.click(event);">
|
||||
<image id="alerts-image"/>
|
||||
<vbox flex="1">
|
||||
<label id="alerts-title" value=""/>
|
||||
<description id="alerts-text" flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<hbox id="appmenu-overflow" bottom="0" hidden="true" oncommand="AppMenu.hideOverflow();">
|
||||
<richlistbox id="appmenu-overflow-commands" flex="1"/>
|
||||
</hbox>
|
||||
|
||||
<hbox id="appmenu" bottom="0" hidden="true" align="stretch" oncommand="AppMenu.hide();">
|
||||
<toolbarbutton class="appmenu-site-button appmenu-button appmenu-pageaction"
|
||||
label="&appMenu.siteOptions;"
|
||||
oncommand="getIdentityHandler().show(); event.stopPropagation();"/>
|
||||
<toolbarbutton class="appmenu-preferences-button appmenu-button"
|
||||
label="&prefsHeader.label;"
|
||||
oncommand="BrowserUI.showPanel('prefs-container');"/>
|
||||
<toolbarbutton class="appmenu-addons-button appmenu-button"
|
||||
label="&addonsHeader.label;"
|
||||
oncommand="BrowserUI.showPanel('addons-container');"/>
|
||||
<toolbarbutton class="appmenu-share-button appmenu-button appmenu-pageaction"
|
||||
label="&pageactions.share.page;"
|
||||
oncommand="SharingUI.show(getBrowser().currentURI.spec, getBrowser().contentTitle);"/>
|
||||
<toolbarbutton class="appmenu-findinpage-button appmenu-button appmenu-pageaction"
|
||||
label="&pageactions.findInPage;"
|
||||
oncommand="FindHelperUI.show();"/>
|
||||
<toolbarbutton class="appmenu-downloads-button appmenu-button"
|
||||
label="&downloadsHeader.label;"
|
||||
oncommand="BrowserUI.showPanel('downloads-container');"/>
|
||||
#ifdef NS_PRINTING
|
||||
<toolbarbutton class="appmenu-saveas-button appmenu-button appmenu-pageaction"
|
||||
label="&pageactions.saveas.pdf;"
|
||||
oncommand="PageActions.savePageAsPDF();"/>
|
||||
#endif
|
||||
<toolbarbutton class="appmenu-quit-button appmenu-button"
|
||||
label="&pageactions.quit;"
|
||||
oncommand="Browser.quit();"/>
|
||||
</hbox>
|
||||
</stack>
|
||||
|
||||
<svg:svg height="0">
|
||||
<svg:mask id="back-button-mask" maskContentUnits="objectBoundingBox">
|
||||
<svg:rect x="0" y="0" width="1" height="1" fill="white"/>
|
||||
<svg:circle cx="-0.85" cy="0.5" r="0.96"/>
|
||||
</svg:mask>
|
||||
</svg:svg>
|
||||
<browser id="home" type="content-primary" flex="1"/>
|
||||
|
||||
</window>
|
||||
|
@ -1,39 +1,3 @@
|
||||
/* -*- Mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is BrowserCLH.js
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Crowder <crowder@fiverocks.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@ -42,257 +6,46 @@ const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function openWindow(aParent, aURL, aTarget, aFeatures, aArgs) {
|
||||
let argString = null;
|
||||
if (aArgs && !(aArgs instanceof Ci.nsISupportsArray)) {
|
||||
argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
argString.data = aArgs;
|
||||
}
|
||||
|
||||
return Services.ww.openWindow(aParent, aURL, aTarget, aFeatures, argString || aArgs);
|
||||
}
|
||||
|
||||
function resolveURIInternal(aCmdLine, aArgument) {
|
||||
let uri = aCmdLine.resolveURI(aArgument);
|
||||
|
||||
if (!(uri instanceof Ci.nsIFileURL))
|
||||
return uri;
|
||||
|
||||
try {
|
||||
if (uri.file.exists())
|
||||
return uri;
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
try {
|
||||
let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
|
||||
uri = urifixup.createFixupURI(aArgument, 0);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a home page override is needed.
|
||||
* Returns:
|
||||
* "new profile" if this is the first run with a new profile.
|
||||
* "new version" if this is the first run with a build with a different
|
||||
* Gecko milestone (i.e. right after an upgrade).
|
||||
* "none" otherwise.
|
||||
*/
|
||||
function needHomepageOverride() {
|
||||
let savedmstone = null;
|
||||
try {
|
||||
savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
|
||||
} catch (e) {}
|
||||
|
||||
if (savedmstone == "ignore")
|
||||
return "none";
|
||||
|
||||
#expand let ourmstone = "__MOZ_APP_VERSION__";
|
||||
|
||||
if (ourmstone != savedmstone) {
|
||||
Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourmstone);
|
||||
|
||||
return (savedmstone ? "new version" : "new profile");
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
function getHomePage() {
|
||||
let url = "about:home";
|
||||
try {
|
||||
url = Services.prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
|
||||
} catch (e) { }
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
function showPanelWhenReady(aWindow, aPage) {
|
||||
aWindow.addEventListener("UIReadyDelayed", function(aEvent) {
|
||||
aWindow.BrowserUI.showPanel(aPage);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function haveSystemLocale() {
|
||||
let localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);
|
||||
let systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE");
|
||||
return isLocaleAvailable(systemLocale);
|
||||
}
|
||||
|
||||
function checkCurrentLocale() {
|
||||
if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
|
||||
// if the user has a compatible locale from a different buildid, we need to update
|
||||
var buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformBuildID;
|
||||
let localeBuildID = Services.prefs.getCharPref("extensions.compatability.locales.buildid");
|
||||
if (buildID != localeBuildID)
|
||||
return false;
|
||||
|
||||
let currentLocale = Services.prefs.getCharPref("general.useragent.locale");
|
||||
return isLocaleAvailable(currentLocale);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isLocaleAvailable(aLocale) {
|
||||
let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
|
||||
chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
|
||||
let availableLocales = chrome.getLocalesForPackage("browser");
|
||||
|
||||
let locale = aLocale.split("-")[0];
|
||||
let localeRegEx = new RegExp("^" + locale);
|
||||
|
||||
while (availableLocales.hasMore()) {
|
||||
let locale = availableLocales.getNext();
|
||||
if (localeRegEx.test(locale))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
function dump(a) {
|
||||
Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService)
|
||||
.logStringMessage(a);
|
||||
}
|
||||
|
||||
function BrowserCLH() { }
|
||||
|
||||
BrowserCLH.prototype = {
|
||||
//
|
||||
// nsICommandLineHandler
|
||||
//
|
||||
|
||||
handle: function fs_handle(aCmdLine) {
|
||||
// Instantiate the search service so the search engine cache is created now
|
||||
// instead when the application is running. The install process will register
|
||||
// this component by using the -silent command line flag, thereby creating
|
||||
// the cache during install, not runtime.
|
||||
// NOTE: This code assumes this CLH is run before the nsDefaultCLH, which
|
||||
// consumes the "-silent" flag.
|
||||
if (aCmdLine.findFlag("silent", false) > -1) {
|
||||
let searchService = Services.search;
|
||||
let autoComplete = Cc["@mozilla.org/autocomplete/search;1?name=history"].
|
||||
getService(Ci.nsIAutoCompleteSearch);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle chrome windows loaded via commandline
|
||||
let chromeParam = aCmdLine.handleFlagWithParam("chrome", false);
|
||||
if (chromeParam) {
|
||||
try {
|
||||
// Only load URIs which do not inherit chrome privs
|
||||
let features = "chrome,dialog=no,all";
|
||||
let uri = resolveURIInternal(aCmdLine, chromeParam);
|
||||
let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
|
||||
if (!netutil.URIChainHasFlags(uri, Ci.nsIHttpProtocolHandler.URI_INHERITS_SECURITY_CONTEXT)) {
|
||||
openWindow(null, uri.spec, "_blank", features, null);
|
||||
|
||||
// Stop the normal commandline processing from continuing
|
||||
let urlParam = aCmdLine.handleFlagWithParam("remote", false);
|
||||
if (urlParam) {
|
||||
// TODO:
|
||||
// browserWin.browserDOMWindow will be null if
|
||||
// the chrome page hasn't loaded yet. We
|
||||
// should test for this, and reschedule the
|
||||
// event.
|
||||
aCmdLine.preventDefault = true;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
try {
|
||||
dump("fs_handle");
|
||||
let urifixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
|
||||
dump("fs_handle: " + urlParam);
|
||||
let uri = urifixup.createFixupURI(urlParam, 1);
|
||||
if (!uri)
|
||||
return;
|
||||
dump("fs_handle: " + uri);
|
||||
|
||||
let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
browserWin.browserDOMWindow.openURI(uri,
|
||||
null,
|
||||
Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW,
|
||||
Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
|
||||
} catch (x) {
|
||||
Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService)
|
||||
.logStringMessage("fs_handle exception!: " + x);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check and remove the alert flag here, but we'll handle it a bit later - see below
|
||||
let alertFlag = aCmdLine.handleFlagWithParam("alert", false);
|
||||
|
||||
// Check and remove the webapp param
|
||||
let appFlag = aCmdLine.handleFlagWithParam("webapp", false);
|
||||
let appURI;
|
||||
if (appFlag)
|
||||
appURI = resolveURIInternal(aCmdLine, appFlag);
|
||||
|
||||
// Keep an array of possible URL arguments
|
||||
let uris = [];
|
||||
|
||||
// Check for the "url" flag
|
||||
let uriFlag = aCmdLine.handleFlagWithParam("url", false);
|
||||
if (uriFlag) {
|
||||
let uri = resolveURIInternal(aCmdLine, uriFlag);
|
||||
if (uri)
|
||||
uris.push(uri);
|
||||
}
|
||||
|
||||
for (let i = 0; i < aCmdLine.length; i++) {
|
||||
let arg = aCmdLine.getArgument(i);
|
||||
if (!arg || arg[0] == '-')
|
||||
continue;
|
||||
|
||||
let uri = resolveURIInternal(aCmdLine, arg);
|
||||
if (uri)
|
||||
uris.push(uri);
|
||||
}
|
||||
|
||||
// Open the main browser window, if we don't already have one
|
||||
let browserWin;
|
||||
try {
|
||||
let localeWin = Services.wm.getMostRecentWindow("navigator:localepicker");
|
||||
if (localeWin) {
|
||||
localeWin.focus();
|
||||
aCmdLine.preventDefault = true;
|
||||
return;
|
||||
}
|
||||
|
||||
browserWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
if (!browserWin) {
|
||||
// Default to the saved homepage
|
||||
let defaultURL = getHomePage();
|
||||
|
||||
// Override the default if we have a URL passed on command line
|
||||
if (uris.length > 0) {
|
||||
defaultURL = uris[0].spec;
|
||||
uris = uris.slice(1);
|
||||
}
|
||||
|
||||
// Show the locale selector if we have a new profile, or if the selected locale is no longer compatible
|
||||
let showLocalePicker = Services.prefs.getBoolPref("browser.firstrun.show.localepicker")
|
||||
if ((needHomepageOverride() == "new profile" && showLocalePicker && !haveSystemLocale()) || !checkCurrentLocale()) {
|
||||
browserWin = openWindow(null, "chrome://browser/content/localePicker.xul", "_blank", "chrome,dialog=no,all", defaultURL);
|
||||
aCmdLine.preventDefault = true;
|
||||
return;
|
||||
}
|
||||
|
||||
browserWin = openWindow(null, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", defaultURL);
|
||||
}
|
||||
|
||||
browserWin.focus();
|
||||
|
||||
// Stop the normal commandline processing from continuing. We just opened the main browser window
|
||||
aCmdLine.preventDefault = true;
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
// Assumption: All remaining command line arguments have been sent remotely (browser is already running)
|
||||
// Action: Open any URLs we find into an existing browser window
|
||||
|
||||
// First, get a browserDOMWindow object
|
||||
while (!browserWin.browserDOMWindow)
|
||||
Services.tm.currentThread.processNextEvent(true);
|
||||
|
||||
// Open any URIs into new tabs
|
||||
for (let i = 0; i < uris.length; i++)
|
||||
browserWin.browserDOMWindow.openURI(uris[i], null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
|
||||
|
||||
if (appURI)
|
||||
browserWin.browserDOMWindow.openURI(appURI, null, browserWin.OPEN_APPTAB, Ci.nsIBrowserDOMWindow.OPEN_NEW);
|
||||
|
||||
// Handle the notification, if called from it
|
||||
if (alertFlag) {
|
||||
if (alertFlag == "update-app") {
|
||||
// Notification was already displayed and clicked, skip it next time
|
||||
Services.prefs.setBoolPref("app.update.skipNotification", true);
|
||||
|
||||
var updateService = Cc["@mozilla.org/updates/update-service;1"].getService(Ci.nsIApplicationUpdateService);
|
||||
var updateTimerCallback = updateService.QueryInterface(Ci.nsITimerCallback);
|
||||
updateTimerCallback.notify(null);
|
||||
} else if (alertFlag.length >= 9 && alertFlag.substr(0, 9) == "download:") {
|
||||
showPanelWhenReady(browserWin, "downloads-container");
|
||||
} else if (alertFlag == "addons") {
|
||||
showPanelWhenReady(browserWin, "addons-container");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// QI
|
||||
|
@ -565,6 +565,10 @@ report_mapping(char *name, void *base, uint32_t len, uint32_t offset)
|
||||
|
||||
extern "C" void simple_linker_init(void);
|
||||
|
||||
extern "C" struct timeval timings[2];
|
||||
#define TIMING_RELOC 0
|
||||
#define TIMING_CONSTRUCTORS 1
|
||||
|
||||
static void
|
||||
loadLibs(const char *apkName)
|
||||
{
|
||||
@ -651,6 +655,9 @@ loadLibs(const char *apkName)
|
||||
(usage2.ru_utime.tv_sec - usage1.ru_utime.tv_sec)*1000 + (usage2.ru_utime.tv_usec - usage1.ru_utime.tv_usec)/1000,
|
||||
(usage2.ru_stime.tv_sec - usage1.ru_stime.tv_sec)*1000 + (usage2.ru_stime.tv_usec - usage1.ru_stime.tv_usec)/1000,
|
||||
usage2.ru_majflt-usage1.ru_majflt);
|
||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Spent %dms on relocations, %dms on constructors",
|
||||
timings[TIMING_RELOC].tv_sec * 1000 + timings[TIMING_RELOC].tv_usec / 1000,
|
||||
timings[TIMING_CONSTRUCTORS].tv_sec * 1000 + timings[TIMING_CONSTRUCTORS].tv_usec / 1000);
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT void JNICALL
|
||||
|
@ -43,7 +43,6 @@ static const char *dl_errors[] = {
|
||||
#define unlikely(expr) __builtin_expect (expr, 0)
|
||||
|
||||
static pthread_mutex_t dl_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
extern int extractLibs;
|
||||
|
||||
static void set_dlerror(int err)
|
||||
{
|
||||
@ -54,9 +53,6 @@ static void set_dlerror(int err)
|
||||
|
||||
void *__wrap_dlopen(const char *filename, int flag)
|
||||
{
|
||||
if (extractLibs)
|
||||
return dlopen(filename, flag);
|
||||
|
||||
soinfo *ret;
|
||||
|
||||
pthread_mutex_lock(&dl_lock);
|
||||
@ -88,9 +84,6 @@ void *moz_mapped_dlopen(const char *filename, int flag,
|
||||
|
||||
const char *__wrap_dlerror(void)
|
||||
{
|
||||
if (extractLibs)
|
||||
return dlerror();
|
||||
|
||||
const char *tmp = dl_err_str;
|
||||
dl_err_str = NULL;
|
||||
return (const char *)tmp;
|
||||
@ -98,9 +91,6 @@ const char *__wrap_dlerror(void)
|
||||
|
||||
void *__wrap_dlsym(void *handle, const char *symbol)
|
||||
{
|
||||
if (extractLibs)
|
||||
return dlsym(handle, symbol);
|
||||
|
||||
soinfo *found;
|
||||
Elf32_Sym *sym;
|
||||
unsigned bind;
|
||||
@ -183,9 +173,6 @@ int __wrap_dladdr(void *addr, Dl_info *info)
|
||||
|
||||
int __wrap_dlclose(void *handle)
|
||||
{
|
||||
if (extractLibs)
|
||||
return dlclose(handle);
|
||||
|
||||
pthread_mutex_lock(&dl_lock);
|
||||
(void)unload_library((soinfo*)handle);
|
||||
pthread_mutex_unlock(&dl_lock);
|
||||
|
@ -96,6 +96,10 @@ static soinfo *sonext = &libdl_info;
|
||||
static soinfo *somain; /* main process, always the one after libdl_info */
|
||||
#endif
|
||||
|
||||
/* Keep track of cumulative time spent in relocations and static constructors */
|
||||
#define TIMING_RELOC 0
|
||||
#define TIMING_CONSTRUCTORS 1
|
||||
struct timeval timings[2] = { { 0, 0 }, { 0, 0 } };
|
||||
|
||||
/* Set up for the buddy allocator managing the non-prelinked libraries. */
|
||||
static struct ba_bits ba_nonprelink_bitmap[(LIBLAST - LIBBASE) / LIBINC];
|
||||
@ -1317,9 +1321,11 @@ soinfo *find_library(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
si = dlopen(name, RTLD_LAZY);
|
||||
if (si)
|
||||
return si;
|
||||
if (strncmp(name, getenv("CACHE_PATH"), strlen(getenv("CACHE_PATH")))) {
|
||||
si = dlopen(name, RTLD_LAZY);
|
||||
if (si)
|
||||
return si;
|
||||
}
|
||||
|
||||
TRACE("[ %5d '%s' has not been loaded yet. Locating...]\n", pid, name);
|
||||
si = load_library(name);
|
||||
@ -1980,6 +1986,7 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
unsigned *d;
|
||||
Elf32_Phdr *phdr = si->phdr;
|
||||
int phnum = si->phnum;
|
||||
struct timeval t0, t1;
|
||||
|
||||
INFO("[ %5d linking %s ]\n", pid, si->name);
|
||||
DEBUG("%5d si->base = 0x%08x si->flags = 0x%08x\n", pid,
|
||||
@ -2181,8 +2188,6 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
memset(preloads, 0, sizeof(preloads));
|
||||
for(i = 0; ldpreload_names[i] != NULL; i++) {
|
||||
soinfo *lsi = find_library(ldpreload_names[i]);
|
||||
if(lsi == 0)
|
||||
lsi = dlopen(ldpreload_names[i], RTLD_LAZY);
|
||||
if(lsi == 0) {
|
||||
strlcpy(tmp_err_buf, linker_get_error(), sizeof(tmp_err_buf));
|
||||
DL_ERR("%5d could not load needed library '%s' for '%s' (%s)",
|
||||
@ -2197,9 +2202,7 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
for(d = si->dynamic; *d; d += 2) {
|
||||
if(d[0] == DT_NEEDED){
|
||||
DEBUG("%5d %s needs %s\n", pid, si->name, si->strtab + d[1]);
|
||||
soinfo *lsi = dlopen(si->strtab + d[1], RTLD_LAZY);
|
||||
if(lsi == 0)
|
||||
lsi = find_library(si->strtab + d[1]);
|
||||
soinfo *lsi = find_library(si->strtab + d[1]);
|
||||
if(lsi == 0) {
|
||||
strlcpy(tmp_err_buf, linker_get_error(), sizeof(tmp_err_buf));
|
||||
DL_ERR("%5d could not load needed library '%s' for '%s' (%s)",
|
||||
@ -2218,6 +2221,7 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&t0, 0);
|
||||
#ifndef ANDROID_NO_RUNTIME_RELOC
|
||||
/* Initialize GOT[1] and GOT[2], which are used by the PLT trampoline */
|
||||
Elf32_Addr *got = (Elf32_Addr *)si->plt_got;
|
||||
@ -2264,6 +2268,10 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
si->flags |= FLAG_LINKED;
|
||||
DEBUG("[ %5d finished linking %s ]\n", pid, si->name);
|
||||
|
||||
gettimeofday(&t1, 0);
|
||||
timings[TIMING_RELOC].tv_usec += t1.tv_usec - t0.tv_usec;
|
||||
timings[TIMING_RELOC].tv_sec += t1.tv_sec - t0.tv_sec;
|
||||
|
||||
#if 0
|
||||
/* This is the way that the old dynamic linker did protection of
|
||||
* non-writable areas. It would scan section headers and find where
|
||||
@ -2298,7 +2306,12 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
||||
*/
|
||||
if (getuid() != geteuid() || getgid() != getegid())
|
||||
nullify_closed_stdio ();
|
||||
gettimeofday(&t0, 0);
|
||||
call_constructors(si);
|
||||
gettimeofday(&t1, 0);
|
||||
timings[TIMING_CONSTRUCTORS].tv_usec += t1.tv_usec - t0.tv_usec;
|
||||
timings[TIMING_CONSTRUCTORS].tv_sec += t1.tv_sec - t0.tv_sec;
|
||||
|
||||
notify_gdb_of_load(si);
|
||||
return 0;
|
||||
|
||||
|
@ -50,7 +50,6 @@ PARALLEL_DIRS = \
|
||||
content \
|
||||
locales \
|
||||
mozapps/downloads \
|
||||
mozapps/extensions \
|
||||
mozapps/handling \
|
||||
mozapps/preferences \
|
||||
mozapps/plugins \
|
||||
@ -63,6 +62,16 @@ PARALLEL_DIRS = \
|
||||
themes \
|
||||
$(NULL)
|
||||
|
||||
#
|
||||
# The native front end is not going to use extensions based on this code.
|
||||
# If it isn't used, it still takes up .5mb in cached statement. fail for me.
|
||||
# Ideally we start moving other optional stuff into this section.
|
||||
ifdef XXXXX
|
||||
PARALLEL_DIRS += \
|
||||
mozapps/extensions \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gtk2 qt,$(MOZ_WIDGET_TOOLKIT)))
|
||||
PARALLEL_DIRS += system/unixproxy
|
||||
endif
|
||||
|
@ -473,6 +473,13 @@ nsNavHistory::~nsNavHistory()
|
||||
nsresult
|
||||
nsNavHistory::Init()
|
||||
{
|
||||
|
||||
// XXX
|
||||
// For the native ui on android, we will not be using MOZ_PLACES.
|
||||
// Currently places has deeply weaved it way throughout the gecko codebase.
|
||||
// Here we disable all database creation and loading of places.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
NS_TIME_FUNCTION;
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefService =
|
||||
|
@ -321,9 +321,9 @@ INNER_MAKE_PACKAGE = \
|
||||
make -C ../embedding/android gecko.ap_ && \
|
||||
cp ../embedding/android/gecko.ap_ $(_ABS_DIST) && \
|
||||
( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \
|
||||
rm -rf lib && \
|
||||
mkdir -p lib/$(ABI_DIR) && \
|
||||
mv libmozutils.so lib/$(ABI_DIR) && \
|
||||
cp lib*.so lib && \
|
||||
mv libmozutils.so $(MOZ_CHILD_PROCESS_NAME) lib/$(ABI_DIR) && \
|
||||
rm -f lib.id && \
|
||||
for SOMELIB in *.so ; \
|
||||
do \
|
||||
|
@ -251,6 +251,12 @@ GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DMOZILLA_OFFICIAL
|
||||
endif
|
||||
|
||||
DEFINES += -DAPP_VERSION=$(MOZ_APP_VERSION)
|
||||
|
||||
$(srcdir)/nsAppRunner.cpp: $(DEPTH)/config/buildid $(topsrcdir)/config/milestone.txt
|
||||
|
||||
platform.ini: FORCE
|
||||
|
@ -57,6 +57,9 @@
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args)
|
||||
|
||||
#define _STR(s) # s
|
||||
#define STR(s) _STR(s)
|
||||
|
||||
struct AutoAttachJavaThread {
|
||||
AutoAttachJavaThread() {
|
||||
attached = mozilla_AndroidBridge_SetMainThread((void*)pthread_self());
|
||||
@ -97,20 +100,6 @@ GeckoStart(void *data)
|
||||
LOG("Failed to get GRE_HOME from the env vars");
|
||||
return 0;
|
||||
}
|
||||
nsCAutoString appini_path(greHome);
|
||||
appini_path.AppendLiteral("/application.ini");
|
||||
rv = NS_NewNativeLocalFile(appini_path, PR_FALSE, getter_AddRefs(appini));
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG("Failed to create nsILocalFile for appdata\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsXREAppData *appData;
|
||||
rv = XRE_CreateAppData(appini, &appData);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG("Failed to load application.ini from %s\n", appini_path.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILocalFile> xreDir;
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(greHome), PR_FALSE, getter_AddRefs(xreDir));
|
||||
@ -119,7 +108,25 @@ GeckoStart(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
appData->xreDirectory = xreDir.get();
|
||||
nsXREAppData appData = {
|
||||
sizeof(nsXREAppData),
|
||||
xreDir.get(),
|
||||
"Mozilla",
|
||||
"Fennec",
|
||||
STR(APP_VERSION),
|
||||
STR(GRE_BUILDID),
|
||||
"{a23983c0-fd0e-11dc-95ff-0800200c9a66}",
|
||||
NULL,
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
NS_XRE_ENABLE_EXTENSION_MANAGER | NS_XRE_ENABLE_CRASH_REPORTER,
|
||||
#else
|
||||
NS_XRE_ENABLE_EXTENSION_MANAGER,
|
||||
#endif
|
||||
xreDir.get(),
|
||||
STR(GRE_MILESTONE),
|
||||
STR(GRE_MILESTONE),
|
||||
"https://crash-reports.mozilla.com/submit"
|
||||
};
|
||||
|
||||
nsTArray<char *> targs;
|
||||
char *arg = strtok(static_cast<char *>(data), " ");
|
||||
@ -129,13 +136,11 @@ GeckoStart(void *data)
|
||||
}
|
||||
targs.AppendElement(static_cast<char *>(nsnull));
|
||||
|
||||
int result = XRE_main(targs.Length() - 1, targs.Elements(), appData);
|
||||
int result = XRE_main(targs.Length() - 1, targs.Elements(), &appData);
|
||||
|
||||
if (result)
|
||||
LOG("XRE_main returned %d", result);
|
||||
|
||||
XRE_FreeAppData(appData);
|
||||
|
||||
mozilla::AndroidBridge::Bridge()->NotifyXreExit();
|
||||
|
||||
free(targs[0]);
|
||||
|
@ -137,7 +137,6 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
jGetDpi = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getDpi", "()I");
|
||||
jSetFullScreen = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setFullScreen", "(Z)V");
|
||||
jShowInputMethodPicker = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "showInputMethodPicker", "()V");
|
||||
jHideProgressDialog = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideProgressDialog", "()V");
|
||||
jPerformHapticFeedback = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "performHapticFeedback", "(Z)V");
|
||||
jSetKeepScreenOn = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setKeepScreenOn", "(Z)V");
|
||||
jIsNetworkLinkUp = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isNetworkLinkUp", "()Z");
|
||||
@ -151,6 +150,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
jPostToJavaThread = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "postToJavaThread", "(Z)V");
|
||||
jInitCamera = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "initCamera", "(Ljava/lang/String;III)[I");
|
||||
jCloseCamera = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "closeCamera", "()V");
|
||||
jHandleGeckoMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "handleGeckoMessage", "(Ljava/lang/String;)V");
|
||||
|
||||
jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
|
||||
jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
|
||||
@ -650,17 +650,6 @@ AndroidBridge::SetFullScreen(bool aFullScreen)
|
||||
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jSetFullScreen, aFullScreen);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::HideProgressDialogOnce()
|
||||
{
|
||||
static bool once = false;
|
||||
if (!once) {
|
||||
ALOG_BRIDGE("AndroidBridge::HideProgressDialogOnce");
|
||||
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jHideProgressDialog);
|
||||
once = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::PerformHapticFeedback(bool aIsLongPress)
|
||||
{
|
||||
@ -935,10 +924,10 @@ AndroidBridge::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, co
|
||||
void
|
||||
AndroidBridge::PostToJavaThread(nsIRunnable* aRunnable, bool aMainThread)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "%s", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("GeckoBridge", "%s", __PRETTY_FUNCTION__);
|
||||
JNIEnv* env = AndroidBridge::AttachThread(false);
|
||||
if (!env) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "no jni env in %s!!", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("no jni env in %s!!", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
mRunnableQueue.AppendObject(aRunnable);
|
||||
@ -949,27 +938,49 @@ AndroidBridge::PostToJavaThread(nsIRunnable* aRunnable, bool aMainThread)
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::ExecuteNextRunnable()
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "%s", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
JNIEnv* env = AndroidBridge::AttachThread(false);
|
||||
if (!env) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "no jni env in %s!!", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("no jni env in %s!!", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mRunnableQueue.Count() > 0) {
|
||||
nsIRunnable* r = mRunnableQueue[0];
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "going to run %p", r);
|
||||
ALOG_BRIDGE("going to run %p", r);
|
||||
r->Run();
|
||||
mRunnableQueue.RemoveObjectAt(0);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
|
||||
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::HandleGeckoMessage(const nsAString& aMessage)
|
||||
{
|
||||
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
|
||||
JNIEnv* env = AndroidBridge::AttachThread(false);
|
||||
if (!env) {
|
||||
ALOG_BRIDGE("no jni env in %s!!", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoLocalJNIFrame jniFrame(1);
|
||||
jstring jMessage = mJNIEnv->NewString(nsPromiseFlatString(aMessage).get(), aMessage.Length());
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jHandleGeckoMessage, jMessage);
|
||||
|
||||
jthrowable ex = env->ExceptionOccurred();
|
||||
if (ex) {
|
||||
env->ExceptionDescribe();
|
||||
env->ExceptionClear();
|
||||
}
|
||||
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1002,9 +1013,7 @@ AndroidBridge::OpenGraphicsLibraries()
|
||||
ANativeWindow_setBuffersGeometry = (int (*)(void*, int, int, int)) dlsym(handle, "ANativeWindow_setBuffersGeometry");
|
||||
ANativeWindow_lock = (int (*)(void*, void*, void*)) dlsym(handle, "ANativeWindow_lock");
|
||||
ANativeWindow_unlockAndPost = (int (*)(void*))dlsym(handle, "ANativeWindow_unlockAndPost");
|
||||
|
||||
mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release && ANativeWindow_lock && ANativeWindow_unlockAndPost;
|
||||
|
||||
ALOG_BRIDGE("Successfully opened libandroid.so, have native window access? %d", mHasNativeWindowAccess);
|
||||
}
|
||||
}
|
||||
@ -1188,3 +1197,21 @@ AndroidBridge::UnlockWindow(void* window)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS1(nsAndroidBridge, nsIAndroidBridge)
|
||||
|
||||
nsAndroidBridge::nsAndroidBridge()
|
||||
{
|
||||
}
|
||||
|
||||
nsAndroidBridge::~nsAndroidBridge()
|
||||
{
|
||||
}
|
||||
|
||||
/* void handleGeckoEvent (in AString message); */
|
||||
NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(const nsAString & message)
|
||||
{
|
||||
AndroidBridge::Bridge()->HandleGeckoMessage(message);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -52,6 +52,8 @@
|
||||
#include "nsIMIMEInfo.h"
|
||||
#include "nsColor.h"
|
||||
|
||||
#include "nsIAndroidBridge.h"
|
||||
|
||||
// Some debug #defines
|
||||
// #define DEBUG_ANDROID_EVENTS
|
||||
// #define DEBUG_ANDROID_WIDGET
|
||||
@ -199,8 +201,6 @@ public:
|
||||
|
||||
void ShowInputMethodPicker();
|
||||
|
||||
void HideProgressDialogOnce();
|
||||
|
||||
bool IsNetworkLinkUp();
|
||||
|
||||
bool IsNetworkLinkKnown();
|
||||
@ -280,6 +280,8 @@ public:
|
||||
|
||||
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
|
||||
bool UnlockWindow(void *window);
|
||||
|
||||
void HandleGeckoMessage(const nsAString& message);
|
||||
|
||||
bool InitCamera(const nsCString& contentType, PRUint32 camera, PRUint32 *width, PRUint32 *height, PRUint32 *fps);
|
||||
|
||||
@ -341,7 +343,6 @@ protected:
|
||||
jmethodID jGetDpi;
|
||||
jmethodID jSetFullScreen;
|
||||
jmethodID jShowInputMethodPicker;
|
||||
jmethodID jHideProgressDialog;
|
||||
jmethodID jPerformHapticFeedback;
|
||||
jmethodID jSetKeepScreenOn;
|
||||
jmethodID jIsNetworkLinkUp;
|
||||
@ -355,6 +356,7 @@ protected:
|
||||
jmethodID jPostToJavaThread;
|
||||
jmethodID jInitCamera;
|
||||
jmethodID jCloseCamera;
|
||||
jmethodID jHandleGeckoMessage;
|
||||
|
||||
// stuff we need for CallEglCreateWindowSurface
|
||||
jclass jEGLSurfaceImplClass;
|
||||
@ -379,6 +381,27 @@ protected:
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define NS_ANDROIDBRIDGE_CID \
|
||||
{ 0x0FE2321D, 0xEBD9, 0x467D, \
|
||||
{ 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E } }
|
||||
|
||||
class nsAndroidBridge : public nsIAndroidBridge
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIANDROIDBRIDGE
|
||||
|
||||
nsAndroidBridge();
|
||||
|
||||
private:
|
||||
~nsAndroidBridge();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
extern "C" JNIEnv * GetJNIForThread();
|
||||
extern bool mozilla_AndroidBridge_SetMainThread(void *);
|
||||
extern jclass GetGeckoAppShellClass();
|
||||
|
@ -437,6 +437,11 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
||||
break;
|
||||
}
|
||||
|
||||
case SAVE_STATE: {
|
||||
ReadCharactersField(jenv);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -498,6 +498,7 @@ public:
|
||||
GECKO_EVENT_SYNC = 15,
|
||||
FORCED_RESIZE = 16,
|
||||
ACTIVITY_START = 17,
|
||||
SAVE_STATE = 18,
|
||||
dummy_java_enum_list_end
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = widget
|
||||
LIBRARY_NAME = widget_android
|
||||
XPIDL_MODULE = widget
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsWidgetAndroidModule
|
||||
@ -79,6 +80,10 @@ NOT_THERE_YET_CPPSRCS = \
|
||||
nsSound.cpp \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIAndroidBridge.idl \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
|
||||
|
||||
EXPORTS = AndroidBridge.h AndroidJavaWrappers.h
|
||||
|
@ -374,6 +374,9 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
if (!cmdline)
|
||||
break;
|
||||
|
||||
if (curEvent->Characters().Length() == 0)
|
||||
break;
|
||||
|
||||
char *uri = ToNewUTF8String(curEvent->Characters());
|
||||
if (!uri)
|
||||
break;
|
||||
|
7
widget/src/android/nsIAndroidBridge.idl
Normal file
7
widget/src/android/nsIAndroidBridge.idl
Normal file
@ -0,0 +1,7 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(32c345d4-9f45-446a-8a93-8939f3453e87)]
|
||||
interface nsIAndroidBridge : nsISupports
|
||||
{
|
||||
void handleGeckoMessage(in AString message);
|
||||
};
|
@ -60,6 +60,7 @@
|
||||
#include "nsIMEPicker.h"
|
||||
#include "nsFilePickerProxy.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
|
||||
@ -74,6 +75,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecAndroid)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIMEPicker)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidBridge)
|
||||
|
||||
#include "GfxInfo.h"
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
@ -116,6 +119,7 @@ NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_IMEPICKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ANDROIDBRIDGE_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_WINDOW_CID, false, NULL, nsWindowConstructor },
|
||||
@ -133,6 +137,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_FILEPICKER_CID, false, NULL, nsFilePickerConstructor },
|
||||
{ &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor },
|
||||
{ &kNS_IMEPICKER_CID, false, NULL, nsIMEPickerConstructor },
|
||||
{ &kNS_ANDROIDBRIDGE_CID, false, NULL, nsAndroidBridgeConstructor },
|
||||
{ &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
@ -153,6 +158,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID },
|
||||
{ "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
|
||||
{ "@mozilla.org/imepicker;1", &kNS_IMEPICKER_CID },
|
||||
{ "@mozilla.org/android/bridge;1", &kNS_ANDROIDBRIDGE_CID },
|
||||
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -74,6 +74,8 @@ using mozilla::unused;
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
#include "imgIEncoder.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
|
||||
@ -725,6 +727,65 @@ nsWindow::GetThebesSurface()
|
||||
return new gfxImageSurface(gfxIntSize(5,5), gfxImageSurface::ImageFormatRGB24);
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindow::DrawToFile(const nsAString &path)
|
||||
{
|
||||
if (!IsTopLevel() || !mIsVisible) {
|
||||
ALOG("### DrawToFile works only for a visible toplevel window!");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (GetLayerManager(nsnull)->GetBackendType() != LayerManager::LAYERS_BASIC) {
|
||||
ALOG("### DrawToFile works only for a basic layers!");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface =
|
||||
new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
|
||||
if (imgSurface->CairoStatus()) {
|
||||
ALOG("### Failed to create a valid surface");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
bool result = DrawTo(imgSurface);
|
||||
NS_ENSURE_TRUE(result, PR_FALSE);
|
||||
|
||||
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/png");
|
||||
NS_ENSURE_TRUE(encoder, PR_FALSE);
|
||||
|
||||
encoder->InitFromData(imgSurface->Data(),
|
||||
imgSurface->Stride() * mBounds.height,
|
||||
mBounds.width,
|
||||
mBounds.height,
|
||||
imgSurface->Stride(),
|
||||
imgIEncoder::INPUT_FORMAT_HOSTARGB,
|
||||
EmptyString());
|
||||
|
||||
nsCOMPtr<nsILocalFile> file;
|
||||
NS_NewLocalFile(path, true, getter_AddRefs(file));
|
||||
NS_ENSURE_TRUE(file, PR_FALSE);
|
||||
|
||||
PRUint32 length;
|
||||
encoder->Available(&length);
|
||||
|
||||
nsCOMPtr<nsIOutputStream> outputStream;
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), file);
|
||||
NS_ENSURE_TRUE(outputStream, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
|
||||
NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
|
||||
outputStream, length);
|
||||
NS_ENSURE_TRUE(bufferedOutputStream, PR_FALSE);
|
||||
|
||||
PRUint32 numWritten;
|
||||
bufferedOutputStream->WriteFrom(encoder, length, &numWritten);
|
||||
NS_ENSURE_SUCCESS(length == numWritten, PR_FALSE);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
@ -877,6 +938,10 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
||||
AndroidBridge::Bridge()->AcknowledgeEventSync();
|
||||
break;
|
||||
|
||||
case AndroidGeckoEvent::SAVE_STATE:
|
||||
win->DrawToFile(ae->Characters());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1016,8 +1081,6 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
||||
|
||||
NS_ASSERTION(!sview.isNull(), "SurfaceView is null!");
|
||||
|
||||
AndroidBridge::Bridge()->HideProgressDialogOnce();
|
||||
|
||||
if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_BASIC) {
|
||||
if (sNativeWindow) {
|
||||
unsigned char *bits;
|
||||
|
@ -174,6 +174,7 @@ protected:
|
||||
void BringToFront();
|
||||
nsWindow *FindTopLevel();
|
||||
bool DrawTo(gfxASurface *targetSurface);
|
||||
bool DrawToFile(const nsAString &path);
|
||||
bool IsTopLevel();
|
||||
void OnIMEAddRange(mozilla::AndroidGeckoEvent *ae);
|
||||
|
||||
|
@ -53,6 +53,10 @@
|
||||
#include "nsConsoleMessage.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsConsoleService)
|
||||
@ -189,6 +193,12 @@ nsConsoleService::LogMessage(nsIConsoleMessage *message)
|
||||
NS_IMETHODIMP
|
||||
nsConsoleService::LogStringMessage(const PRUnichar *message)
|
||||
{
|
||||
#if defined(ANDROID)
|
||||
__android_log_print(ANDROID_LOG_ERROR, "nsConsoleService",
|
||||
"%s",
|
||||
NS_LossyConvertUTF16toASCII(message).get());
|
||||
#endif
|
||||
|
||||
nsConsoleMessage *msg = new nsConsoleMessage(message);
|
||||
return this->LogMessage(msg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user