Permalink
Browse files

Merge remote-tracking branch 'upstream/master'

  • Loading branch information...
2 parents 6ccdaa4 + f2066a9 commit 197181d658230de71178936ffd7576a1e4b27189 @mykmelez mykmelez committed Apr 19, 2012
Showing with 809 additions and 455 deletions.
  1. +3 −0 accessible/src/mac/mozAccessible.h
  2. +17 −7 accessible/src/mac/mozAccessible.mm
  3. +46 −6 browser/components/migration/tests/unit/head_migration.js
  4. +45 −16 browser/components/migration/tests/unit/test_IE_bookmarks.js
  5. +1 −1 browser/components/migration/tests/unit/xpcshell.ini
  6. +11 −6 browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
  7. +16 −6 build/mobile/sutagent/android/DoCommand.java
  8. +5 −0 build/mobile/sutagent/android/RedirOutputThread.java
  9. +13 −3 build/mobile/sutagent/android/watcher/WatcherService.java
  10. +15 −53 configure.in
  11. +1 −21 content/events/src/nsEventStateManager.cpp
  12. +0 −1 content/events/test/Makefile.in
  13. +0 −139 content/events/test/test_focus_disabled.html
  14. +3 −0 dom/locales/en-US/chrome/accessibility/mac/accessible.properties
  15. +3 −1 gfx/thebes/Makefile.in
  16. +0 −1 gfx/thebes/gfxASurface.h
  17. +71 −0 gfx/thebes/gfxReusableSurfaceWrapper.cpp
  18. +68 −0 gfx/thebes/gfxReusableSurfaceWrapper.h
  19. +4 −2 gfx/thebes/gfxUtils.cpp
  20. +3 −1 gfx/thebes/gfxUtils.h
  21. +8 −2 image/public/imgIContainer.idl
  22. +1 −1 image/src/RasterImage.cpp
  23. +5 −3 image/src/imgFrame.cpp
  24. +3 −1 image/src/imgFrame.h
  25. +1 −3 js/src/jsgc.h
  26. +23 −21 js/src/jsgcmark.cpp
  27. +21 −14 layout/base/nsDisplayList.cpp
  28. +60 −21 layout/base/nsDisplayList.h
  29. +3 −0 layout/base/nsLayoutUtils.cpp
  30. +8 −16 layout/generic/nsFrame.cpp
  31. +0 −5 layout/generic/nsIFrame.h
  32. +1 −0 layout/style/forms.css
  33. +5 −0 layout/style/nsStyleStruct.h
  34. +3 −2 layout/tables/nsTableCellFrame.cpp
  35. +1 −1 layout/tables/nsTableFrame.cpp
  36. +1 −1 layout/xul/base/src/nsBoxFrame.cpp
  37. +37 −13 mobile/android/base/GeckoApp.java
  38. +4 −0 mobile/android/base/Makefile.in
  39. +247 −20 mobile/android/base/ProfileMigrator.java
  40. +1 −1 mobile/android/base/db/BrowserProvider.java.in
  41. +1 −4 mobile/android/base/gfx/GeckoLayerClient.java
  42. +39 −47 mobile/android/base/gfx/LayerRenderer.java
  43. BIN mobile/android/base/resources/drawable-hdpi/validation_arrow.png
  44. BIN mobile/android/base/resources/drawable-hdpi/validation_bg.9.png
  45. BIN mobile/android/base/resources/drawable-xhdpi-v11/validation_arrow.png
  46. BIN mobile/android/base/resources/drawable-xhdpi-v11/validation_bg.9.png
  47. BIN mobile/android/base/resources/drawable/validation_arrow.png
  48. BIN mobile/android/base/resources/drawable/validation_bg.9.png
  49. +4 −4 mobile/android/base/resources/layout/validation_message.xml
  50. +4 −11 mobile/android/base/sync/repositories/android/PasswordsRepositorySession.java
  51. +3 −0 mobile/android/chrome/content/browser.js
