merge m-c to fx-team; a=merge

This commit is contained in:
Tim Taubert 2014-10-13 22:58:30 +02:00
commit e16550584f
29 changed files with 194 additions and 278 deletions

View File

@ -61,6 +61,10 @@ input[type=button] {
right: auto;
}
#newtab-scrollbox[page-disabled] #newtab-intro-what {
display: none;
}
#newtab-intro-panel {
color: #6a7b86;
font-size: 15px;

View File

@ -391,7 +391,8 @@ loop.conversation = (function(mozL10n) {
if (progressData.state !== "terminated")
return;
if (progressData.reason === "cancel") {
if (progressData.reason === "cancel" ||
progressData.reason === "closed") {
this._abortIncomingCall();
return;
}

View File

@ -391,7 +391,8 @@ loop.conversation = (function(mozL10n) {
if (progressData.state !== "terminated")
return;
if (progressData.reason === "cancel") {
if (progressData.reason === "cancel" ||
progressData.reason === "closed") {
this._abortIncomingCall();
return;
}

View File

@ -406,6 +406,46 @@ describe("loop.conversation", function() {
});
});
describe("progress - terminated - closed", function() {
it("should stop alerting", function(done) {
promise.then(function() {
icView._websocket.trigger("progress", {
state: "terminated",
reason: "closed"
});
sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
done();
});
});
it("should close the websocket", function(done) {
promise.then(function() {
icView._websocket.trigger("progress", {
state: "terminated",
reason: "closed"
});
sinon.assert.calledOnce(icView._websocket.close);
done();
});
});
it("should close the window", function(done) {
promise.then(function() {
icView._websocket.trigger("progress", {
state: "terminated",
reason: "closed"
});
sandbox.clock.tick(1);
sinon.assert.calledOnce(window.close);
done();
});
});
});
describe("progress - terminated - timeout (previousState = alerting)", function() {
it("should stop alerting", function(done) {
promise.then(function() {

View File

@ -1,45 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["RevivableWindows"];
// List of closed windows that we can revive when closing
// windows in succession until the browser quits.
let closedWindows = [];
/**
* This module keeps track of closed windows that are revivable. On Windows
* and Linux we can revive windows before saving to disk - i.e. moving them
* from state._closedWindows[] to state.windows[] so that they're opened
* automatically on next startup. This feature lets us properly support
* closing windows in succession until the browser quits.
*
* The length of the list is not capped by max_undo_windows unlike
* state._closedWindows[].
*/
this.RevivableWindows = Object.freeze({
// Returns whether there are windows to revive.
get isEmpty() {
return closedWindows.length == 0;
},
// Add a window to the list.
add(winState) {
#ifndef XP_MACOSX
closedWindows.push(winState);
#endif
},
// Get the list of revivable windows.
get() {
return [...closedWindows];
},
// Clear the list of revivable windows.
clear() {
closedWindows.length = 0;
}
});

View File

@ -19,8 +19,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyFilter",
"resource:///modules/sessionstore/PrivacyFilter.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RevivableWindows",
"resource:///modules/sessionstore/RevivableWindows.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionFile",
@ -207,24 +205,23 @@ let SessionSaverInternal = {
delete state.deferredInitialState;
}
// We want to revive closed windows that have been closed in succession
// without any user action in between closing those. This happens here in
// the SessionSaver because we only want to revive when saving to disk.
// On Mac OS X this list will always be empty.
let windowsToRevive = RevivableWindows.get();
state.windows.unshift(...windowsToRevive);
let revivedWindows = state._closedWindows.splice(0, windowsToRevive.length);
#ifdef DEBUG
// Check that the windows to revive equal the windows
// that we removed from the list of closed windows.
let match = revivedWindows.every((win, idx) => {
return win == windowsToRevive[windowsToRevive.length - 1 - idx];
});
#ifndef XP_MACOSX
// We want to restore closed windows that are marked with _shouldRestore.
// We're doing this here because we want to control this only when saving
// the file.
while (state._closedWindows.length) {
let i = state._closedWindows.length - 1;
if (!match) {
throw new Error("SessionStore: revived windows didn't match closed windows");
if (!state._closedWindows[i]._shouldRestore) {
// We only need to go until _shouldRestore
// is falsy since we're going in reverse.
break;
}
delete state._closedWindows[i]._shouldRestore;
state.windows.unshift(state._closedWindows.pop());
}
#endif DEBUG
#endif
stopWatchFinish("COLLECT_DATA_MS", "COLLECT_DATA_LONGEST_OP_MS");
return this._writeState(state);

View File

@ -107,8 +107,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "GlobalState",
"resource:///modules/sessionstore/GlobalState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyFilter",
"resource:///modules/sessionstore/PrivacyFilter.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RevivableWindows",
"resource:///modules/sessionstore/RevivableWindows.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RunState",
"resource:///modules/sessionstore/RunState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager",
@ -703,9 +701,7 @@ let SessionStoreInternal = {
this.saveStateDelayed(win);
break;
}
// Any event handled here indicates a user action.
RevivableWindows.clear();
this._clearRestoringWindows();
},
/**
@ -1017,6 +1013,12 @@ let SessionStoreInternal = {
SessionCookies.update([winData]);
}
#ifndef XP_MACOSX
// Until we decide otherwise elsewhere, this window is part of a series
// of closing windows to quit.
winData._shouldRestore = true;
#endif
// Store the window's close date to figure out when each individual tab
// was closed. This timestamp should allow re-arranging data based on how
// recently something was closed.
@ -1037,8 +1039,9 @@ let SessionStoreInternal = {
// with tabs we deem not worth saving then we might end up with a
// random closed or even a pop-up window re-opened. To prevent that
// we explicitly allow saving an "empty" window state.
let numOpenWindows = Object.keys(this._windows).length;
let isLastWindow = numOpenWindows == 1 && RevivableWindows.isEmpty;
let isLastWindow =
Object.keys(this._windows).length == 1 &&
!this._closedWindows.some(win => win._shouldRestore || false);
if (hasSaveableTabs || isLastWindow) {
// we don't want to save the busy state
@ -1047,10 +1050,6 @@ let SessionStoreInternal = {
this._closedWindows.unshift(winData);
this._capClosedWindows();
}
// Until we decide otherwise elsewhere, this window
// is part of a series of closing windows to quit.
RevivableWindows.add(winData);
}
// clear this window from the list
@ -1156,11 +1155,8 @@ let SessionStoreInternal = {
delete this._windows[ix];
}
}
// also clear all data about closed windows
this._closedWindows = [];
RevivableWindows.clear();
// give the tabbrowsers a chance to clear their histories first
var win = this._getMostRecentBrowserWindow();
if (win) {
@ -1168,6 +1164,8 @@ let SessionStoreInternal = {
} else if (RunState.isRunning) {
SessionSaver.run();
}
this._clearRestoringWindows();
},
/**
@ -1221,12 +1219,11 @@ let SessionStoreInternal = {
}
}
// Purging domain data indicates a user action.
RevivableWindows.clear();
if (RunState.isRunning) {
SessionSaver.run();
}
this._clearRestoringWindows();
},
/**
@ -3349,6 +3346,21 @@ let SessionStoreInternal = {
this._closedWindows.splice(spliceTo, this._closedWindows.length);
},
/**
* Clears the set of windows that are "resurrected" before writing to disk to
* make closing windows one after the other until shutdown work as expected.
*
* This function should only be called when we are sure that there has been
* a user action that indicates the browser is actively being used and all
* windows that have been closed before are not part of a series of closing
* windows.
*/
_clearRestoringWindows: function ssi_clearRestoringWindows() {
for (let i = 0; i < this._closedWindows.length; i++) {
delete this._closedWindows[i]._shouldRestore;
}
},
/**
* Reset state to prepare for a new session state to be restored.
*/

View File

@ -46,7 +46,6 @@ EXTRA_JS_MODULES.sessionstore = [
]
EXTRA_PP_JS_MODULES.sessionstore += [
'RevivableWindows.jsm',
'SessionSaver.jsm',
'SessionStore.jsm',
]

View File

@ -81,7 +81,6 @@ skip-if = buildapp == 'mulet'
[browser_merge_closed_tabs.js]
[browser_pageStyle.js]
[browser_privatetabs.js]
[browser_revive_windows.js]
[browser_scrollPositions.js]
[browser_sessionHistory.js]
skip-if = e10s

View File

@ -1,160 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const IS_MAC = ("nsILocalFileMac" in Ci);
const URL_PREFIX = "about:mozilla?t=browser_revive_windows&r=";
const PREF_MAX_UNDO = "browser.sessionstore.max_windows_undo";
const URL_MAIN_WINDOW = URL_PREFIX + Math.random();
const URL_ADD_WINDOW1 = URL_PREFIX + Math.random();
const URL_ADD_WINDOW2 = URL_PREFIX + Math.random();
const URL_CLOSED_WINDOW = URL_PREFIX + Math.random();
add_task(function* setup() {
registerCleanupFunction(() => Services.prefs.clearUserPref(PREF_MAX_UNDO));
});
/**
* This test ensure that when closing windows in succession until the browser
* quits we are able to revive more windows than we keep around for the
* "Undo Close Window" feature.
*/
add_task(function* test_revive_windows() {
// We can restore a single window max.
Services.prefs.setIntPref(PREF_MAX_UNDO, 1);
// Clear list of closed windows.
forgetClosedWindows();
let windows = [];
// Create three windows.
for (let i = 0; i < 3; i++) {
let win = yield promiseNewWindow();
windows.push(win);
let tab = win.gBrowser.addTab("about:mozilla");
yield promiseBrowserLoaded(tab.linkedBrowser);
}
// Create a private window.
// This window must not be revived.
{
let win = yield promiseNewWindow({private: true});
windows.push(win);
let tab = win.gBrowser.addTab("about:mozilla");
yield promiseBrowserLoaded(tab.linkedBrowser);
}
// Close all windows.
for (let win of windows) {
yield promiseWindowClosed(win);
}
is(ss.getClosedWindowCount(), 1, "one window restorable");
// Save to disk and read.
let state = JSON.parse(yield promiseRecoveryFileContents());
// Check number of windows.
if (IS_MAC) {
is(state.windows.length, 1, "one open window");
is(state._closedWindows.length, 1, "one closed window");
} else {
is(state.windows.length, 4, "four open windows");
is(state._closedWindows.length, 0, "closed windows");
}
});
/**
* This test ensures that when closing windows one after the other until the
* browser shuts down (on Windows and Linux) we revive closed windows in the
* right order.
*/
add_task(function* test_revive_windows_order() {
// We can restore up to three windows max.
Services.prefs.setIntPref(PREF_MAX_UNDO, 3);
// Clear list of closed windows.
forgetClosedWindows();
let tab = gBrowser.addTab(URL_MAIN_WINDOW);
yield promiseBrowserLoaded(tab.linkedBrowser);
TabState.flush(tab.linkedBrowser);
registerCleanupFunction(() => gBrowser.removeTab(tab));
let win0 = yield promiseNewWindow();
let tab0 = win0.gBrowser.addTab(URL_CLOSED_WINDOW);
yield promiseBrowserLoaded(tab0.linkedBrowser);
yield promiseWindowClosed(win0);
let data = ss.getClosedWindowData();
ok(data.contains(URL_CLOSED_WINDOW), "window is restorable");
let win1 = yield promiseNewWindow();
let tab1 = win1.gBrowser.addTab(URL_ADD_WINDOW1);
yield promiseBrowserLoaded(tab1.linkedBrowser);
let win2 = yield promiseNewWindow();
let tab2 = win2.gBrowser.addTab(URL_ADD_WINDOW2);
yield promiseBrowserLoaded(tab2.linkedBrowser);
// Close both windows so that |win1| will be opened first and would be
// behind |win2| that was closed later.
yield promiseWindowClosed(win1);
yield promiseWindowClosed(win2);
// Repeat the checks once.
for (let i = 0; i < 2; i++) {
info(`checking window data, iteration #${i}`);
let contents = yield promiseRecoveryFileContents();
let {windows, _closedWindows: closedWindows} = JSON.parse(contents);
if (IS_MAC) {
// Check number of windows.
is(windows.length, 1, "one open window");
is(closedWindows.length, 3, "three closed windows");
// Check open window.
ok(JSON.stringify(windows).contains(URL_MAIN_WINDOW),
"open window is correct");
// Check closed windows.
ok(JSON.stringify(closedWindows[0]).contains(URL_ADD_WINDOW2),
"correct first additional window");
ok(JSON.stringify(closedWindows[1]).contains(URL_ADD_WINDOW1),
"correct second additional window");
ok(JSON.stringify(closedWindows[2]).contains(URL_CLOSED_WINDOW),
"correct main window");
} else {
// Check number of windows.
is(windows.length, 3, "three open windows");
is(closedWindows.length, 1, "one closed window");
// Check closed window.
ok(JSON.stringify(closedWindows).contains(URL_CLOSED_WINDOW),
"closed window is correct");
// Check that windows are in the right order.
ok(JSON.stringify(windows[0]).contains(URL_ADD_WINDOW1),
"correct first additional window");
ok(JSON.stringify(windows[1]).contains(URL_ADD_WINDOW2),
"correct second additional window");
ok(JSON.stringify(windows[2]).contains(URL_MAIN_WINDOW),
"correct main window");
}
}
});
function promiseNewWindow(opts = {private: false}) {
return new Promise(resolve => whenNewWindowLoaded(opts, resolve));
}
function forgetClosedWindows() {
while (ss.getClosedWindowCount()) {
ss.forgetClosedWindow(0);
}
}

View File

@ -14,6 +14,7 @@ skip-if = true
[browser_layoutview_update-after-navigation.js]
[browser_layoutview_update-after-reload.js]
[browser_layoutview_update-in-iframes.js]
skip-if = true # Bug 1020038 layout-view updates for iframe elements changes
[browser_editablemodel.js]
# [browser_editablemodel_allproperties.js]
# Disabled for too many intermittent failures (bug 1009322)

View File

@ -2760,7 +2760,7 @@ public class BrowserApp extends GeckoApp
share.setVisible(shareEnabled);
share.setEnabled(StringUtils.isShareableUrl(url) && shareEnabled);
MenuUtils.safeSetEnabled(aMenu, R.id.apps, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_INSTALL_APPS));
MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSIONS));
MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSION));
MenuUtils.safeSetEnabled(aMenu, R.id.downloads, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_DOWNLOADS));
// NOTE: Use MenuUtils.safeSetEnabled because some actions might

View File

@ -81,6 +81,7 @@ import android.location.Location;
import android.location.LocationListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.StrictMode;
@ -978,6 +979,12 @@ public abstract class GeckoApp
image = BitmapUtils.decodeByteArray(imgBuffer);
}
if (image != null) {
// Some devices don't have a DCIM folder and the Media.insertImage call will fail.
File dcimDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!dcimDir.mkdirs() && !dcimDir.isDirectory()) {
Toast.makeText((Context) this, R.string.set_image_path_fail, Toast.LENGTH_SHORT).show();
return;
}
String path = Media.insertImage(getContentResolver(),image, null, null);
if (path == null) {
Toast.makeText((Context) this, R.string.set_image_path_fail, Toast.LENGTH_SHORT).show();

View File

@ -55,14 +55,16 @@ public class RestrictedProfiles {
*/
public static enum Restriction {
DISALLOW_DOWNLOADS(1, "no_download_files"),
DISALLOW_INSTALL_EXTENSIONS(2, "no_install_extensions"),
DISALLOW_INSTALL_EXTENSION(2, "no_install_extensions"),
DISALLOW_INSTALL_APPS(3, "no_install_apps"), // UserManager.DISALLOW_INSTALL_APPS
DISALLOW_BROWSE_FILES(4, "no_browse_files"),
DISALLOW_SHARE(5, "no_share"),
DISALLOW_BOOKMARK(6, "no_bookmark"),
DISALLOW_ADD_CONTACTS(7, "no_add_contacts"),
DISALLOW_SET_IMAGE(8, "no_set_image"),
DISALLOW_MODIFY_ACCOUNTS(9, "no_modify_accounts"); // UserManager.DISALLOW_MODIFY_ACCOUNTS
DISALLOW_MODIFY_ACCOUNTS(9, "no_modify_accounts"), // UserManager.DISALLOW_MODIFY_ACCOUNTS
DISALLOW_REMOTE_DEBUGGING(10, "no_remote_debugging"),
DISALLOW_IMPORT_SETTINGS(11, "no_import_settings");
public final int id;
public final String name;

View File

@ -10,7 +10,10 @@ import org.mozilla.gecko.animation.BounceAnimator;
import org.mozilla.gecko.animation.BounceAnimator.Attributes;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.view.PagerTabStrip;
import android.util.AttributeSet;
import android.view.View;
@ -37,8 +40,11 @@ class HomePagerTabStrip extends PagerTabStrip {
private static final int BOUNCE4_MS = 100;
private static final int INIT_OFFSET = 100;
private final Paint shadowPaint;
private final int shadowSize;
public HomePagerTabStrip(Context context) {
super(context);
this(context, null);
}
public HomePagerTabStrip(Context context, AttributeSet attrs) {
@ -50,6 +56,13 @@ class HomePagerTabStrip extends PagerTabStrip {
setTabIndicatorColor(color);
final Resources res = getResources();
shadowSize = res.getDimensionPixelSize(R.dimen.tabs_strip_shadow_size);
shadowPaint = new Paint();
shadowPaint.setColor(res.getColor(R.color.url_bar_shadow));
shadowPaint.setStrokeWidth(0.0f);
getViewTreeObserver().addOnPreDrawListener(new PreDrawListener());
}
@ -61,6 +74,14 @@ class HomePagerTabStrip extends PagerTabStrip {
return 0;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int height = getHeight();
canvas.drawRect(0, height - shadowSize, getWidth(), height, shadowPaint);
}
private void animateTitles() {
final View prevTextView = getChildAt(0);
final View nextTextView = getChildAt(getChildCount() - 1);

View File

@ -8,8 +8,10 @@ package org.mozilla.gecko.home;
import org.mozilla.gecko.R;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@ -35,16 +37,35 @@ public class TabMenuStrip extends HorizontalScrollView
private final int titleOffset;
private final TabMenuStripLayout layout;
private final Paint shadowPaint;
private final int shadowSize;
public TabMenuStrip(Context context, AttributeSet attrs) {
super(context, attrs);
// Disable the scroll bar.
setHorizontalScrollBarEnabled(false);
titleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
final Resources res = getResources();
titleOffset = (int) (TITLE_OFFSET_DIPS * res.getDisplayMetrics().density);
layout = new TabMenuStripLayout(context, attrs);
addView(layout, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
shadowSize = res.getDimensionPixelSize(R.dimen.tabs_strip_shadow_size);
shadowPaint = new Paint();
shadowPaint.setColor(res.getColor(R.color.url_bar_shadow));
shadowPaint.setStrokeWidth(0.0f);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int height = getHeight();
canvas.drawRect(0, height - shadowSize, getWidth(), height, shadowPaint);
}
@Override

View File

@ -7,19 +7,31 @@ package org.mozilla.gecko.preferences;
import org.mozilla.gecko.R;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.RestrictedProfiles;
import org.mozilla.gecko.RestrictedProfiles.Restriction;
import java.util.Set;
import android.app.ProgressDialog;
import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
class AndroidImportPreference extends MultiPrefMultiChoicePreference {
private static final String LOGTAG = "AndroidImport";
public static final String PREF_KEY = "android.not_a_preference.import_android";
private static final String PREF_KEY_PREFIX = "import_android.data.";
private final Context mContext;
public static class Handler implements GeckoPreferences.PrefHandler {
public boolean setupPref(Context context, Preference pref) {
return RestrictedProfiles.isAllowed(Restriction.DISALLOW_IMPORT_SETTINGS);
}
public void onChange(Context context, Preference pref, Object newValue) { }
}
public AndroidImportPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;

View File

@ -19,12 +19,13 @@ public class ClearOnShutdownPref implements GeckoPreferences.PrefHandler {
public static final String PREF = GeckoPreferences.NON_PREF_PREFIX + "history.clear_on_exit";
@Override
public void setupPref(Context context, Preference pref) {
public boolean setupPref(Context context, Preference pref) {
// The pref is initialized asynchronously. Read the pref explicitly
// here to make sure we have the data.
final SharedPreferences prefs = GeckoSharedPrefs.forProfile(context);
final Set<String> clearItems = PrefUtils.getStringSet(prefs, PREF, new HashSet<String>());
((ListCheckboxPreference) pref).setChecked(clearItems.size() > 0);
return true;
}
@Override

View File

@ -700,6 +700,12 @@ OnSharedPreferenceChangeListener
i--;
continue;
} else if (PREFS_DEVTOOLS_REMOTE_ENABLED.equals(key)) {
if (!RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_REMOTE_DEBUGGING)) {
preferences.removePreference(pref);
i--;
continue;
}
final Context thisContext = this;
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
@ -744,7 +750,11 @@ OnSharedPreferenceChangeListener
continue;
} else if (handlers.containsKey(key)) {
PrefHandler handler = handlers.get(key);
handler.setupPref(this, pref);
if (!handler.setupPref(this, pref)) {
preferences.removePreference(pref);
i--;
continue;
}
}
// Some Preference UI elements are not actually preferences,
@ -1026,13 +1036,16 @@ OnSharedPreferenceChangeListener
}
public interface PrefHandler {
public void setupPref(Context context, Preference pref);
// Allows the pref to do any initialization it needs. Return false to have the pref removed
// from the prefs screen entirely.
public boolean setupPref(Context context, Preference pref);
public void onChange(Context context, Preference pref, Object newValue);
}
@SuppressWarnings("serial")
private final Map<String, PrefHandler> handlers = new HashMap<String, PrefHandler>() {{
put(ClearOnShutdownPref.PREF, new ClearOnShutdownPref());
put(AndroidImportPreference.PREF_KEY, new AndroidImportPreference.Handler());
}};
@Override

View File

@ -14,7 +14,7 @@
android:background="@android:color/white">
<org.mozilla.gecko.home.TabMenuStrip android:layout_width="match_parent"
android:layout_height="32dip"
android:layout_height="@dimen/tabs_strip_height"
android:background="@color/background_light"
android:layout_gravity="top"
gecko:strip="@drawable/home_tab_menu_strip"/>

View File

@ -14,7 +14,7 @@
android:background="@android:color/white">
<org.mozilla.gecko.home.HomePagerTabStrip android:layout_width="match_parent"
android:layout_height="40dip"
android:layout_height="@dimen/tabs_strip_height"
android:layout_gravity="top"
android:gravity="center_vertical"
android:background="@color/background_light"

View File

@ -71,9 +71,4 @@
<item name="android:layout_gravity">center</item>
</style>
<style name="Widget.Home.HomeList">
<item name="topDivider">true</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
</resources>

View File

@ -19,11 +19,6 @@
<item name="android:verticalSpacing">20dp</item>
</style>
<style name="Widget.Home.HomeList">
<item name="android:scrollbarStyle">outsideOverlay</item>
<item name="topDivider">true</item>
</style>
<!-- Tabs panel -->
<style name="TabsPanelFrame.RemoteTabs" parent="TabsPanelFrameBase">
<item name="android:paddingLeft">0dp</item>

View File

@ -16,11 +16,6 @@
<item name="android:layout_height">48dip</item>
</style>
<style name="Widget.Home.HomeList">
<item name="android:scrollbarStyle">outsideOverlay</item>
<item name="topDivider">true</item>
</style>
<!-- Tabs panel -->
<style name="TabsPanelFrame.RemoteTabs" parent="TabsPanelFrameBase">
<item name="android:paddingLeft">212dp</item>

View File

@ -105,8 +105,10 @@
<dimen name="tabs_panel_list_padding">16dip</dimen>
<dimen name="tabs_list_divider_height">2dp</dimen>
<dimen name="tabs_sidebar_width">200dp</dimen>
<dimen name="tabs_strip_height">40dp</dimen>
<dimen name="tabs_strip_button_width">100dp</dimen>
<dimen name="tabs_strip_button_padding">18dp</dimen>
<dimen name="tabs_strip_shadow_size">1dp</dimen>
<dimen name="tabs_tray_horizontal_height">156dp</dimen>
<dimen name="text_selection_handle_width">47dp</dimen>
<dimen name="text_selection_handle_height">58dp</dimen>

View File

@ -63,10 +63,6 @@
</style>
<style name="Widget.Home.HomeList">
<item name="android:paddingTop">0dip</item>
<item name="android:paddingRight">0dip</item>
<item name="android:paddingLeft">0dip</item>
<item name="topDivider">true</item>
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
@ -229,7 +225,7 @@
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">32dp</item>
<item name="android:textAppearance">@style/TextAppearance.Widget.Home.Header</item>
<item name="android:background">#fff5f7f9</item>
<item name="android:background">@color/background_light</item>
<item name="android:focusable">false</item>
<item name="android:gravity">center|left</item>
<item name="android:paddingLeft">10dip</item>

View File

@ -465,7 +465,7 @@ var BrowserApp = {
if (this._startupStatus)
this.onAppUpdated();
if (!ParentalControls.isAllowed(ParentalControls.INSTALL_EXTENSIONS)) {
if (!ParentalControls.isAllowed(ParentalControls.INSTALL_EXTENSION)) {
// Disable extension installs
Services.prefs.setIntPref("extensions.enabledScopes", 1);
Services.prefs.setIntPref("extensions.autoDisableScopes", 1);

View File

@ -102,8 +102,13 @@ public class SearchWidget extends AppWidgetProvider {
// Utility to create the view for this widget and attach any event listeners to it
private void addView(final AppWidgetManager manager, final Context context, final int id, final Bundle options) {
final int category = options.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
final boolean isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
final boolean isKeyguard;
if (options != null) {
final int category = options.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
} else {
isKeyguard = false;
}
final RemoteViews views;
if (isKeyguard) {

View File

@ -11,7 +11,7 @@ interface nsIFile;
interface nsIInterfaceRequestor;
interface nsIArray;
[scriptable, uuid(4bde6754-406a-45d1-b18e-dc685adc1db4)]
[scriptable, uuid(e7bcc22c-e9fc-4e7d-88b9-7482399b322d)]
interface nsIParentalControlsService : nsISupports
{
/**
@ -26,6 +26,8 @@ interface nsIParentalControlsService : nsISupports
const short ADD_CONTACT = 7; // Add contacts to the system database
const short SET_IMAGE = 8; // Setting images as wall paper
const short MODIFY_ACCOUNTS = 9; // Modifying system accounts
const short REMOTE_DEBUGGING = 10; // Remote debugging
const short IMPORT_SETTINGS = 11; // Importing settings from other apps
/**
* @returns true if the current user account has parental controls