View
3 accessible/src/mac/mozAccessible.h
@@ -109,6 +109,9 @@ GetObjectOrRepresentedView(id <mozAccessible> aObject)
// the role might be "textfield", while the subrole is "password textfield".
- (NSString*)subrole;
+// Return the role description, as there are a few exceptions.
+- (NSString*)roleDescription;
+
// returns the native window we're inside.
- (NSWindow*)window;
View
24 accessible/src/mac/mozAccessible.mm
@@ -225,13 +225,8 @@ - (id)accessibilityAttributeValue:(NSString*)attribute
return [NSNumber numberWithBool:[self isEnabled]];
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return [self value];
- if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
- if (mRole == roles::DOCUMENT)
- return utils::LocalizedString(NS_LITERAL_STRING("htmlContent"));
-
- return NSAccessibilityRoleDescription([self role], [self subrole]);
- }
-
+ if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
+ return [self roleDescription];
if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute])
return [self customDescription];
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
@@ -510,6 +505,21 @@ - (NSString*)subrole
return nil;
}
+- (NSString*)roleDescription
+{
+ if (mRole == roles::DOCUMENT)
+ return utils::LocalizedString(NS_LITERAL_STRING("htmlContent"));
+
+ NSString* subrole = [self subrole];
+
+ if ((mRole == roles::LISTITEM) && [subrole isEqualToString:@"AXTerm"])
+ return utils::LocalizedString(NS_LITERAL_STRING("term"));
+ if ((mRole == roles::PARAGRAPH) && [subrole isEqualToString:@"AXDefinition"])
+ return utils::LocalizedString(NS_LITERAL_STRING("definition"));
+
+ return NSAccessibilityRoleDescription([self role], subrole);
+}
+
- (NSString*)title
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
View
52 browser/components/migration/tests/unit/head_migration.js
@@ -5,20 +5,60 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
-
-const IMIGRATOR = Ci.nsIBrowserProfileMigrator;
+const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
-
+XPCOMUtils.defineLazyModuleGetter(this, "MigrationUtils",
+ "resource:///modules/MigrationUtils.jsm");
// Initialize profile.
let gProfD = do_get_profile();
-function newMigratorFor(aKey) {
- let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
- return Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
+// Create a fake XULAppInfo to satisfy the eventual needs of the migrators.
+let (XULAppInfo = {
+ // nsIXUlAppInfo
+ get vendor() "Mozilla",
+ get name() "XPCShell",
+ get ID() "xpcshell@tests.mozilla.org",
+ get version() "1",
+ get appBuildID() "2007010101",
+ get platformVersion() "1.0",
+ get platformBuildID() "2007010101",
+
+ // nsIXUlRuntime (partial)
+ get inSafeMode() false,
+ logConsoleErrors: true,
+ get OS() "XPCShell",
+ get XPCOMABI() "noarch-spidermonkey",
+ invalidateCachesOnRestart: function () {},
+
+ // nsIWinAppHelper
+ get userCanElevate() false,
+
+ QueryInterface: function (aIID) {
+ let interfaces = [Ci.nsIXULAppInfo, Ci.nsIXULRuntime];
+ if ("nsIWinAppHelper" in Ci)
+ interfaces.push(Ci.nsIWinAppHelper);
+ if (!interfaces.some(function (v) aIID.equals(v)))
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+}) {
+ const CONTRACT_ID = "@mozilla.org/xre/app-info;1";
+ const CID = Components.ID("7685dac8-3637-4660-a544-928c5ec0e714}");
+
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(CID, "XULAppInfo", CONTRACT_ID, {
+ createInstance: function (aOuter, aIID) {
+ if (aOuter != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return XULAppInfo.QueryInterface(aIID);
+ },
+ QueryInterface: XPCOMUtils.generateQI(Ci.nsIFactory)
+ });
}
View
61 browser/components/migration/tests/unit/test_IE_bookmarks.js
@@ -3,26 +3,55 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
function run_test() {
- let migrator = newMigratorFor("ie");
+ do_test_pending();
+
+ let migrator = MigrationUtils.getMigrator("ie");
// Sanity check for the source.
do_check_true(migrator.sourceExists);
// Ensure bookmarks migration is available.
let availableSources = migrator.getMigrateData("FieldOfFlowers", false);
- do_check_true((availableSources & IMIGRATOR.BOOKMARKS) > 0);
-
- // Needed to enforce bookmarks replacing.
- let startup = {
- doStartup: function () {},
- get directory() do_get_profile()
- }
- migrator.migrate(IMIGRATOR.BOOKMARKS, startup, "FieldOfFlowers");
-
- // Check that at least two bookmark have been added to the menu and the
- // toolbar. The first one comes from bookmarks.html, the others from IE.
- do_check_true(PlacesUtils.bookmarks
- .getIdForItemAt(PlacesUtils.bookmarksMenuFolderId, 1) > 0);
- do_check_true(PlacesUtils.bookmarks
- .getIdForItemAt(PlacesUtils.toolbarFolderId, 1) > 0);
+ do_check_true((availableSources & MigrationUtils.resourceTypes.BOOKMARKS) > 0);
+
+ // Wait for the imported bookmarks. Check that "From Internet Explorer"
+ // folders are created in the menu and on the toolbar.
+ let source = MigrationUtils.getLocalizedString("sourceNameIE");
+ let label = MigrationUtils.getLocalizedString("importedBookmarksFolder", [source]);
+
+ let expectedParents = [ PlacesUtils.bookmarksMenuFolderId,
+ PlacesUtils.toolbarFolderId ];
+
+ PlacesUtils.bookmarks.addObserver({
+ onItemAdded: function onItemAdded(aItemId, aParentId, aIndex, aItemType,
+ aURI, aTitle) {
+ if (aTitle == label) {
+ let index = expectedParents.indexOf(aParentId);
+ do_check_neq(index, -1);
+ expectedParents.splice(index, 1);
+ if (expectedParents.length == 0)
+ PlacesUtils.bookmarks.removeObserver(this);
+ }
+ },
+ onBeginUpdateBatch: function () {},
+ onEndUpdateBatch: function () {},
+ onBeforeItemRemoved: function () {},
+ onItemRemoved: function () {},
+ onItemChanged: function () {},
+ onItemVisited: function () {},
+ onItemMoved: function () {},
+ }, false);
+
+ // Wait for migration.
+ Services.obs.addObserver(function onMigrationEnded() {
+ Services.obs.removeObserver(onMigrationEnded, "Migration:Ended");
+
+ // Check the bookmarks have been imported to all the expected parents.
+ do_check_eq(expectedParents.length, 0);
+
+ do_test_finished();
+ }, "Migration:Ended", false);
+
+ migrator.migrate(MigrationUtils.resourceTypes.BOOKMARKS, null,
+ "FieldOfFlowers");
}
View
2 browser/components/migration/tests/unit/xpcshell.ini
@@ -3,4 +3,4 @@ head = head_migration.js
tail =
[test_IE_bookmarks.js]
-skip-if = true
+skip-if = os != "win"
View
17 browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -70,13 +70,18 @@ function autocompletePopupHidden()
is(completeNode.value, testStr + "dy", "completeNode is empty");
jsterm.setInputValue("");
- // Check the property panel as well.
+ // Check the property panel as well. It's a bit gross to parse the properties
+ // out of the treeView cell text, but nsITreeView doesn't give us a good
+ // structured way to get at the data. :-(
let propPanel = jsterm.openPropertyPanel("Test", content.document);
- let docProps = 0;
- for (let prop in content.document) {
- docProps++;
- }
- is (propPanel.treeView.rowCount, docProps, "all document properties shown in propertyPanel");
+ let propPanelProps = [];
+ for (let idx = 0; idx < propPanel.treeView.rowCount; ++idx)
+ propPanelProps.push(propPanel.treeView.getCellText(idx, null).split(':')[0]);
+ // NB: We pull the properties off the prototype, rather than off object itself,
+ // so that expandos like |constructor|, which the propPanel can't see, are not
+ // included.
+ for (let prop in Object.getPrototypeOf(content.document))
+ ok(propPanelProps.indexOf(prop) != -1, "Property |" + prop + "| should be reflected in propertyPanel");
let treeRows = propPanel.treeView._rows;
is (treeRows[30].display, "body: Object", "found document.body");
View
22 build/mobile/sutagent/android/DoCommand.java
@@ -1531,7 +1531,7 @@ public String HashFile(String fileName)
}
catch (FileNotFoundException e) {
sRet += " file not found";
- e.printStackTrace();
+ Log.d("SUT", "HashFile: "+e);
}
catch (IOException e) {
sRet += " io exception";
@@ -2388,8 +2388,12 @@ public String KillProcess(String sProcName, OutputStream out)
int lcv = 0;
String strProcName = "";
int nPID = 0;
+ int nProcs = 0;
+
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
- for (lcv = 0; lcv < lProcesses.size(); lcv++)
+ for (lcv = 0; lcv < nProcs; lcv++)
{
if (lProcesses.get(lcv).processName.contains(sProcName))
{
@@ -2441,7 +2445,10 @@ public String KillProcess(String sProcName, OutputStream out)
{
sRet = "Successfully killed " + nPID + " " + strProcName + "\n";
lProcesses = aMgr.getRunningAppProcesses();
- for (lcv = 0; lcv < lProcesses.size(); lcv++)
+ nProcs = 0;
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
+ for (lcv = 0; lcv < nProcs; lcv++)
{
if (lProcesses.get(lcv).processName.contains(sProcName))
{
@@ -2524,12 +2531,15 @@ public String GetProcessInfo()
String sRet = "";
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
- int nProcs = lProcesses.size();
+ int nProcs = 0;
int lcv = 0;
String strProcName = "";
int nPID = 0;
int nUser = 0;
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
+
for (lcv = 0; lcv < nProcs; lcv++)
{
strProcName = lProcesses.get(lcv).processName;
@@ -3508,7 +3518,7 @@ public String StartPrg(String [] progArray, OutputStream out)
}
catch (IllegalThreadStateException itse) {
lcv++;
- itse.printStackTrace();
+ Log.d("SUT", "StartPrg waited 10s for "+progArray[0]);
}
}
}
@@ -3639,7 +3649,7 @@ public String StartPrg2(String [] progArray, OutputStream out, String cwd)
}
catch (IllegalThreadStateException itse) {
lcv++;
- itse.printStackTrace();
+ Log.d("SUT", "StartPrg2 waited 10s for "+theArgs[0]);
}
}
}
View
5 build/mobile/sutagent/android/RedirOutputThread.java
@@ -137,6 +137,11 @@ public void run()
{
e.printStackTrace();
}
+ catch (java.lang.IllegalArgumentException e)
+ {
+ // Bug 743766: InputStream.available() unexpectedly throws this sometimes
+ e.printStackTrace();
+ }
}
pProc.destroy();
View
16 build/mobile/sutagent/android/watcher/WatcherService.java
@@ -495,10 +495,13 @@ public boolean GetProcessInfo(String sProcName)
boolean bRet = false;
ActivityManager aMgr = (ActivityManager) getApplicationContext().getSystemService(Activity.ACTIVITY_SERVICE);
List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
- int nProcs = lProcesses.size();
+ int nProcs = 0;
int lcv = 0;
String strProcName = "";
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
+
for (lcv = 0; lcv < nProcs; lcv++)
{
strProcName = lProcesses.get(lcv).processName;
@@ -554,8 +557,12 @@ public String KillProcess(String sProcName, OutputStream out)
int lcv = 0;
String strProcName = "";
int nPID = 0;
+ int nProcs = 0;
+
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
- for (lcv = 0; lcv < lProcesses.size(); lcv++)
+ for (lcv = 0; lcv < nProcs; lcv++)
{
if (lProcesses.get(lcv).processName.contains(sProcName))
{
@@ -598,7 +605,10 @@ public String KillProcess(String sProcName, OutputStream out)
{
sRet = "Successfully killed " + nPID + " " + strProcName + "\n";
lProcesses = aMgr.getRunningAppProcesses();
- for (lcv = 0; lcv < lProcesses.size(); lcv++)
+ nProcs = 0;
+ if (lProcesses != null)
+ nProcs = lProcesses.size();
+ for (lcv = 0; lcv < nProcs; lcv++)
{
if (lProcesses.get(lcv).processName.contains(sProcName))
{
View
68 configure.in
@@ -5591,12 +5591,10 @@ MOZ_ARG_DISABLE_BOOL(webm,
dnl system libvpx Support
dnl ========================================================
-MOZ_ARG_WITH_STRING(system-libvpx,
-[ --with-system-libvpx=[PFX]
- Use system libvpx [installed at prefix PFX]],
- LIBVPX_DIR=$withval)
+MOZ_ARG_WITH_BOOL(system-libvpx,
+[ --with-system-libvpx Use system libvpx (located with pkgconfig)],
+ MOZ_NATIVE_LIBVPX=1)
-MOZ_NATIVE_LIBVPX=
MOZ_LIBVPX_INCLUDES=
MOZ_LIBVPX_LIBS=
@@ -5609,54 +5607,18 @@ if test -n "$MOZ_WEBM"; then
AC_DEFINE(MOZ_VP8_ENCODER)
fi
- if test -n "$LIBVPX_DIR" -a "$LIBVPX_DIR" != no; then
- _SAVE_CFLAGS=$CFLAGS
- _SAVE_LDFLAGS=$LDFLAGS
- _SAVE_LIBS=$LIBS
- if test "${LIBVPX_DIR}" = "yes"; then
- LIBVPX_DIR=/usr
- fi
- CFLAGS="-I${LIBVPX_DIR}/include $CFLAGS"
- LDFLAGS="-L${LIBVPX_DIR}/lib $LDFLAGS"
- MOZ_NATIVE_LIBVPX_DEC_TEST=
- MOZ_CHECK_HEADER(vpx/vpx_decoder.h,
- [if test ! -f "${LIBVPX_DIR}/include/vpx/vpx_decoder.h"; then
- AC_MSG_ERROR([vpx/vpx_decoder.h found, but is not in ${LIBVPX_DIR}/include])
- fi],
- AC_MSG_ERROR([--with-system-libvpx requested but vpx/vpx_decoder.h not found]))
- AC_CHECK_LIB(vpx, vpx_codec_dec_init_ver,
- [MOZ_NATIVE_LIBVPX_DEC_TEST=1],
- ([--with-system-libvpx requested but symbol vpx_codec_dec_init_ver not found]))
- if test -n "$MOZ_NATIVE_LIBVPX_DEC_TEST" ; then
- AC_MSG_CHECKING([for libvpx version >= v1.0.0])
- dnl We need at least v1.0.0 to fix several crash bugs (for which we
- dnl had local patches prior to v1.0.0).
- dnl
- dnl This is a terrible test for the library version, but we don't
- dnl have a good one. There is no version number in a public header,
- dnl and testing the headers still doesn't guarantee we link against
- dnl the right version. While we could call vpx_codec_version() at
- dnl run-time, that would break cross-compiling. There are no
- dnl additional exported decoder symbols between the v1.0.0 release
- dnl and the v0.9.7 one to check for.
- AC_TRY_COMPILE([
- #include <vpx/vpx_decoder.h>
- #if !defined(VPX_CODEC_USE_INPUT_FRAGMENTS)
- #error "test failed."
- #endif
- ],
- [return 0;],
- [AC_MSG_RESULT([yes])
- MOZ_NATIVE_LIBVPX=1
- AC_DEFINE(MOZ_NATIVE_LIBVPX)
- MOZ_LIBVPX_INCLUDES="-I${LIBVPX_DIR}/include"
- MOZ_LIBVPX_LIBS="-L${LIBVPX_DIR}/lib -lvpx"],
- [AC_MSG_RESULT([no])
- AC_MSG_ERROR([--with-system-libvpx requested but it is not v1.0.0 or later])])
- fi
- CFLAGS=$_SAVE_CFLAGS
- LDFLAGS=$_SAVE_LDFLAGS
- LIBS=$_SAVE_LIBS
+ if test -n "$MOZ_NATIVE_LIBVPX"; then
+ dnl ============================
+ dnl === libvpx Version check ===
+ dnl ============================
+ dnl Check to see if we have a system libvpx package.
+ PKG_CHECK_MODULES(LIBVPX, vpx >= 1.0.0)
+
+ MOZ_CHECK_HEADER([vpx/vpx_decoder.h], [],
+ [AC_MSG_ERROR([Couldn't find vpx/vpx_decoder.h which is required for build with system libvpx. Use --without-system-libvpx to build with in-tree libvpx.])])
+
+ AC_CHECK_LIB(vpx, vpx_codec_dec_init_ver, [],
+ [AC_MSG_ERROR([--with-system-libvpx requested but symbol vpx_codec_dec_init_ver not found])])
fi
fi
View
22 content/events/src/nsEventStateManager.cpp
@@ -3066,28 +3066,8 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
if (mCurrentTarget) {
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(newFocus));
const nsStyleUserInterface* ui = mCurrentTarget->GetStyleUserInterface();
- activeContent = mCurrentTarget->GetContent();
-
- // In some cases, we do not want to even blur the current focused
- // element. Those cases are:
- // 1. -moz-user-focus CSS property is set to 'ignore';
- // 2. HTML element has :disabled pseudo-class applying;
- // 3. XUL control element has the disabled attribute set to 'true.
suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE);
-
- if (!suppressBlur) {
- nsCOMPtr<Element> element = do_QueryInterface(aEvent->target);
- suppressBlur = element && element->State().HasState(NS_EVENT_STATE_DISABLED);
- }
-
- if (!suppressBlur) {
- nsCOMPtr<nsIDOMXULControlElement> xulControl = do_QueryInterface(aEvent->target);
- if (xulControl) {
- bool disabled;
- xulControl->GetDisabled(&disabled);
- suppressBlur = disabled;
- }
- }
+ activeContent = mCurrentTarget->GetContent();
}
nsIFrame* currFrame = mCurrentTarget;
View
1 content/events/test/Makefile.in
@@ -115,7 +115,6 @@ _TEST_FILES = \
test_eventctors.html \
test_bug635465.html \
test_bug741666.html \
- test_focus_disabled.html \
$(NULL)
#bug 585630
View
139 content/events/test/test_focus_disabled.html
@@ -1,139 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=375008
--->
-<head>
- <meta charset="utf-8">
- <title>Test for Bug 375008</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=375008">Mozilla Bug 375008</a>
-<p id="display"></p>
-<div id="content">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 375008 **/
-
-elementsToTest = [
- "button",
- "input",
- "fieldset",
- "select",
- "textarea",
- "optgroup",
- "option"
-];
-
-var content = document.getElementById('content');
-var input = null;
-var idx = 0;
-var element = null;
-
-const ELEMENT_DISABLED_PHASE = 1;
-const ELEMENT_ENABLED_PHASE = 2;
-var testPhase = ELEMENT_DISABLED_PHASE;
-
-function checkEndOfPhase() {
- if (idx == elementsToTest.length) {
- if (testPhase == ELEMENT_ENABLED_PHASE) {
- SimpleTest.finish();
- return;
- }
-
- idx = 0;
- testPhase = ELEMENT_ENABLED_PHASE;
- }
-}
-
-function init() {
- // Here, we create the following DOM inside $(content):
- // <input><element tabindex='1'>
- // There is one round of tests with disabled=true and another with false.
-
- input = document.createElement('input');
- content.appendChild(input);
-
- element = document.createElement(elementsToTest[idx]);
- element.disabled = (testPhase == ELEMENT_DISABLED_PHASE) ? true : false;
- element.tabIndex = 1;
-
- // <button> and <option> need a content to make sure they are clickable.
- if (element.tagName == "BUTTON" ||
- element.tagName == "OPTION") {
- element.innerHTML = "foo";
- }
- // <optgroup> need a content too to make sure it is clickable.
- if (element.tagName == "OPTGROUP") {
- element.appendChild(document.createElement("option"));
- element.firstChild.value = "foobar";
- }
-
- content.appendChild(element);
-
- idx++;
-}
-
-function test() {
- if (testPhase == ELEMENT_DISABLED_PHASE) {
- if (element.tagName == "OPTGROUP") {
- // TODO: doesn't work because of bug 577306.
- todo_is(document.activeElement, input, "[" + element.tagName + "] input should still be focused");
- } else {
- is(document.activeElement, input, "[" + element.tagName + "] input should still be focused");
- }
- } else {
- is(document.activeElement, element, "focus should have moved to " + element);
- }
-}
-
-function cleanup() {
- element = null;
- input = null;
- content.innerHTML = "";
-}
-
-function next() {
- // Check if we need to change phase or stop the test.
- checkEndOfPhase();
-
- // Initialise |input| and |element| and put them inside |content|.
- init();
-
- input.onfocus = function() {
- // Try to focus the element and then check if it has been actually focused.
- // After that, we blur the focused element and we remove all elements from
- // $(content) and we go for the next test.
- synthesizeMouseAtCenter(element, {});
-
- test();
-
- if (document.activeElement != input && document.activeElement != element) {
- cleanup();
- next();
- return;
- }
-
- document.activeElement.onblur = function() {
- cleanup();
- next();
- };
-
- document.activeElement.blur();
- };
-
- input.focus();
-}
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.waitForFocus(next);
-
-</script>
-</pre>
-</body>
-</html>
View
3 dom/locales/en-US/chrome/accessibility/mac/accessible.properties
@@ -18,3 +18,6 @@ cycle = Cycle
htmlContent = HTML Content
# The Role Description for the Tab button.
tab = tab
+# The Role Description for definition list dl, dt and dd
+term = term
+definition = definition
View
4 gfx/thebes/Makefile.in
@@ -46,7 +46,7 @@ LIBXUL_LIBRARY = 1
EXPORT_LIBRARY = 1
EXPORTS = \
- gfx2DGlue.h \
+ gfx2DGlue.h \
gfx3DMatrix.h \
gfxASurface.h \
gfxAlphaRecovery.h \
@@ -80,6 +80,7 @@ EXPORTS = \
nsCoreAnimationSupport.h \
nsIOSurface.h \
gfxSharedImageSurface.h \
+ gfxReusableSurfaceWrapper.h \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
@@ -202,6 +203,7 @@ CPPSRCS = \
gfxScriptItemizer.cpp \
gfxHarfBuzzShaper.cpp \
gfxSharedImageSurface.cpp \
+ gfxReusableSurfaceWrapper.cpp \
$(NULL)
ifdef MOZ_GRAPHITE
View
1 gfx/thebes/gfxASurface.h
@@ -44,7 +44,6 @@
#include "nsAutoRef.h"
#include "nsThreadUtils.h"
-
typedef struct _cairo_surface cairo_surface_t;
typedef struct _cairo_user_data_key cairo_user_data_key_t;
View
71 gfx/thebes/gfxReusableSurfaceWrapper.cpp
@@ -0,0 +1,71 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gfxReusableSurfaceWrapper.h"
+#include "gfxImageSurface.h"
+#include "pratom.h"
+
+gfxReusableSurfaceWrapper::gfxReusableSurfaceWrapper(gfxImageSurface* aSurface)
+ : mSurface(aSurface)
+ , mSurfaceData(aSurface->Data())
+ , mReadCount(0)
+{
+ MOZ_COUNT_CTOR(gfxReusableSurfaceWrapper);
+}
+
+gfxReusableSurfaceWrapper::~gfxReusableSurfaceWrapper()
+{
+ NS_ABORT_IF_FALSE(mReadCount == 0, "Should not be locked when released");
+ MOZ_COUNT_DTOR(gfxReusableSurfaceWrapper);
+ if (!NS_IsMainThread()) {
+ class DeleteImageOnMainThread : public nsRunnable {
+ public:
+ DeleteImageOnMainThread(gfxImageSurface *aImage)
+ : mImage(aImage)
+ {}
+
+ NS_IMETHOD Run()
+ {
+ return NS_OK;
+ }
+ private:
+ nsRefPtr<gfxImageSurface> mImage;
+ };
+ NS_DispatchToMainThread(new DeleteImageOnMainThread(mSurface));
+ }
+}
+
+void
+gfxReusableSurfaceWrapper::ReadLock()
+{
+ NS_CheckThreadSafe(_mOwningThread.GetThread(), "Only the owner thread can call ReadOnlyLock");
+ PR_ATOMIC_INCREMENT(&mReadCount);
+}
+
+void
+gfxReusableSurfaceWrapper::ReadUnlock()
+{
+ PR_ATOMIC_DECREMENT(&mReadCount);
+}
+
+gfxReusableSurfaceWrapper*
+gfxReusableSurfaceWrapper::GetWritable(gfxImageSurface** aSurface)
+{
+ NS_CheckThreadSafe(_mOwningThread.GetThread(), "Only the owner thread can call GetWritable");
+
+ if (mReadCount == 0) {
+ *aSurface = mSurface;
+ return this;
+ }
+
+ // Something else is reading the surface, copy it
+ gfxImageSurface* copySurface = new gfxImageSurface(mSurface->GetSize(), mSurface->Format());
+ copySurface->CopyFrom(mSurface);
+ *aSurface = copySurface;
+
+ // We need to create a new wrapper since this wrapper has a read only lock.
+ gfxReusableSurfaceWrapper* wrapper = new gfxReusableSurfaceWrapper(copySurface);
+ return wrapper;
+}
+
View
68 gfx/thebes/gfxReusableSurfaceWrapper.h
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GFXCOWSURFACEWRAPPER
+#define GFXCOWSURFACEWRAPPER
+
+#include "nsISupportsImpl.h"
+#include "nsAutoPtr.h"
+
+class gfxImageSurface;
+
+/**
+ * Provides a cross thread wrapper for a gfxImageSurface
+ * that has copy-on-write schemantics.
+ *
+ * Only the owner thread can write to the surface and aquire
+ * read locks.
+ *
+ * OMTC Usage:
+ * 1) Content creates a writable copy of this surface
+ * wrapper which be optimized to the same wrapper if there
+ * are no readers.
+ * 2) The surface is sent from content to the compositor once
+ * or potentially many time, each increasing a read lock.
+ * 3) When the compositor has processed the surface and uploaded
+ * the content it then releases the read lock.
+ */
+class gfxReusableSurfaceWrapper {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxReusableSurfaceWrapper);
+public:
+ /**
+ * Pass the gfxASurface to the wrapper.
+ * The wrapper should hold the only strong reference
+ * to the surface and its memebers.
+ */
+ gfxReusableSurfaceWrapper(gfxImageSurface* aSurface);
+
+ ~gfxReusableSurfaceWrapper();
+
+ const unsigned char* GetReadOnlyData() const {
+ NS_ABORT_IF_FALSE(mReadCount > 0, "Should have read lock");
+ return mSurfaceData;
+ }
+
+ /**
+ * Get a writable copy of the image.
+ * If necessary this will copy the wrapper. If there are no contention
+ * the same wrapper will be returned.
+ */
+ gfxReusableSurfaceWrapper* GetWritable(gfxImageSurface** aSurface);
+
+ /**
+ * A read only lock count is recorded, any attempts to
+ * call GetWritable() while this count is positive will
+ * create a new surface/wrapper pair.
+ */
+ void ReadLock();
+ void ReadUnlock();
+
+private:
+ NS_DECL_OWNINGTHREAD
+ nsRefPtr<gfxImageSurface> mSurface;
+ const unsigned char* mSurfaceData;
+ PRInt32 mReadCount;
+};
+
+#endif // GFXCOWSURFACEWRAPPER
View
6 gfx/thebes/gfxUtils.cpp
@@ -421,9 +421,11 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
const gfxRect& aImageRect,
const gfxRect& aFill,
const gfxImageSurface::gfxImageFormat aFormat,
- const gfxPattern::GraphicsFilter& aFilter)
+ const gfxPattern::GraphicsFilter& aFilter,
+ PRUint32 aImageFlags)
{
- bool doTile = !aImageRect.Contains(aSourceRect);
+ bool doTile = !aImageRect.Contains(aSourceRect) &&
+ !(aImageFlags & imgIContainer::FLAG_CLAMP);
nsRefPtr<gfxASurface> currentTarget = aContext->CurrentSurface();
gfxMatrix deviceSpaceToImageSpace =
View
4 gfx/thebes/gfxUtils.h
@@ -43,6 +43,7 @@
#include "gfxImageSurface.h"
#include "ImageLayers.h"
#include "mozilla/gfx/2D.h"
+#include "imgIContainer.h"
class gfxDrawable;
class nsIntRegion;
@@ -89,7 +90,8 @@ class THEBES_API gfxUtils {
const gfxRect& aImageRect,
const gfxRect& aFill,
const gfxImageSurface::gfxImageFormat aFormat,
- const gfxPattern::GraphicsFilter& aFilter);
+ const gfxPattern::GraphicsFilter& aFilter,
+ PRUint32 aImageFlags = imgIContainer::FLAG_NONE);
/**
* Clip aContext to the region aRegion.
View
10 image/public/imgIContainer.idl
@@ -93,7 +93,7 @@ native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
*
* Internally, imgIContainer also manages animation of images.
*/
-[scriptable, uuid(8bf87433-be67-413b-9497-00071c5002bd)]
+[scriptable, uuid(ead94080-cfd6-4a3e-8353-bd45333061d2)]
interface imgIContainer : nsISupports
{
/**
@@ -156,12 +156,16 @@ interface imgIContainer : nsISupports
* FLAG_DECODE_NO_COLORSPACE_CONVERSION: Do not do any colorspace conversion;
* ignore any embedded profiles, and don't convert to any particular destination
* space.
+ *
+ * FLAG_CLAMP: Extend the image to the fill area by clamping image sample
+ * coordinates instead of by tiling. This only affects 'draw'.
*/
const long FLAG_NONE = 0x0;
const long FLAG_SYNC_DECODE = 0x1;
const long FLAG_DECODE_NO_PREMULTIPLY_ALPHA = 0x2;
const long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x4;
+ const long FLAG_CLAMP = 0x8;
/**
* Constants for specifying various "special" frames.
@@ -222,7 +226,9 @@ interface imgIContainer : nsISupports
* @param aFilter The filter to be used if we're scaling the image.
* @param aUserSpaceToImageSpace The transformation from user space (e.g.,
* appunits) to image space.
- * @param aFill The area in the context to draw pixels to. Image will be
+ * @param aFill The area in the context to draw pixels to. When aFlags includes
+ * FLAG_CLAMP, the image will be extended to this area by clampling
+ * image sample coordinates. Otherwise, the image will be
* automatically tiled as necessary.
* @param aSubimage The area of the image, in pixels, that we are allowed to
* sample from.
View
2 image/src/RasterImage.cpp
@@ -2634,7 +2634,7 @@ RasterImage::Draw(gfxContext *aContext,
mSize.width - framerect.XMost(),
mSize.height - framerect.YMost());
- frame->Draw(aContext, aFilter, aUserSpaceToImageSpace, aFill, padding, aSubimage);
+ frame->Draw(aContext, aFilter, aUserSpaceToImageSpace, aFill, padding, aSubimage, aFlags);
if (mDecoded && !mDrawStartTime.IsNull()) {
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
View
8 image/src/imgFrame.cpp
@@ -466,7 +466,8 @@ imgFrame::SurfaceForDrawing(bool aDoPadding,
void imgFrame::Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
const gfxMatrix &aUserSpaceToImageSpace, const gfxRect& aFill,
- const nsIntMargin &aPadding, const nsIntRect &aSubimage)
+ const nsIntMargin &aPadding, const nsIntRect &aSubimage,
+ PRUint32 aImageFlags)
{
SAMPLE_LABEL("image", "imgFrame::Draw");
NS_ASSERTION(!aFill.IsEmpty(), "zero dest size --- fix caller");
@@ -491,7 +492,8 @@ void imgFrame::Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
NS_ASSERTION(!sourceRect.Intersect(subimage).IsEmpty(),
"We must be allowed to sample *some* source pixels!");
- bool doTile = !imageRect.Contains(sourceRect);
+ bool doTile = !imageRect.Contains(sourceRect) &&
+ !(aImageFlags & imgIContainer::FLAG_CLAMP);
SurfaceWithFormat surfaceResult =
SurfaceForDrawing(doPadding, doPartialDecode, doTile, aPadding,
userSpaceToImageSpace, fill, subimage, sourceRect,
@@ -501,7 +503,7 @@ void imgFrame::Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
gfxUtils::DrawPixelSnapped(aContext, surfaceResult.mDrawable,
userSpaceToImageSpace,
subimage, sourceRect, imageRect, fill,
- surfaceResult.mFormat, aFilter);
+ surfaceResult.mFormat, aFilter, aImageFlags);
}
}
View
4 image/src/imgFrame.h
@@ -54,6 +54,7 @@
#include "gfxQuartzImageSurface.h"
#endif
#include "nsAutoPtr.h"
+#include "imgIContainer.h"
class imgFrame
{
@@ -66,7 +67,8 @@ class imgFrame
void Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
const gfxMatrix &aUserSpaceToImageSpace, const gfxRect& aFill,
- const nsIntMargin &aPadding, const nsIntRect &aSubimage);
+ const nsIntMargin &aPadding, const nsIntRect &aSubimage,
+ PRUint32 aImageFlags = imgIContainer::FLAG_NONE);
nsresult Extract(const nsIntRect& aRegion, imgFrame** aResult);
View
4 js/src/jsgc.h
@@ -1860,9 +1860,6 @@ struct GCMarker : public JSTracer {
void pushValueArray(JSObject *obj, void *start, void *end) {
checkCompartment(obj);
- if (start == end)
- return;
-
JS_ASSERT(start <= end);
uintptr_t tagged = reinterpret_cast<uintptr_t>(obj) | GCMarker::ValueArrayTag;
uintptr_t startAddr = reinterpret_cast<uintptr_t>(start);
@@ -1883,6 +1880,7 @@ struct GCMarker : public JSTracer {
bool restoreValueArray(JSObject *obj, void **vpp, void **endp);
void saveValueRanges();
inline void processMarkStackTop(SliceBudget &budget);
+ void processMarkStackOther(uintptr_t tag, uintptr_t addr);
void appendGrayRoot(void *thing, JSGCTraceKind kind);
View
44 js/src/jsgcmark.cpp
@@ -918,7 +918,9 @@ GCMarker::saveValueRanges()
} else {
HeapSlot *vp = obj->fixedSlots();
unsigned nfixed = obj->numFixedSlots();
- if (arr->start >= vp && arr->start < vp + nfixed) {
+ if (arr->start == arr->end) {
+ arr->index = obj->slotSpan();
+ } else if (arr->start >= vp && arr->start < vp + nfixed) {
JS_ASSERT(arr->end == vp + Min(nfixed, obj->slotSpan()));
arr->index = arr->start - vp;
} else {
@@ -977,6 +979,25 @@ GCMarker::restoreValueArray(JSObject *obj, void **vpp, void **endp)
return true;
}
+void
+GCMarker::processMarkStackOther(uintptr_t tag, uintptr_t addr)
+{
+ if (tag == TypeTag) {
+ ScanTypeObject(this, reinterpret_cast<types::TypeObject *>(addr));
+ } else if (tag == SavedValueArrayTag) {
+ JS_ASSERT(!(addr & Cell::CellMask));
+ JSObject *obj = reinterpret_cast<JSObject *>(addr);
+ HeapValue *vp, *end;
+ if (restoreValueArray(obj, (void **)&vp, (void **)&end))
+ pushValueArray(obj, vp, end);
+ else
+ pushObject(obj);
+ } else {
+ JS_ASSERT(tag == XmlTag);
+ MarkChildren(this, reinterpret_cast<JSXML *>(addr));
+ }
+}
+
inline void
GCMarker::processMarkStackTop(SliceBudget &budget)
{
@@ -1011,31 +1032,12 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
goto scan_obj;
}
- if (tag == TypeTag) {
- ScanTypeObject(this, reinterpret_cast<types::TypeObject *>(addr));
- } else if (tag == SavedValueArrayTag) {
- JS_ASSERT(!(addr & Cell::CellMask));
- obj = reinterpret_cast<JSObject *>(addr);
- if (restoreValueArray(obj, (void **)&vp, (void **)&end))
- goto scan_value_array;
- else
- goto scan_obj;
- } else {
- JS_ASSERT(tag == XmlTag);
- MarkChildren(this, reinterpret_cast<JSXML *>(addr));
- }
- budget.step();
+ processMarkStackOther(tag, addr);
return;
scan_value_array:
JS_ASSERT(vp <= end);
while (vp != end) {
- budget.step();
- if (budget.isOverBudget()) {
- pushValueArray(obj, vp, end);
- return;
- }
-
const Value &v = *vp++;
if (v.isString()) {
JSString *str = v.toString();
View
35 layout/base/nsDisplayList.cpp
@@ -79,6 +79,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mIgnoreScrollFrame(nsnull),
mCurrentTableItem(nsnull),
mFinalTransparentRegion(nsnull),
+ mCachedOffsetFrame(aReferenceFrame),
+ mCachedOffset(0, 0),
mMode(aMode),
mBuildCaret(aBuildCaret),
mIgnoreSuppression(false),
@@ -1177,7 +1179,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
nsStyleContext* bgSC;
nsPresContext* presContext = mFrame->PresContext();
- if (!nsCSSRendering::FindBackground(mFrame->PresContext(), mFrame, &bgSC))
+ if (!nsCSSRendering::FindBackground(presContext, mFrame, &bgSC))
return result;
const nsStyleBackground* bg = bgSC->GetStyleBackground();
const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer();
@@ -1582,8 +1584,11 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
- nsIFrame* aFrame)
- : nsDisplayItem(aBuilder, aFrame) {
+ nsIFrame* aFrame, nsDisplayItem* aItem,
+ const nsPoint& aToReferenceFrame)
+ : nsDisplayItem(aBuilder, aFrame, aToReferenceFrame) {
+ mList.AppendToTop(aItem);
+ mBounds = mList.GetBounds(aBuilder);
}
nsDisplayWrapList::~nsDisplayWrapList() {
@@ -2099,7 +2104,9 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem,
const nsRect& aRect)
- : nsDisplayWrapList(aBuilder, aFrame, aItem), mClip(aRect) {
+ : nsDisplayWrapList(aBuilder, aFrame, aItem,
+ aFrame == aItem->GetUnderlyingFrame() ? aItem->ToReferenceFrame() : aBuilder->ToReferenceFrame(aFrame)),
+ mClip(aRect) {
MOZ_COUNT_CTOR(nsDisplayClip);
}
@@ -3000,7 +3007,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
- : nsDisplayWrapList(aBuilder, aFrame, aList), mEffectsFrame(aFrame),
+ : nsDisplayWrapList(aBuilder, aFrame, aList),
mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
{
MOZ_COUNT_CTOR(nsDisplaySVGEffects);
@@ -3027,8 +3034,8 @@ nsDisplaySVGEffects::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
{
nsPoint rectCenter(aRect.x + aRect.width / 2, aRect.y + aRect.height / 2);
- if (nsSVGIntegrationUtils::HitTestFrameForEffects(mEffectsFrame,
- rectCenter - aBuilder->ToReferenceFrame(mEffectsFrame))) {
+ if (nsSVGIntegrationUtils::HitTestFrameForEffects(mFrame,
+ rectCenter - ToReferenceFrame())) {
mList.HitTest(aBuilder, aRect, aState, aOutFrames);
}
}
@@ -3037,15 +3044,15 @@ void nsDisplaySVGEffects::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
nsSVGIntegrationUtils::PaintFramesWithEffects(aCtx,
- mEffectsFrame, mVisibleRect, aBuilder, &mList);
+ mFrame, mVisibleRect, aBuilder, &mList);
}
bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion) {
- nsPoint offset = aBuilder->ToReferenceFrame(mEffectsFrame);
+ nsPoint offset = ToReferenceFrame();
nsRect dirtyRect =
- nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mEffectsFrame,
+ nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mFrame,
mVisibleRect - offset) +
offset;
@@ -3070,7 +3077,7 @@ bool nsDisplaySVGEffects::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem
nsDisplaySVGEffects* other = static_cast<nsDisplaySVGEffects*>(aItem);
MergeFromTrackingMergedFrames(other);
mEffectsBounds.UnionRect(mEffectsBounds,
- other->mEffectsBounds + other->mEffectsFrame->GetOffsetTo(mEffectsFrame));
+ other->mEffectsBounds + other->mFrame->GetOffsetTo(mFrame));
return true;
}
@@ -3079,16 +3086,16 @@ void
nsDisplaySVGEffects::PrintEffects(FILE* aOutput)
{
nsIFrame* firstFrame =
- nsLayoutUtils::GetFirstContinuationOrSpecialSibling(mEffectsFrame);
+ nsLayoutUtils::GetFirstContinuationOrSpecialSibling(mFrame);
nsSVGEffects::EffectProperties effectProperties =
nsSVGEffects::GetEffectProperties(firstFrame);
bool isOK = true;
nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
bool first = true;
fprintf(aOutput, " effects=(");
- if (mEffectsFrame->GetStyleDisplay()->mOpacity != 1.0f) {
+ if (mFrame->GetStyleDisplay()->mOpacity != 1.0f) {
first = false;
- fprintf(aOutput, "opacity(%f)", mEffectsFrame->GetStyleDisplay()->mOpacity);
+ fprintf(aOutput, "opacity(%f)", mFrame->GetStyleDisplay()->mOpacity);
}
if (clipPathFrame) {
if (!first) {
View
81 layout/base/nsDisplayList.h
@@ -197,8 +197,12 @@ class nsDisplayListBuilder {
* the appunits of aFrame. It may be optimized to be faster than
* aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't).
*/
- nsPoint ToReferenceFrame(const nsIFrame* aFrame) const {
- return aFrame->GetOffsetToCrossDoc(ReferenceFrame());
+ const nsPoint& ToReferenceFrame(const nsIFrame* aFrame) {
+ if (aFrame != mCachedOffsetFrame) {
+ mCachedOffsetFrame = aFrame;
+ mCachedOffset = aFrame->GetOffsetToCrossDoc(ReferenceFrame());
+ }
+ return mCachedOffset;
}
/**
* When building the display list, the scrollframe aFrame will be "ignored"
@@ -412,22 +416,44 @@ class nsDisplayListBuilder {
/**
* A helper class to temporarily set the value of
- * mIsAtRootOfPseudoStackingContext.
+ * mIsAtRootOfPseudoStackingContext and temporarily update
+ * mCachedOffsetFrame/mCachedOffset from a frame to its child.
*/
- class AutoIsRootSetter;
- friend class AutoIsRootSetter;
- class AutoIsRootSetter {
+ class AutoBuildingDisplayList;
+ friend class AutoBuildingDisplayList;
+ class AutoBuildingDisplayList {
public:
- AutoIsRootSetter(nsDisplayListBuilder* aBuilder, bool aIsRoot)
- : mBuilder(aBuilder), mOldValue(aBuilder->mIsAtRootOfPseudoStackingContext) {
+ AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, bool aIsRoot)
+ : mBuilder(aBuilder),
+ mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
+ mPrevCachedOffset(aBuilder->mCachedOffset),
+ mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext) {
+ aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
+ }
+ AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aForChild, bool aIsRoot)
+ : mBuilder(aBuilder),
+ mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame),
+ mPrevCachedOffset(aBuilder->mCachedOffset),
+ mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext) {
+ if (mPrevCachedOffsetFrame == aForChild->GetParent()) {
+ aBuilder->mCachedOffset += aForChild->GetPosition();
+ } else {
+ aBuilder->mCachedOffset = aForChild->GetOffsetToCrossDoc(aBuilder->ReferenceFrame());
+ }
+ aBuilder->mCachedOffsetFrame = aForChild;
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
}
- ~AutoIsRootSetter() {
- mBuilder->mIsAtRootOfPseudoStackingContext = mOldValue;
+ ~AutoBuildingDisplayList() {
+ mBuilder->mCachedOffsetFrame = mPrevCachedOffsetFrame;
+ mBuilder->mCachedOffset = mPrevCachedOffset;
+ mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
}
private:
nsDisplayListBuilder* mBuilder;
- bool mOldValue;
+ const nsIFrame* mPrevCachedOffsetFrame;
+ nsPoint mPrevCachedOffset;
+ bool mPrevIsAtRootOfPseudoStackingContext;
};
/**
@@ -438,7 +464,7 @@ class nsDisplayListBuilder {
class AutoInTransformSetter {
public:
AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
- : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
+ : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
aBuilder->mInTransform = aInTransform;
}
~AutoInTransformSetter() {
@@ -447,8 +473,8 @@ class nsDisplayListBuilder {
private:
nsDisplayListBuilder* mBuilder;
bool mOldValue;
- };
-
+ };
+
// Helpers for tables
nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
@@ -497,6 +523,10 @@ class nsDisplayListBuilder {
nsAutoTArray<ThemeGeometry,2> mThemeGeometries;
nsDisplayTableItem* mCurrentTableItem;
const nsRegion* mFinalTransparentRegion;
+ // When mCachedOffsetFrame is non-null, mCachedOffset is the offset from
+ // mCachedOffsetFrame to mReferenceFrame.
+ const nsIFrame* mCachedOffsetFrame;
+ nsPoint mCachedOffset;
nsRect mDisplayPort;
nsRegion mExcludedGlassRegion;
Mode mMode;
@@ -567,6 +597,15 @@ class nsDisplayItem : public nsDisplayItemLink {
mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
}
}
+ nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+ const nsPoint& aToReferenceFrame)
+ : mFrame(aFrame)
+ , mToReferenceFrame(aToReferenceFrame)
+#ifdef MOZ_DUMP_PAINTING
+ , mPainted(false)
+#endif
+ {
+ }
virtual ~nsDisplayItem() {}
void* operator new(size_t aSize,
@@ -1700,7 +1739,10 @@ class nsDisplayWrapList : public nsDisplayItem {
nsDisplayList* aList);
nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayItem* aItem);
- nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
+ nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+ nsDisplayItem* aItem, const nsPoint& aToReferenceFrame);
+ nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+ : nsDisplayItem(aBuilder, aFrame) {}
virtual ~nsDisplayWrapList();
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
@@ -2097,7 +2139,7 @@ class nsDisplaySVGEffects : public nsDisplayWrapList {
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
- return mEffectsBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
+ return mEffectsBounds + ToReferenceFrame();
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
@@ -2106,16 +2148,13 @@ class nsDisplaySVGEffects : public nsDisplayWrapList {
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem);
NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
- nsIFrame* GetEffectsFrame() { return mEffectsFrame; }
-
#ifdef MOZ_DUMP_PAINTING
void PrintEffects(FILE* aOutput);
#endif
private:
- nsIFrame* mEffectsFrame;
- // relative to mEffectsFrame
- nsRect mEffectsBounds;
+ // relative to mFrame
+ nsRect mEffectsBounds;
};
/* A display item that applies a transformation to all of its descendant
View
3 layout/base/nsLayoutUtils.cpp
@@ -3554,6 +3554,9 @@ DrawImageInternal(nsRenderingContext* aRenderingContext,
const nsIntSize& aImageSize,
PRUint32 aImageFlags)
{
+ if (aDest.Contains(aFill)) {
+ aImageFlags |= imgIContainer::FLAG_CLAMP;
+ }
PRInt32 appUnitsPerDevPixel = aRenderingContext->AppUnitsPerDevPixel();
gfxContext* ctx = aRenderingContext->ThebesContext();
View
24 layout/generic/nsFrame.cpp
@@ -1407,15 +1407,6 @@ nsIFrame::GetCaretColorAt(PRInt32 aOffset)
return GetStyleColor()->mColor;
}
-bool
-nsIFrame::HasBorder() const
-{
- // Border images contribute to the background of the content area
- // even if there's no border proper.
- return (GetUsedBorder() != nsMargin(0,0,0,0) ||
- GetStyleBorder()->IsBorderImageLoaded());
-}
-
nsresult
nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists,
@@ -1465,9 +1456,8 @@ nsFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
}
// If there's a themed background, we should not create a border item.
- // It won't be rendered. Calling HasBorder() for themed frames is expensive
- // too (calls into native theme code), so avoiding it is valuable.
- if ((!bg || !bg->IsThemed()) && HasBorder()) {
+ // It won't be rendered.
+ if ((!bg || !bg->IsThemed()) && GetStyleBorder()->HasBorder()) {
rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayBorder(aBuilder, this));
NS_ENSURE_SUCCESS(rv, rv);
@@ -1816,7 +1806,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsDisplayListCollection set;
nsresult rv;
{
- nsDisplayListBuilder::AutoIsRootSetter rootSetter(aBuilder, true);
+ nsDisplayListBuilder::AutoBuildingDisplayList rootSetter(aBuilder, true);
nsDisplayListBuilder::AutoInTransformSetter
inTransformSetter(aBuilder, inTransform);
rv = BuildDisplayList(aBuilder, dirtyRect, set);
@@ -2069,7 +2059,10 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// If you change this, also change IsPseudoStackingContextFromStyle()
pseudoStackingContext = true;
}
-
+
+ nsDisplayListBuilder::AutoBuildingDisplayList
+ buildingForChild(aBuilder, child, pseudoStackingContext);
+
nsRect overflowClip;
nscoord overflowClipRadii[8];
bool applyOverflowClip =
@@ -2084,7 +2077,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// overflow:hidden etc creates an nsHTML/XULScrollFrame which does its own
// clipping.
- nsDisplayListBuilder::AutoIsRootSetter rootSetter(aBuilder, pseudoStackingContext);
nsresult rv;
if (!pseudoStackingContext) {
// THIS IS THE COMMON CASE.
@@ -3874,7 +3866,7 @@ nsRect
nsFrame::ComputeSimpleTightBounds(gfxContext* aContext) const
{
if (GetStyleOutline()->GetOutlineStyle() != NS_STYLE_BORDER_STYLE_NONE ||
- HasBorder() || !GetStyleBackground()->IsTransparent() ||
+ GetStyleBorder()->HasBorder() || !GetStyleBackground()->IsTransparent() ||
GetStyleDisplay()->mAppearance) {
// Not necessarily tight, due to clipping, negative
// outline-offset, and lots of other issues, but that's OK
View
5 layout/generic/nsIFrame.h
@@ -815,11 +815,6 @@ class nsIFrame : public nsQueryFrame
nsStyleContext* aStyleContext) = 0;
/**
- * @return false if this frame definitely has no borders at all
- */
- bool HasBorder() const;
-
- /**
* Accessor functions for geometric parent
*/
nsIFrame* GetParent() const { return mParent; }
View
1 layout/style/forms.css
@@ -379,6 +379,7 @@ select:disabled:disabled /* Need the pseudo-class twice to have the specificity
be at least the same as select[size][multiple] above */
{
-moz-user-input: disabled;
+ -moz-user-focus: ignore;
color: GrayText;
background-color: ThreeDFace;
cursor: inherit;
View
5 layout/style/nsStyleStruct.h
@@ -826,6 +826,11 @@ struct nsStyleBorder {
return mComputedBorder;
}
+ bool HasBorder() const
+ {
+ return mComputedBorder != nsMargin(0,0,0,0) || mBorderImageSource;
+ }
+
// Get the actual border width for a particular side, in appunits. Note that
// this is zero if and only if there is no border to be painted for this
// side. That is, this value takes into account the border style and the
View
5 layout/tables/nsTableCellFrame.cpp
@@ -459,7 +459,8 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
// display outset box-shadows if we need to.
- bool hasBoxShadow = !!(GetStyleBorder()->mBoxShadow);
+ const nsStyleBorder* borderStyle = GetStyleBorder();
+ bool hasBoxShadow = !!borderStyle->mBoxShadow;
if (hasBoxShadow) {
nsresult rv = aLists.BorderBackground()->AppendNewToTop(
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this));
@@ -488,7 +489,7 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
// display borders if we need to
- if (!tableFrame->IsBorderCollapse() && HasBorder() &&
+ if (!tableFrame->IsBorderCollapse() && borderStyle->HasBorder() &&
emptyCellStyle == NS_STYLE_TABLE_EMPTY_CELLS_SHOW) {
nsresult rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayBorder(aBuilder, this));
View
2 layout/tables/nsTableFrame.cpp
@@ -1250,7 +1250,7 @@ AnyTablePartHasBorderOrBackground(nsIFrame* aStart, nsIFrame* aEnd)
if (f->GetStyleVisibility()->IsVisible() &&
(!f->GetStyleBackground()->IsTransparent() ||
f->GetStyleDisplay()->mAppearance ||
- f->HasBorder()))
+ f->GetStyleBorder()->HasBorder()))
return true;
nsTableCellFrame *cellFrame = do_QueryFrame(f);
View
2 layout/xul/base/src/nsBoxFrame.cpp
@@ -1342,7 +1342,7 @@ nsBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (GetContent()->IsXUL()) {
const nsStyleDisplay* styles = mStyleContext->GetStyleDisplay();
if (styles && styles->mAppearance == NS_THEME_WIN_EXCLUDE_GLASS) {
- nsRect rect = mRect + aBuilder->ToReferenceFrame(GetParent());
+ nsRect rect = nsRect(aBuilder->ToReferenceFrame(this), GetSize());
aBuilder->AddExcludedGlassRegion(rect);
}
}
View
50 mobile/android/base/GeckoApp.java
@@ -1649,6 +1649,10 @@ private void initialize() {
mBrowserToolbar.updateTabCount(1);
}
+ // Start migrating as early as possible, can do this in
+ // parallel with Gecko load.
+ checkMigrateProfile();
+
Uri data = intent.getData();
if (data != null && "http".equals(data.getScheme()) &&
isHostOnPrefetchWhitelist(data.getHost())) {
@@ -1771,6 +1775,9 @@ public void run() {
GeckoAppShell.getHandler().postDelayed(new Runnable() {
public void run() {
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - pre checkLaunchState");
+ // Sync settings need Gecko to be loaded, so
+ // no hurry in starting this.
+ checkMigrateSync();
/*
XXXX see bug 635342
@@ -1784,8 +1791,6 @@ public void run() {
if (!checkLaunchState(LaunchState.Launched)) {
return;
}
-
- checkMigrateProfile();
}
}, 50);
}
@@ -2278,30 +2283,49 @@ private String readUpdateStatus(File statusFile) {
}
private void checkMigrateProfile() {
- File profileDir = getProfile().getDir();
- long currentTime = SystemClock.uptimeMillis();
+ final File profileDir = getProfile().getDir();
+ final long currentTime = SystemClock.uptimeMillis();
if (profileDir != null) {
- Log.i(LOGTAG, "checking profile migration in: " + profileDir.getAbsolutePath());
+ Log.i(LOGTAG, "Checking profile migration in: " + profileDir.getAbsolutePath());
final GeckoApp app = GeckoApp.mAppContext;
- ProfileMigrator profileMigrator =
+ final ProfileMigrator profileMigrator =
new ProfileMigrator(app, profileDir);
// Do a migration run on the first start after an upgrade.
if (!profileMigrator.hasMigrationRun()) {
final SetupScreen setupScreen = new SetupScreen(app);
- // don't show unless this take a while
+ // Don't show unless this take a while.
setupScreen.showDelayed(mMainHandler);
- profileMigrator.launch();
- setupScreen.dismiss();
- // Update about:home with the new information.
- updateAboutHomeTopSites();
+ GeckoAppShell.getHandler().post(new Runnable() {
+ public void run() {
+ profileMigrator.launchPlaces();
+ setupScreen.dismiss();
+
+ long timeDiff = SystemClock.uptimeMillis() - currentTime;
+ Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
+
+ // Update about:home with the new information.
+ updateAboutHomeTopSites();
+ }
+ });
+ }
+ }
+ }
+
+ private void checkMigrateSync() {
+ final File profileDir = getProfile().getDir();
+ if (profileDir != null) {
+ final GeckoApp app = GeckoApp.mAppContext;
+ ProfileMigrator profileMigrator =
+ new ProfileMigrator(app, profileDir);
+ if (!profileMigrator.hasSyncMigrated()) {
+ Log.i(LOGTAG, "Checking Sync settings in: " + profileDir.getAbsolutePath());
+ profileMigrator.launchSyncPrefs();
}
}
- long timeDiff = SystemClock.uptimeMillis() - currentTime;
- Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
}
/**
View
4 mobile/android/base/Makefile.in
@@ -420,6 +420,8 @@ RES_DRAWABLE_HDPI = \
res/drawable-hdpi/site_security_identified.png \
res/drawable-hdpi/site_security_verified.png \
res/drawable-hdpi/urlbar_stop.png \
+ res/drawable-hdpi/validation_arrow.png \
+ res/drawable-hdpi/validation_bg.9.png \
$(addprefix res/drawable-hdpi/,$(notdir $(SYNC_RES_DRAWABLE_HDPI))) \
$(NULL)
@@ -481,6 +483,8 @@ RES_DRAWABLE_XHDPI_V11 = \
res/drawable-xhdpi-v11/site_security_identified.png \
res/drawable-xhdpi-v11/site_security_verified.png \
res/drawable-xhdpi-v11/tabs_button_tail.9.png \
+ res/drawable-xhdpi-v11/validation_arrow.png \
+ res/drawable-xhdpi-v11/validation_bg.9.png \
$(NULL)
RES_DRAWABLE_LAND_V14 = \
View
267 mobile/android/base/ProfileMigrator.java
@@ -42,11 +42,15 @@
import org.mozilla.gecko.db.BrowserContract.History;
import org.mozilla.gecko.db.BrowserContract.ImageColumns;
import org.mozilla.gecko.db.BrowserContract.Images;
+import org.mozilla.gecko.db.BrowserContract.Passwords;
import org.mozilla.gecko.db.BrowserContract.URLColumns;
import org.mozilla.gecko.db.BrowserContract.SyncColumns;
import org.mozilla.gecko.sqlite.SQLiteBridge;
import org.mozilla.gecko.sqlite.SQLiteBridgeException;
+import org.mozilla.gecko.sync.setup.SyncAccounts;
+import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
+import android.accounts.Account;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -61,11 +65,12 @@
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.RemoteException;
import android.provider.Browser;
+import android.text.TextUtils;
import android.util.Log;
-import android.net.Uri;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -83,6 +88,10 @@
import java.util.Map;
import java.util.Set;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.json.JSONException;
+
public class ProfileMigrator {
private static final String LOGTAG = "ProfileMigrator";
private static final String PREFS_NAME = "ProfileMigrator";
@@ -101,6 +110,7 @@
private static final String PREFS_MIGRATE_HISTORY_DONE = "history_done";
// Number of history entries already migrated.
private static final String PREFS_MIGRATE_HISTORY_COUNT = "history_count";
+ private static final String PREFS_MIGRATE_SYNC_DONE = "sync_done";
/*
These queries are derived from the low-level Places schema
@@ -199,29 +209,57 @@ vs milli (Android) distiction.
private final String kHistoryDate = "h_date";
private final String kHistoryVisits = "h_visits";
+ /*
+ Sync settings to get from prefs.js.
+ */
+ private final String[] kSyncSettingsList = new String[] {
+ "services.sync.account",
+ "services.sync.client.name",
+ "services.sync.client.GUID",
+ "services.sync.serverURL",
+ "services.sync.clusterURL"
+ };
+
+ /*
+ Sync settings to get from password manager.
+ */
+ private final String kSyncHostName = "chrome://weave";
+ private final String[] kSyncRealmList = new String[] {
+ "Mozilla Services Password",
+ "Mozilla Services Encryption Passphrase"
+ };
+
+
public ProfileMigrator(Context context, File profileDir) {
mProfileDir = profileDir;
mContext = context;
mCr = mContext.getContentResolver();
}
- public void launch() {
+ public void launchPlaces() {
boolean timeThisRun = false;
Telemetry.Timer timer = null;
// First run, time things
if (!hasMigrationRun()) {
timeThisRun = true;
timer = new Telemetry.Timer("BROWSERPROVIDER_XUL_IMPORT_TIME");
}
- launch(DEFAULT_HISTORY_MIGRATE_COUNT);
+ launchPlaces(DEFAULT_HISTORY_MIGRATE_COUNT);
if (timeThisRun)
timer.stop();
}
- public void launch(int maxEntries) {
+ public void launchPlaces(int maxEntries) {
+ // Places migration is heavy on the phone, allow it to block
+ // other processing.
new PlacesRunnable(maxEntries).run();
}
+ public void launchSyncPrefs() {
+ // Sync settings will post a runnable, no need for a seperate thread.
+ new SyncTask().run();
+ }
+
public boolean areBookmarksMigrated() {
return getPreferences().getBoolean(PREFS_MIGRATE_BOOKMARKS_DONE, false);
}
@@ -230,6 +268,11 @@ public boolean isHistoryMigrated() {
return getPreferences().getBoolean(PREFS_MIGRATE_HISTORY_DONE, false);
}
+ // Have Sync settings been transferred?
+ public boolean hasSyncMigrated() {
+ return getPreferences().getBoolean(PREFS_MIGRATE_SYNC_DONE, false);
+ }
+
// Has migration run before?
protected boolean hasMigrationRun() {
return areBookmarksMigrated() && (getMigratedHistoryEntries() > 0);
@@ -266,6 +309,206 @@ protected void setMigratedBookmarks() {
editor.commit();
}
+ protected void setMigratedSync() {
+ SharedPreferences.Editor editor = getPreferences().edit();
+ editor.putBoolean(PREFS_MIGRATE_SYNC_DONE, true);
+ editor.commit();
+ }
+
+ private class SyncTask implements Runnable, GeckoEventListener {
+ private List<String> mSyncSettingsList;
+ private Map<String, String> mSyncSettingsMap;
+
+ // Initialize preferences by sending the "Preferences:Get" command to Gecko
+ protected void requestValues() {
+ mSyncSettingsList = Arrays.asList(kSyncSettingsList);
+ mSyncSettingsMap = new HashMap<String, String>();
+ JSONArray jsonPrefs = new JSONArray(mSyncSettingsList);
+ Log.d(LOGTAG, "Sending: " + jsonPrefs.toString());
+ GeckoEvent event =
+ GeckoEvent.createBroadcastEvent("Preferences:Get",
+ jsonPrefs.toString());
+ GeckoAppShell.sendEventToGecko(event);
+ }
+
+ // Receive settings reply from Gecko, do the rest of the setup
+ public void handleMessage(String event, JSONObject message) {
+ Log.d(LOGTAG, "Received event: " + event);
+ try {
+ if (event.equals("Preferences:Data")) {
+ // Receive most settings from Gecko's service.
+ // This includes personal info, so don't log.
+ // Log.d(LOGTAG, "Message: " + message.toString());
+ JSONArray jsonPrefs = message.getJSONArray("preferences");
+ parsePrefs(jsonPrefs);
+ GeckoAppShell.unregisterGeckoEventListener("Preferences:Data",
+ (GeckoEventListener)this);
+
+ // Now call the password provider to fill in the rest.
+ for (String location: kSyncRealmList) {
+ Log.d(LOGTAG, "Checking: " + location);
+ String passwd = getPassword(location);
+ if (!TextUtils.isEmpty(passwd)) {
+ Log.d(LOGTAG, "Got password");
+ mSyncSettingsMap.put(location, passwd);
+ } else {
+ Log.d(LOGTAG, "No password found");
+ mSyncSettingsMap.put(location, null);
+ }
+ }
+
+ // Call Sync and transfer settings.
+ configureSync();
+ }
+ } catch (Exception e) {
+ Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
+ }
+ }
+
+ protected String getPassword(String realm) {
+ Cursor cursor = null;
+ String result = null;
+ try {
+ cursor = mCr.query(Passwords.CONTENT_URI,
+ null,
+ Passwords.HOSTNAME + " = ? AND "
+ + Passwords.HTTP_REALM + " = ?",
+ new String[] { kSyncHostName, realm },
+ null);
+
+ if (cursor != null) {
+ final int userCol =
+ cursor.getColumnIndexOrThrow(Passwords.ENCRYPTED_USERNAME);
+ final int passCol =
+ cursor.getColumnIndexOrThrow(Passwords.ENCRYPTED_PASSWORD);
+
+ if (cursor.moveToFirst()) {
+ String user = cursor.getString(userCol);
+ String pass = cursor.getString(passCol);
+ result = pass;
+ } else {
+ Log.i(LOGTAG, "No password found for realm = " + realm);
+ }
+ }
+ } finally {
+ if (cursor != null)
+ cursor.close();
+ }
+
+ return result;
+ }
+
+ protected void parsePrefs(JSONArray jsonPrefs) {
+ try {
+ final int length = jsonPrefs.length();
+ for (int i = 0; i < length; i++) {
+ JSONObject jPref = jsonPrefs.getJSONObject(i);
+ final String prefName = jPref.getString("name");
+ final String prefType = jPref.getString("type");
+ if ("bool".equals(prefType)) {
+ final boolean value = jPref.getBoolean("value");
+ mSyncSettingsMap.put(prefName, value ? "1" : "0");
+ } else {
+ final String value = jPref.getString("value");
+ if (!TextUtils.isEmpty(value)) {
+ mSyncSettingsMap.put(prefName, value);
+ } else {
+ Log.w(LOGTAG, "Could not recover setting for = " + prefName);
+ mSyncSettingsMap.put(prefName, null);
+ }
+ }
+ }
+ } catch (JSONException e) {
+ Log.e(LOGTAG, "Exception handling preferences answer: "
+ + e.getMessage());
+ }
+ }
+
+ protected void configureSync() {
+ final String userName = mSyncSettingsMap.get("services.sync.account");
+ final String syncKey = mSyncSettingsMap.get("Mozilla Services Password");
+ final String syncPass = mSyncSettingsMap.get("Mozilla Services Encryption Passphrase");
+ final String serverURL = mSyncSettingsMap.get("services.sync.serverURL");
+ final String clusterURL = mSyncSettingsMap.get("services.sync.clusterURL");
+ final String clientName = mSyncSettingsMap.get("services.sync.client.name");
+ final String clientGuid = mSyncSettingsMap.get("services.sync.client.GUID");
+
+ if (userName == null || syncKey == null || syncPass == null) {
+ // This isn't going to work. Give up.
+ Log.e(LOGTAG, "Profile has incomplete Sync config. Not migrating.");
+ setMigratedSync();
+ return;
+ }
+
+ final SyncAccountParameters params =
+ new SyncAccountParameters(mContext, null,
+ userName, syncKey,
+ syncPass, serverURL, clusterURL,
+ clientName, clientGuid);
+
+ new SyncAccounts.CreateSyncAccountTask() {
+ @Override
+ protected void onPostExecute(Account account) {
+ if (account == null) {
+ Log.e(LOGTAG, "Failed to migrate Sync account.");
+ } else {
+ Log.i(LOGTAG, "Migrating Sync account succeeded.");
+ }
+ setMigratedSync();
+ }
+ }.execute(params);
+ }
+
+ protected void registerAndRequest() {
+ GeckoAppShell.getHandler().post(new Runnable() {
+ public void run() {
+ GeckoAppShell.registerGeckoEventListener("Preferences:Data",
+ SyncTask.this);
+ requestValues();
+ }
+ });
+ }
+
+ @Override
+ public void run() {
+ // Run only if no Sync accounts exist.
+ new SyncAccounts.AccountsExistTask() {
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (result.booleanValue()) {
+ Log.i(LOGTAG, "Sync account already configured, skipping.");
+ setMigratedSync();
+ } else {
+ // No account configured, fire up.
+ registerAndRequest();
+ }
+ }
+ }.execute(mContext);
+ }
+ }
+
+ private class MiscTask implements Runnable {
+ protected void cleanupXULLibCache() {
+ File cacheFile = GeckoAppShell.getCacheDir(mContext);
+ File[] files = cacheFile.listFiles();
+ if (files != null) {
+ Iterator cacheFiles = Arrays.asList(files).iterator();
+ while (cacheFiles.hasNext()) {
+ File libFile = (File)cacheFiles.next();
+ if (libFile.getName().endsWith(".so")) {
+ libFile.delete();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ // XXX: Land dependent bugs (732069) first
+ // cleanupXULLibCache();
+ }
+ }
+
private class PlacesRunnable implements Runnable {
private Map<Long, Long> mRerootMap;
private ArrayList<ContentProviderOperation> mOperations;
@@ -878,25 +1121,9 @@ protected void migratePlaces(File aFile) {
}
}
- protected void cleanupXULLibCache() {
- File cacheFile = GeckoAppShell.getCacheDir(mContext);
- File[] files = cacheFile.listFiles();
- if (files != null) {
- Iterator<File> cacheFiles = Arrays.asList(files).iterator();
- while (cacheFiles.hasNext()) {
- File libFile = cacheFiles.next();
- if (libFile.getName().endsWith(".so")) {
- libFile.delete();
- }
- }
- }
- }
-
@Override
public void run() {
migratePlaces(mProfileDir);
- // XXX: Land dependent bugs first
- // cleanupXULLibCache();
}
}
}
View
2 mobile/android/base/db/BrowserProvider.java.in
@@ -1497,7 +1497,7 @@ public class BrowserProvider extends ContentProvider {
boolean needHistory = wantHistory && !migrator.isHistoryMigrated();
if (needBookmarks || needHistory) {
- migrator.launch();
+ migrator.launchPlaces();
needBookmarks = wantBookmarks && !migrator.areBookmarksMigrated();