mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 936756 - Switch locales via pref, not via system locale setting. r=mfinkle,sriram (relanded as one patch)
This commit is contained in:
parent
ddc7ad74e3
commit
c34e10b816
@ -124,7 +124,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
|
|
||||||
private static final int GECKO_TOOLS_MENU = -1;
|
private static final int GECKO_TOOLS_MENU = -1;
|
||||||
private static final int ADDON_MENU_OFFSET = 1000;
|
private static final int ADDON_MENU_OFFSET = 1000;
|
||||||
private class MenuItemInfo {
|
private static class MenuItemInfo {
|
||||||
public int id;
|
public int id;
|
||||||
public String label;
|
public String label;
|
||||||
public String icon;
|
public String icon;
|
||||||
@ -133,6 +133,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
public boolean enabled = true;
|
public boolean enabled = true;
|
||||||
public boolean visible = true;
|
public boolean visible = true;
|
||||||
public int parent;
|
public int parent;
|
||||||
|
public boolean added = false; // So we can re-add after a locale change.
|
||||||
}
|
}
|
||||||
|
|
||||||
// The types of guest mdoe dialogs we show
|
// The types of guest mdoe dialogs we show
|
||||||
@ -1639,6 +1640,20 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
showHomePagerWithAnimator(page, null);
|
showHomePagerWithAnimator(page, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLocaleReady(final String locale) {
|
||||||
|
super.onLocaleReady(locale);
|
||||||
|
if (mHomePager != null) {
|
||||||
|
// Blow it away and rebuild it with the right strings.
|
||||||
|
mHomePager.redisplay(getSupportFragmentManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMenu != null) {
|
||||||
|
mMenu.clear();
|
||||||
|
onCreateOptionsMenu(mMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void showHomePagerWithAnimator(HomePager.Page page, PropertyAnimator animator) {
|
private void showHomePagerWithAnimator(HomePager.Page page, PropertyAnimator animator) {
|
||||||
if (isHomePagerVisible()) {
|
if (isHomePagerVisible()) {
|
||||||
return;
|
return;
|
||||||
@ -1811,7 +1826,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Menu findParentMenu(Menu menu, MenuItem item) {
|
private static Menu findParentMenu(Menu menu, MenuItem item) {
|
||||||
final int itemId = item.getItemId();
|
final int itemId = item.getItemId();
|
||||||
|
|
||||||
final int count = (menu != null) ? menu.size() : 0;
|
final int count = (menu != null) ? menu.size() : 0;
|
||||||
@ -1831,54 +1846,58 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAddonMenuItem(final MenuItemInfo info) {
|
/**
|
||||||
if (mMenu == null) {
|
* Add the provided item to the provided menu, which should be
|
||||||
if (mAddonMenuItemsCache == null)
|
* the root (mMenu).
|
||||||
mAddonMenuItemsCache = new Vector<MenuItemInfo>();
|
*/
|
||||||
|
private void addAddonMenuItemToMenu(final Menu menu, final MenuItemInfo info) {
|
||||||
mAddonMenuItemsCache.add(info);
|
info.added = true;
|
||||||
return;
|
|
||||||
}
|
final Menu destination;
|
||||||
|
|
||||||
Menu menu;
|
|
||||||
if (info.parent == 0) {
|
if (info.parent == 0) {
|
||||||
menu = mMenu;
|
destination = menu;
|
||||||
} else if (info.parent == GECKO_TOOLS_MENU) {
|
} else if (info.parent == GECKO_TOOLS_MENU) {
|
||||||
MenuItem tools = mMenu.findItem(R.id.tools);
|
MenuItem tools = menu.findItem(R.id.tools);
|
||||||
menu = tools != null ? tools.getSubMenu() : mMenu;
|
destination = tools != null ? tools.getSubMenu() : menu;
|
||||||
} else {
|
} else {
|
||||||
MenuItem parent = mMenu.findItem(info.parent);
|
MenuItem parent = menu.findItem(info.parent);
|
||||||
if (parent == null)
|
if (parent == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Menu parentMenu = findParentMenu(mMenu, parent);
|
Menu parentMenu = findParentMenu(menu, parent);
|
||||||
|
|
||||||
if (!parent.hasSubMenu()) {
|
if (!parent.hasSubMenu()) {
|
||||||
parentMenu.removeItem(parent.getItemId());
|
parentMenu.removeItem(parent.getItemId());
|
||||||
menu = parentMenu.addSubMenu(Menu.NONE, parent.getItemId(), Menu.NONE, parent.getTitle());
|
destination = parentMenu.addSubMenu(Menu.NONE, parent.getItemId(), Menu.NONE, parent.getTitle());
|
||||||
if (parent.getIcon() != null)
|
if (parent.getIcon() != null) {
|
||||||
((SubMenu) menu).getItem().setIcon(parent.getIcon());
|
((SubMenu) destination).getItem().setIcon(parent.getIcon());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
menu = parent.getSubMenu();
|
destination = parent.getSubMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem item = menu.add(Menu.NONE, info.id, Menu.NONE, info.label);
|
MenuItem item = destination.add(Menu.NONE, info.id, Menu.NONE, info.label);
|
||||||
|
|
||||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
Log.i(LOGTAG, "menu item clicked");
|
Log.i(LOGTAG, "Menu item clicked");
|
||||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Menu:Clicked", Integer.toString(info.id - ADDON_MENU_OFFSET)));
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Menu:Clicked", Integer.toString(info.id - ADDON_MENU_OFFSET)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (info.icon != null) {
|
if (info.icon == null) {
|
||||||
|
item.setIcon(R.drawable.ic_menu_addons_filler);
|
||||||
|
} else {
|
||||||
final int id = info.id;
|
final int id = info.id;
|
||||||
BitmapUtils.getDrawable(this, info.icon, new BitmapUtils.BitmapLoader() {
|
BitmapUtils.getDrawable(this, info.icon, new BitmapUtils.BitmapLoader() {
|
||||||
@Override
|
@Override
|
||||||
public void onBitmapFound(Drawable d) {
|
public void onBitmapFound(Drawable d) {
|
||||||
MenuItem item = mMenu.findItem(id);
|
// TODO: why do we re-find the item?
|
||||||
|
MenuItem item = destination.findItem(id);
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1889,8 +1908,6 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
item.setIcon(d);
|
item.setIcon(d);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
item.setIcon(R.drawable.ic_menu_addons_filler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item.setCheckable(info.checkable);
|
item.setCheckable(info.checkable);
|
||||||
@ -1899,6 +1916,24 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
item.setVisible(info.visible);
|
item.setVisible(info.visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addAddonMenuItem(final MenuItemInfo info) {
|
||||||
|
if (mAddonMenuItemsCache == null) {
|
||||||
|
mAddonMenuItemsCache = new Vector<MenuItemInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark it as added if the menu was ready.
|
||||||
|
info.added = (mMenu != null);
|
||||||
|
|
||||||
|
// Always cache so we can rebuild after a locale switch.
|
||||||
|
mAddonMenuItemsCache.add(info);
|
||||||
|
|
||||||
|
if (mMenu == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAddonMenuItemToMenu(mMenu, info);
|
||||||
|
}
|
||||||
|
|
||||||
private void removeAddonMenuItem(int id) {
|
private void removeAddonMenuItem(int id) {
|
||||||
// Remove add-on menu item from cache, if available.
|
// Remove add-on menu item from cache, if available.
|
||||||
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
|
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
|
||||||
@ -1928,13 +1963,15 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
item.checked = options.optBoolean("checked", item.checked);
|
item.checked = options.optBoolean("checked", item.checked);
|
||||||
item.enabled = options.optBoolean("enabled", item.enabled);
|
item.enabled = options.optBoolean("enabled", item.enabled);
|
||||||
item.visible = options.optBoolean("visible", item.visible);
|
item.visible = options.optBoolean("visible", item.visible);
|
||||||
|
item.added = (mMenu != null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMenu == null)
|
if (mMenu == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MenuItem menuItem = mMenu.findItem(id);
|
MenuItem menuItem = mMenu.findItem(id);
|
||||||
if (menuItem != null) {
|
if (menuItem != null) {
|
||||||
@ -1948,22 +1985,23 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
// Sets mMenu = menu.
|
||||||
super.onCreateOptionsMenu(menu);
|
super.onCreateOptionsMenu(menu);
|
||||||
|
|
||||||
// Inform the menu about the action-items bar.
|
// Inform the menu about the action-items bar.
|
||||||
if (menu instanceof GeckoMenu && HardwareUtils.isTablet())
|
if (menu instanceof GeckoMenu &&
|
||||||
|
HardwareUtils.isTablet()) {
|
||||||
((GeckoMenu) menu).setActionItemBarPresenter(mBrowserToolbar);
|
((GeckoMenu) menu).setActionItemBarPresenter(mBrowserToolbar);
|
||||||
|
}
|
||||||
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
MenuInflater inflater = getMenuInflater();
|
||||||
inflater.inflate(R.menu.browser_app_menu, mMenu);
|
inflater.inflate(R.menu.browser_app_menu, mMenu);
|
||||||
|
|
||||||
// Add add-on menu items if any.
|
// Add add-on menu items, if any exist.
|
||||||
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
|
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
|
||||||
for (MenuItemInfo item : mAddonMenuItemsCache) {
|
for (MenuItemInfo item : mAddonMenuItemsCache) {
|
||||||
addAddonMenuItem(item);
|
addAddonMenuItemToMenu(mMenu, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAddonMenuItemsCache.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action providers are available only ICS+.
|
// Action providers are available only ICS+.
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
package org.mozilla.gecko;
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||||
import android.content.Context;
|
* 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/. */
|
||||||
|
|
||||||
interface ContextGetter {
|
package org.mozilla.gecko;
|
||||||
Context getContext();
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
public interface ContextGetter {
|
||||||
|
Context getContext();
|
||||||
|
SharedPreferences getSharedPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,15 @@ public class GeckoActivity extends FragmentActivity implements GeckoActivityStat
|
|||||||
// has this activity recently started another Gecko activity?
|
// has this activity recently started another Gecko activity?
|
||||||
private boolean mGeckoActivityOpened = false;
|
private boolean mGeckoActivityOpened = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display any resources that show strings or encompass locale-specific
|
||||||
|
* representations.
|
||||||
|
*
|
||||||
|
* onLocaleReady must always be called on the UI thread.
|
||||||
|
*/
|
||||||
|
public void onLocaleReady(final String locale) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
@ -126,12 +126,18 @@ import java.util.Set;
|
|||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
abstract public class GeckoApp
|
public abstract class GeckoApp
|
||||||
extends GeckoActivity
|
extends GeckoActivity
|
||||||
implements GeckoEventListener, SensorEventListener, LocationListener,
|
implements
|
||||||
Tabs.OnTabsChangedListener, GeckoEventResponder,
|
ContextGetter,
|
||||||
GeckoMenu.Callback, GeckoMenu.MenuPresenter,
|
GeckoAppShell.GeckoInterface,
|
||||||
ContextGetter, GeckoAppShell.GeckoInterface
|
GeckoEventListener,
|
||||||
|
GeckoEventResponder,
|
||||||
|
GeckoMenu.Callback,
|
||||||
|
GeckoMenu.MenuPresenter,
|
||||||
|
LocationListener,
|
||||||
|
SensorEventListener,
|
||||||
|
Tabs.OnTabsChangedListener
|
||||||
{
|
{
|
||||||
private static final String LOGTAG = "GeckoApp";
|
private static final String LOGTAG = "GeckoApp";
|
||||||
|
|
||||||
@ -233,10 +239,20 @@ abstract public class GeckoApp
|
|||||||
|
|
||||||
void focusChrome() { }
|
void focusChrome() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
public Context getContext() {
|
public Context getContext() {
|
||||||
return sAppContext;
|
return sAppContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SharedPreferences getSharedPreferences() {
|
||||||
|
return GeckoApp.getAppSharedPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SharedPreferences getAppSharedPreferences() {
|
||||||
|
return GeckoApp.sAppContext.getSharedPreferences(GeckoApp.PREFS_NAME, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public Activity getActivity() {
|
public Activity getActivity() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -258,10 +274,6 @@ abstract public class GeckoApp
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SharedPreferences getAppSharedPreferences() {
|
|
||||||
return GeckoApp.sAppContext.getSharedPreferences(PREFS_NAME, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getCameraView() {
|
public View getCameraView() {
|
||||||
return mCameraView;
|
return mCameraView;
|
||||||
}
|
}
|
||||||
@ -703,6 +715,8 @@ abstract public class GeckoApp
|
|||||||
GeckoAppShell.openUriExternal(message.optString("url"),
|
GeckoAppShell.openUriExternal(message.optString("url"),
|
||||||
message.optString("mime"), message.optString("packageName"),
|
message.optString("mime"), message.optString("packageName"),
|
||||||
message.optString("className"), message.optString("action"), message.optString("title"));
|
message.optString("className"), message.optString("action"), message.optString("title"));
|
||||||
|
} else if (event.equals("Locale:Set")) {
|
||||||
|
setLocale(message.getString("locale"));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
||||||
@ -1179,7 +1193,7 @@ abstract public class GeckoApp
|
|||||||
}
|
}
|
||||||
|
|
||||||
BrowserDB.initialize(getProfile().getName());
|
BrowserDB.initialize(getProfile().getName());
|
||||||
((GeckoApplication)getApplication()).initialize();
|
((GeckoApplication) getApplication()).initialize();
|
||||||
|
|
||||||
sAppContext = this;
|
sAppContext = this;
|
||||||
GeckoAppShell.setContextGetter(this);
|
GeckoAppShell.setContextGetter(this);
|
||||||
@ -1193,12 +1207,13 @@ abstract public class GeckoApp
|
|||||||
Log.e(LOGTAG, "Exception starting favicon cache. Corrupt resources?", e);
|
Log.e(LOGTAG, "Exception starting favicon cache. Corrupt resources?", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we detect a locale change, we need to restart Gecko, which
|
// Did the OS locale change while we were backgrounded? If so,
|
||||||
// actually means restarting the entire application. This logic should
|
// we need to die so that Gecko will re-init add-ons that touch
|
||||||
// actually be handled elsewhere since GeckoApp may not be alive to
|
// the UI.
|
||||||
// handle this event if "Don't keep activities" is enabled (filed as
|
// This is using a sledgehammer to crack a nut, but it'll do for
|
||||||
// bug 889082).
|
// now.
|
||||||
if (((GeckoApplication)getApplication()).needsRestart()) {
|
if (LocaleManager.systemLocaleDidChange()) {
|
||||||
|
Log.i(LOGTAG, "System locale changed. Restarting.");
|
||||||
doRestart();
|
doRestart();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
return;
|
return;
|
||||||
@ -1279,6 +1294,11 @@ abstract public class GeckoApp
|
|||||||
public void run() {
|
public void run() {
|
||||||
final SharedPreferences prefs = GeckoApp.getAppSharedPreferences();
|
final SharedPreferences prefs = GeckoApp.getAppSharedPreferences();
|
||||||
|
|
||||||
|
// Wait until now to set this, because we'd rather throw an exception than
|
||||||
|
// have a caller of LocaleManager regress startup.
|
||||||
|
LocaleManager.setContextGetter(GeckoApp.this);
|
||||||
|
LocaleManager.initialize();
|
||||||
|
|
||||||
SessionInformation previousSession = SessionInformation.fromSharedPrefs(prefs);
|
SessionInformation previousSession = SessionInformation.fromSharedPrefs(prefs);
|
||||||
if (previousSession.wasKilled()) {
|
if (previousSession.wasKilled()) {
|
||||||
Telemetry.HistogramAdd("FENNEC_WAS_KILLED", 1);
|
Telemetry.HistogramAdd("FENNEC_WAS_KILLED", 1);
|
||||||
@ -1299,17 +1319,29 @@ abstract public class GeckoApp
|
|||||||
final String profilePath = getProfile().getDir().getAbsolutePath();
|
final String profilePath = getProfile().getDir().getAbsolutePath();
|
||||||
final EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher();
|
final EventDispatcher dispatcher = GeckoAppShell.getEventDispatcher();
|
||||||
Log.i(LOGTAG, "Creating BrowserHealthRecorder.");
|
Log.i(LOGTAG, "Creating BrowserHealthRecorder.");
|
||||||
final String osLocale = Locale.getDefault().toString();
|
|
||||||
Log.d(LOGTAG, "Locale is " + osLocale);
|
|
||||||
|
|
||||||
// Replace the duplicate `osLocale` argument when we support switchable
|
final String osLocale = Locale.getDefault().toString();
|
||||||
// application locales.
|
String appLocale = LocaleManager.getAndApplyPersistedLocale();
|
||||||
|
Log.d(LOGTAG, "OS locale is " + osLocale + ", app locale is " + appLocale);
|
||||||
|
|
||||||
|
if (appLocale == null) {
|
||||||
|
appLocale = osLocale;
|
||||||
|
}
|
||||||
|
|
||||||
mHealthRecorder = new BrowserHealthRecorder(GeckoApp.this,
|
mHealthRecorder = new BrowserHealthRecorder(GeckoApp.this,
|
||||||
profilePath,
|
profilePath,
|
||||||
dispatcher,
|
dispatcher,
|
||||||
osLocale,
|
osLocale,
|
||||||
osLocale, // Placeholder.
|
appLocale,
|
||||||
previousSession);
|
previousSession);
|
||||||
|
|
||||||
|
final String uiLocale = appLocale;
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
GeckoApp.this.onLocaleReady(uiLocale);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1317,6 +1349,30 @@ abstract public class GeckoApp
|
|||||||
NotificationHelper.init(getApplicationContext());
|
NotificationHelper.init(getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At this point, the resource system and the rest of the browser are
|
||||||
|
* aware of the locale.
|
||||||
|
*
|
||||||
|
* Now we can display strings!
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onLocaleReady(final String locale) {
|
||||||
|
if (!ThreadUtils.isOnUiThread()) {
|
||||||
|
throw new RuntimeException("onLocaleReady must always be called from the UI thread.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// The URL bar hint needs to be populated.
|
||||||
|
TextView urlBar = (TextView) findViewById(R.id.url_bar_title);
|
||||||
|
if (urlBar == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String hint = getResources().getString(R.string.url_bar_default_text);
|
||||||
|
urlBar.setHint(hint);
|
||||||
|
|
||||||
|
// Allow onConfigurationChanged to take care of the rest.
|
||||||
|
onConfigurationChanged(getResources().getConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
protected void initializeChrome() {
|
protected void initializeChrome() {
|
||||||
mDoorHangerPopup = new DoorHangerPopup(this, null);
|
mDoorHangerPopup = new DoorHangerPopup(this, null);
|
||||||
mPluginContainer = (AbsoluteLayout) findViewById(R.id.plugin_container);
|
mPluginContainer = (AbsoluteLayout) findViewById(R.id.plugin_container);
|
||||||
@ -1526,6 +1582,7 @@ abstract public class GeckoApp
|
|||||||
registerEventListener("Contact:Add");
|
registerEventListener("Contact:Add");
|
||||||
registerEventListener("Intent:Open");
|
registerEventListener("Intent:Open");
|
||||||
registerEventListener("Intent:GetHandlers");
|
registerEventListener("Intent:GetHandlers");
|
||||||
|
registerEventListener("Locale:Set");
|
||||||
|
|
||||||
if (SmsManager.getInstance() != null) {
|
if (SmsManager.getInstance() != null) {
|
||||||
SmsManager.getInstance().start();
|
SmsManager.getInstance().start();
|
||||||
@ -1579,23 +1636,6 @@ abstract public class GeckoApp
|
|||||||
// intervals.
|
// intervals.
|
||||||
GeckoPreferences.broadcastAnnouncementsPref(context);
|
GeckoPreferences.broadcastAnnouncementsPref(context);
|
||||||
GeckoPreferences.broadcastHealthReportUploadPref(context);
|
GeckoPreferences.broadcastHealthReportUploadPref(context);
|
||||||
|
|
||||||
/*
|
|
||||||
XXXX see Bug 635342.
|
|
||||||
We want to disable this code if possible. It is about 145ms in runtime.
|
|
||||||
|
|
||||||
If this code ever becomes live again, you'll need to chain the
|
|
||||||
new locale into BrowserHealthRecorder correctly. See
|
|
||||||
GeckoAppShell.setSelectedLocale.
|
|
||||||
We pass the OS locale into the BHR constructor: we need to grab
|
|
||||||
that *before* we modify the current locale!
|
|
||||||
|
|
||||||
SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
|
|
||||||
String localeCode = settings.getString(getPackageName() + ".locale", "");
|
|
||||||
if (localeCode != null && localeCode.length() > 0)
|
|
||||||
GeckoAppShell.setSelectedLocale(localeCode);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.Launched)) {
|
if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.Launched)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2140,6 +2180,8 @@ abstract public class GeckoApp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
Log.d(LOGTAG, "onConfigurationChanged: " + newConfig.locale);
|
||||||
|
LocaleManager.correctLocale(getResources(), newConfig);
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
|
|
||||||
if (mOrientation != newConfig.orientation) {
|
if (mOrientation != newConfig.orientation) {
|
||||||
@ -2725,4 +2767,52 @@ abstract public class GeckoApp
|
|||||||
}
|
}
|
||||||
return versionCode;
|
return versionCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FHR reason code for a session end prior to a restart for a
|
||||||
|
// locale change.
|
||||||
|
private static final String SESSION_END_LOCALE_CHANGED = "L";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use LocaleManager to change our persisted and current locales,
|
||||||
|
* and poke BrowserHealthRecorder to tell it of our changed state.
|
||||||
|
*/
|
||||||
|
private void setLocale(final String locale) {
|
||||||
|
if (locale == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final String resultant = LocaleManager.setSelectedLocale(locale);
|
||||||
|
if (resultant == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BrowserHealthRecorder rec = mHealthRecorder;
|
||||||
|
if (rec == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean startNewSession = true;
|
||||||
|
final boolean shouldRestart = false;
|
||||||
|
rec.onAppLocaleChanged(resultant);
|
||||||
|
rec.onEnvironmentChanged(startNewSession, SESSION_END_LOCALE_CHANGED);
|
||||||
|
|
||||||
|
if (!shouldRestart) {
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
GeckoApp.this.onLocaleReady(resultant);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do this in the background so that the health recorder has its
|
||||||
|
// time to finish.
|
||||||
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
GeckoApp.this.doRestart();
|
||||||
|
GeckoApp.this.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,8 +229,7 @@ public class GeckoAppShell
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof OutOfMemoryError) {
|
if (e instanceof OutOfMemoryError) {
|
||||||
SharedPreferences prefs =
|
SharedPreferences prefs = getSharedPreferences();
|
||||||
getContext().getSharedPreferences(GeckoApp.PREFS_NAME, 0);
|
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
editor.putBoolean(GeckoApp.PREFS_OOM_EXCEPTION, true);
|
editor.putBoolean(GeckoApp.PREFS_OOM_EXCEPTION, true);
|
||||||
editor.commit();
|
editor.commit();
|
||||||
@ -1587,45 +1586,6 @@ public class GeckoAppShell
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@WrapElementForJNI
|
|
||||||
public static void setSelectedLocale(String localeCode) {
|
|
||||||
/* Bug 713464: This method is still called from Gecko side.
|
|
||||||
Earlier we had an option to run Firefox in a language other than system's language.
|
|
||||||
However, this is not supported as of now.
|
|
||||||
Gecko resets the locale to en-US by calling this function with an empty string.
|
|
||||||
This affects GeckoPreferences activity in multi-locale builds.
|
|
||||||
|
|
||||||
N.B., if this code ever becomes live again, you need to hook it up to locale
|
|
||||||
recording in BrowserHealthRecorder: we track the current app and OS locales
|
|
||||||
as part of the recorded environment.
|
|
||||||
|
|
||||||
See similar note in GeckoApp.java for the startup path.
|
|
||||||
|
|
||||||
//We're not using this, not need to save it (see bug 635342)
|
|
||||||
SharedPreferences settings =
|
|
||||||
getContext().getPreferences(Activity.MODE_PRIVATE);
|
|
||||||
settings.edit().putString(getContext().getPackageName() + ".locale",
|
|
||||||
localeCode).commit();
|
|
||||||
Locale locale;
|
|
||||||
int index;
|
|
||||||
if ((index = localeCode.indexOf('-')) != -1 ||
|
|
||||||
(index = localeCode.indexOf('_')) != -1) {
|
|
||||||
String langCode = localeCode.substring(0, index);
|
|
||||||
String countryCode = localeCode.substring(index + 1);
|
|
||||||
locale = new Locale(langCode, countryCode);
|
|
||||||
} else {
|
|
||||||
locale = new Locale(localeCode);
|
|
||||||
}
|
|
||||||
Locale.setDefault(locale);
|
|
||||||
|
|
||||||
Resources res = getContext().getBaseContext().getResources();
|
|
||||||
Configuration config = res.getConfiguration();
|
|
||||||
config.locale = locale;
|
|
||||||
res.updateConfiguration(config, res.getDisplayMetrics());
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@WrapElementForJNI(stubName = "GetSystemColoursWrapper")
|
@WrapElementForJNI(stubName = "GetSystemColoursWrapper")
|
||||||
public static int[] getSystemColors() {
|
public static int[] getSystemColors() {
|
||||||
// attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h
|
// attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h
|
||||||
@ -2146,6 +2106,13 @@ public class GeckoAppShell
|
|||||||
sContextGetter = cg;
|
sContextGetter = cg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SharedPreferences getSharedPreferences() {
|
||||||
|
if (sContextGetter == null) {
|
||||||
|
throw new IllegalStateException("No ContextGetter; cannot fetch prefs.");
|
||||||
|
}
|
||||||
|
return sContextGetter.getSharedPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
public interface AppStateListener {
|
public interface AppStateListener {
|
||||||
public void onPause();
|
public void onPause();
|
||||||
public void onResume();
|
public void onResume();
|
||||||
|
@ -12,20 +12,39 @@ import org.mozilla.gecko.util.HardwareUtils;
|
|||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.res.Configuration;
|
||||||
import android.content.Context;
|
import android.util.Log;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
|
|
||||||
public class GeckoApplication extends Application {
|
public class GeckoApplication extends Application {
|
||||||
|
|
||||||
private boolean mInited;
|
private boolean mInited;
|
||||||
private boolean mInBackground;
|
private boolean mInBackground;
|
||||||
private boolean mPausedGecko;
|
private boolean mPausedGecko;
|
||||||
private boolean mNeedsRestart;
|
|
||||||
|
|
||||||
private LightweightTheme mLightweightTheme;
|
private LightweightTheme mLightweightTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to do locale work here, because we need to intercept
|
||||||
|
* each hit to onConfigurationChanged.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onConfigurationChanged(Configuration config) {
|
||||||
|
Log.d("GeckoApplication", "onConfigurationChanged: " + config.locale +
|
||||||
|
", background: " + mInBackground);
|
||||||
|
|
||||||
|
// Do nothing if we're in the background. It'll simply cause a loop
|
||||||
|
// (Bug 936756 Comment 11), and it's not necessary.
|
||||||
|
if (mInBackground) {
|
||||||
|
super.onConfigurationChanged(config);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, correct the locale. This catches some cases that GeckoApp
|
||||||
|
// doesn't get a chance to.
|
||||||
|
LocaleManager.correctLocale(getResources(), config);
|
||||||
|
super.onConfigurationChanged(config);
|
||||||
|
}
|
||||||
|
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
if (mInited)
|
if (mInited)
|
||||||
return;
|
return;
|
||||||
@ -43,14 +62,6 @@ public class GeckoApplication extends Application {
|
|||||||
GeckoNetworkManager.getInstance().init(getApplicationContext());
|
GeckoNetworkManager.getInstance().init(getApplicationContext());
|
||||||
MemoryMonitor.getInstance().init(getApplicationContext());
|
MemoryMonitor.getInstance().init(getApplicationContext());
|
||||||
|
|
||||||
BroadcastReceiver receiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
mNeedsRestart = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
registerReceiver(receiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
|
|
||||||
|
|
||||||
mInited = true;
|
mInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,10 +101,6 @@ public class GeckoApplication extends Application {
|
|||||||
mInBackground = false;
|
mInBackground = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean needsRestart() {
|
|
||||||
return mNeedsRestart;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
HardwareUtils.init(getApplicationContext());
|
HardwareUtils.init(getApplicationContext());
|
||||||
|
@ -19,6 +19,7 @@ import org.json.JSONObject;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -30,6 +31,7 @@ import java.util.List;
|
|||||||
public class GeckoView extends LayerView
|
public class GeckoView extends LayerView
|
||||||
implements GeckoEventListener, ContextGetter {
|
implements GeckoEventListener, ContextGetter {
|
||||||
|
|
||||||
|
private static final String DEFAULT_SHARED_PREFERENCES_FILE = "GeckoView";
|
||||||
private static final String LOGTAG = "GeckoView";
|
private static final String LOGTAG = "GeckoView";
|
||||||
|
|
||||||
private ChromeDelegate mChromeDelegate;
|
private ChromeDelegate mChromeDelegate;
|
||||||
@ -305,6 +307,14 @@ public class GeckoView extends LayerView
|
|||||||
return GeckoAppShell.getGeckoInterface();
|
return GeckoAppShell.getGeckoInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getSharedPreferencesFile() {
|
||||||
|
return DEFAULT_SHARED_PREFERENCES_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SharedPreferences getSharedPreferences() {
|
||||||
|
return getContext().getSharedPreferences(getSharedPreferencesFile(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for a browser in the GeckoView container. Associated with a browser
|
* Wrapper for a browser in the GeckoView container. Associated with a browser
|
||||||
* element in the Gecko system.
|
* element in the Gecko system.
|
||||||
|
215
mobile/android/base/LocaleManager.java
Normal file
215
mobile/android/base/LocaleManager.java
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class manages persistence, application, and otherwise handling of
|
||||||
|
* user-specified locales.
|
||||||
|
*
|
||||||
|
* Of note:
|
||||||
|
*
|
||||||
|
* * It's a singleton, because its scope extends to that of the application,
|
||||||
|
* and definitionally all changes to the locale of the app must go through
|
||||||
|
* this.
|
||||||
|
* * It's lazy.
|
||||||
|
* * It has ties into the Gecko event system, because it has to tell Gecko when
|
||||||
|
* to switch locale.
|
||||||
|
* * It relies on using the SharedPreferences file owned by the browser (in
|
||||||
|
* Fennec's case, "GeckoApp") for performance.
|
||||||
|
*/
|
||||||
|
public class LocaleManager {
|
||||||
|
private static final String LOG_TAG = "GeckoLocales";
|
||||||
|
|
||||||
|
// These are both volatile because we don't impose restrictions
|
||||||
|
// over which thread calls our methods.
|
||||||
|
private static volatile ContextGetter getter = null;
|
||||||
|
private static volatile Locale currentLocale = null;
|
||||||
|
|
||||||
|
private static volatile boolean inited = false;
|
||||||
|
private static boolean systemLocaleDidChange = false;
|
||||||
|
private static BroadcastReceiver receiver;
|
||||||
|
|
||||||
|
public static void setContextGetter(ContextGetter getter) {
|
||||||
|
LocaleManager.getter = getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initialize() {
|
||||||
|
if (inited) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
systemLocaleDidChange = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getContext().registerReceiver(receiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean systemLocaleDidChange() {
|
||||||
|
return systemLocaleDidChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Context getContext() {
|
||||||
|
if (getter == null) {
|
||||||
|
throw new IllegalStateException("No ContextGetter; cannot fetch context.");
|
||||||
|
}
|
||||||
|
return getter.getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SharedPreferences getSharedPreferences() {
|
||||||
|
if (getter == null) {
|
||||||
|
throw new IllegalStateException("No ContextGetter; cannot fetch prefs.", new RuntimeException("No prefs."));
|
||||||
|
}
|
||||||
|
return getter.getSharedPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every time the system gives us a new configuration, it
|
||||||
|
* carries the external locale. Fix it.
|
||||||
|
*/
|
||||||
|
public static void correctLocale(Resources res, Configuration config) {
|
||||||
|
Locale current = getCurrentLocale();
|
||||||
|
if (current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I know it's tempting to short-circuit here if the config seems to be
|
||||||
|
// up-to-date, but the rest is necessary.
|
||||||
|
|
||||||
|
config.locale = current;
|
||||||
|
|
||||||
|
// The following two lines are heavily commented in case someone
|
||||||
|
// decides to chase down performance improvements and decides to
|
||||||
|
// question what's going on here.
|
||||||
|
// Both lines should be cheap, *but*...
|
||||||
|
|
||||||
|
// This is unnecessary for basic string choice, but it almost
|
||||||
|
// certainly comes into play when rendering numbers, deciding on RTL,
|
||||||
|
// etc. Take it out if you can prove that's not the case.
|
||||||
|
Locale.setDefault(current);
|
||||||
|
|
||||||
|
// This seems to be a no-op, but every piece of documentation under the
|
||||||
|
// sun suggests that it's necessary, and it certainly makes sense.
|
||||||
|
res.updateConfiguration(config, res.getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Locale parseLocaleCode(final String localeCode) {
|
||||||
|
int index;
|
||||||
|
if ((index = localeCode.indexOf('-')) != -1 ||
|
||||||
|
(index = localeCode.indexOf('_')) != -1) {
|
||||||
|
final String langCode = localeCode.substring(0, index);
|
||||||
|
final String countryCode = localeCode.substring(index + 1);
|
||||||
|
return new Locale(langCode, countryCode);
|
||||||
|
} else {
|
||||||
|
return new Locale(localeCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Locale getCurrentLocale() {
|
||||||
|
if (currentLocale != null) {
|
||||||
|
return currentLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String current = getPersistedLocale();
|
||||||
|
if (current == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return currentLocale = parseLocaleCode(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the persisted locale if it differed from the current.
|
||||||
|
*/
|
||||||
|
public static String updateLocale(String localeCode) {
|
||||||
|
// Fast path.
|
||||||
|
final Locale defaultLocale = Locale.getDefault();
|
||||||
|
if (defaultLocale.toString().equals(localeCode)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Locale locale = parseLocaleCode(localeCode);
|
||||||
|
|
||||||
|
// Fast path.
|
||||||
|
if (defaultLocale.equals(locale)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale.setDefault(locale);
|
||||||
|
currentLocale = locale;
|
||||||
|
|
||||||
|
// Update resources.
|
||||||
|
Resources res = getContext().getResources();
|
||||||
|
Configuration config = res.getConfiguration();
|
||||||
|
config.locale = locale;
|
||||||
|
res.updateConfiguration(config, res.getDisplayMetrics());
|
||||||
|
|
||||||
|
// Tell Gecko.
|
||||||
|
GeckoEvent ev = GeckoEvent.createBroadcastEvent("Locale:Changed", locale.toString());
|
||||||
|
GeckoAppShell.sendEventToGecko(ev);
|
||||||
|
|
||||||
|
return locale.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPrefName() {
|
||||||
|
return getContext().getPackageName() + ".locale";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPersistedLocale() {
|
||||||
|
final SharedPreferences settings = getSharedPreferences();
|
||||||
|
|
||||||
|
// N.B., it is expected that any per-profile settings will be
|
||||||
|
// implemented via SharedPreferences multiplexing in ContextGetter, not
|
||||||
|
// via profile-annotated preference names.
|
||||||
|
final String locale = settings.getString(getPrefName(), "");
|
||||||
|
|
||||||
|
if ("".equals(locale)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void persistLocale(String localeCode) {
|
||||||
|
final SharedPreferences settings = getSharedPreferences();
|
||||||
|
settings.edit().putString(getPrefName(), localeCode).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAndApplyPersistedLocale() {
|
||||||
|
final long t1 = android.os.SystemClock.uptimeMillis();
|
||||||
|
final String localeCode = getPersistedLocale();
|
||||||
|
if (localeCode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLocale(localeCode);
|
||||||
|
final long t2 = android.os.SystemClock.uptimeMillis();
|
||||||
|
Log.i(LOG_TAG, "Locale read and update took: " + (t2 - t1) + "ms.");
|
||||||
|
return localeCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set locale if it changed. Always persists.
|
||||||
|
*/
|
||||||
|
public static String setSelectedLocale(String localeCode) {
|
||||||
|
final String resultant = updateLocale(localeCode);
|
||||||
|
persistLocale(localeCode);
|
||||||
|
return resultant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -319,6 +319,7 @@ public class BrowserHealthRecorder implements GeckoEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onAppLocaleChanged(String to) {
|
public void onAppLocaleChanged(String to) {
|
||||||
|
Log.d(LOG_TAG, "Setting health recorder app locale to " + to);
|
||||||
this.profileCache.beginInitialization();
|
this.profileCache.beginInitialization();
|
||||||
this.profileCache.setAppLocale(to);
|
this.profileCache.setAppLocale(to);
|
||||||
}
|
}
|
||||||
@ -349,10 +350,19 @@ public class BrowserHealthRecorder implements GeckoEventListener {
|
|||||||
* Invoke this method after calls that mutate the environment.
|
* Invoke this method after calls that mutate the environment.
|
||||||
*
|
*
|
||||||
* If this change resulted in a transition between two environments, {@link
|
* If this change resulted in a transition between two environments, {@link
|
||||||
* #onEnvironmentTransition(int, int)} will be invoked on the background
|
* #onEnvironmentTransition(int, int, boolean, String)} will be invoked on the background
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
public synchronized void onEnvironmentChanged() {
|
public synchronized void onEnvironmentChanged() {
|
||||||
|
onEnvironmentChanged(true, "E");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `startNewSession` is false, it means no new session should begin
|
||||||
|
* (e.g., because we're about to restart, and we don't want to create
|
||||||
|
* an orphan).
|
||||||
|
*/
|
||||||
|
public synchronized void onEnvironmentChanged(final boolean startNewSession, final String sessionEndReason) {
|
||||||
final int previousEnv = this.env;
|
final int previousEnv = this.env;
|
||||||
this.env = -1;
|
this.env = -1;
|
||||||
try {
|
try {
|
||||||
@ -374,7 +384,7 @@ public class BrowserHealthRecorder implements GeckoEventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
onEnvironmentTransition(previousEnv, updatedEnv);
|
onEnvironmentTransition(previousEnv, updatedEnv, startNewSession, sessionEndReason);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(LOG_TAG, "Could not record environment transition.", e);
|
Log.w(LOG_TAG, "Could not record environment transition.", e);
|
||||||
}
|
}
|
||||||
@ -643,7 +653,7 @@ public class BrowserHealthRecorder implements GeckoEventListener {
|
|||||||
* Invoked in the background whenever the environment transitions between
|
* Invoked in the background whenever the environment transitions between
|
||||||
* two valid values.
|
* two valid values.
|
||||||
*/
|
*/
|
||||||
protected void onEnvironmentTransition(int prev, int env) {
|
protected void onEnvironmentTransition(int prev, int env, boolean startNewSession, String sessionEndReason) {
|
||||||
if (this.state != State.INITIALIZED) {
|
if (this.state != State.INITIALIZED) {
|
||||||
Log.d(LOG_TAG, "Not initialized: not recording env transition (" + prev + " => " + env + ").");
|
Log.d(LOG_TAG, "Not initialized: not recording env transition (" + prev + " => " + env + ").");
|
||||||
return;
|
return;
|
||||||
@ -652,7 +662,12 @@ public class BrowserHealthRecorder implements GeckoEventListener {
|
|||||||
final SharedPreferences prefs = GeckoApp.getAppSharedPreferences();
|
final SharedPreferences prefs = GeckoApp.getAppSharedPreferences();
|
||||||
final SharedPreferences.Editor editor = prefs.edit();
|
final SharedPreferences.Editor editor = prefs.edit();
|
||||||
|
|
||||||
recordSessionEnd("E", editor, prev);
|
recordSessionEnd(sessionEndReason, editor, prev);
|
||||||
|
|
||||||
|
if (!startNewSession) {
|
||||||
|
editor.commit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final SessionInformation newSession = SessionInformation.forRuntimeTransition();
|
final SessionInformation newSession = SessionInformation.forRuntimeTransition();
|
||||||
setCurrentSession(newSession);
|
setCurrentSession(newSession);
|
||||||
|
@ -129,6 +129,11 @@ public class HomePager extends ViewPager {
|
|||||||
super.addView(child, index, params);
|
super.addView(child, index, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void redisplay(FragmentManager fm) {
|
||||||
|
final TabsAdapter adapter = (TabsAdapter) getAdapter();
|
||||||
|
show(fm, adapter.getCurrentPage(), null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads and initializes the pager.
|
* Loads and initializes the pager.
|
||||||
*
|
*
|
||||||
@ -281,6 +286,12 @@ public class HomePager extends ViewPager {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Page getCurrentPage() {
|
||||||
|
int currentItem = getCurrentItem();
|
||||||
|
TabInfo info = mTabs.get(currentItem);
|
||||||
|
return info.page;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return mTabs.size();
|
return mTabs.size();
|
||||||
|
@ -95,7 +95,7 @@ public class TabMenuStrip extends LinearLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page scroll animates the drawable and it's bounds from the previous to next child view.
|
// Page scroll animates the drawable and its bounds from the previous to next child view.
|
||||||
@Override
|
@Override
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||||
if (mStrip == null) {
|
if (mStrip == null) {
|
||||||
|
@ -10,6 +10,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.ActionProvider;
|
import android.view.ActionProvider;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -114,7 +115,7 @@ public class GeckoMenu extends ListView
|
|||||||
mItems = new ArrayList<GeckoMenuItem>();
|
mItems = new ArrayList<GeckoMenuItem>();
|
||||||
mActionItems = new HashMap<GeckoMenuItem, View>();
|
mActionItems = new HashMap<GeckoMenuItem, View>();
|
||||||
|
|
||||||
mActionItemBarPresenter = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
|
mActionItemBarPresenter = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -219,14 +220,26 @@ public class GeckoMenu extends ListView
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
for (GeckoMenuItem menuItem : mItems) {
|
for (GeckoMenuItem menuItem : mItems) {
|
||||||
if (menuItem.hasSubMenu()) {
|
if (menuItem.hasSubMenu()) {
|
||||||
menuItem.getSubMenu().clear();
|
SubMenu sub = menuItem.getSubMenu();
|
||||||
|
if (sub == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sub.clear();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(LOGTAG, "Couldn't clear submenu.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mAdapter.clear();
|
mAdapter.clear();
|
||||||
|
|
||||||
mItems.clear();
|
mItems.clear();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reinflating the menu will re-add any action items to the toolbar, so
|
||||||
|
* remove the old ones. This also ensures that any text associated with
|
||||||
|
* these is switched to the correct locale.
|
||||||
|
*/
|
||||||
if (mActionItemBarPresenter != null) {
|
if (mActionItemBarPresenter != null) {
|
||||||
for (View item : mActionItems.values()) {
|
for (View item : mActionItems.values()) {
|
||||||
mActionItemBarPresenter.removeActionItem(item);
|
mActionItemBarPresenter.removeActionItem(item);
|
||||||
|
@ -142,7 +142,11 @@ public class GeckoMenuItem implements MenuItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SubMenu getSubMenu() {
|
public SubMenu getSubMenu() {
|
||||||
return mSubMenu;
|
// For consistency with hasSubMenu.
|
||||||
|
if (mActionProvider == null) {
|
||||||
|
return mSubMenu;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -232,6 +232,7 @@ gbjar.sources += [
|
|||||||
'JavaAddonManager.java',
|
'JavaAddonManager.java',
|
||||||
'LightweightTheme.java',
|
'LightweightTheme.java',
|
||||||
'LightweightThemeDrawable.java',
|
'LightweightThemeDrawable.java',
|
||||||
|
'LocaleManager.java',
|
||||||
'MemoryMonitor.java',
|
'MemoryMonitor.java',
|
||||||
'menu/GeckoMenu.java',
|
'menu/GeckoMenu.java',
|
||||||
'menu/GeckoMenuInflater.java',
|
'menu/GeckoMenuInflater.java',
|
||||||
|
@ -104,7 +104,6 @@
|
|||||||
android:textColor="@color/url_bar_title"
|
android:textColor="@color/url_bar_title"
|
||||||
android:textColorHint="@color/url_bar_title_hint"
|
android:textColorHint="@color/url_bar_title_hint"
|
||||||
android:gravity="center_vertical|left"
|
android:gravity="center_vertical|left"
|
||||||
android:hint="@string/url_bar_default_text"
|
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
gecko:autoUpdateTheme="false"/>
|
gecko:autoUpdateTheme="false"/>
|
||||||
|
|
||||||
|
@ -274,6 +274,7 @@ var BrowserApp = {
|
|||||||
|
|
||||||
Services.androidBridge.browserApp = this;
|
Services.androidBridge.browserApp = this;
|
||||||
|
|
||||||
|
Services.obs.addObserver(this, "Locale:Changed", false);
|
||||||
Services.obs.addObserver(this, "Tab:Load", false);
|
Services.obs.addObserver(this, "Tab:Load", false);
|
||||||
Services.obs.addObserver(this, "Tab:Selected", false);
|
Services.obs.addObserver(this, "Tab:Selected", false);
|
||||||
Services.obs.addObserver(this, "Tab:Closed", false);
|
Services.obs.addObserver(this, "Tab:Closed", false);
|
||||||
@ -410,6 +411,14 @@ var BrowserApp = {
|
|||||||
return "";
|
return "";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass this a locale string, such as "fr" or "es_ES".
|
||||||
|
*/
|
||||||
|
setLocale: function (locale) {
|
||||||
|
console.log("browser.js: requesting locale set: " + locale);
|
||||||
|
sendMessageToJava({ type: "Locale:Set", locale: locale });
|
||||||
|
},
|
||||||
|
|
||||||
initContextMenu: function ba_initContextMenu() {
|
initContextMenu: function ba_initContextMenu() {
|
||||||
// TODO: These should eventually move into more appropriate classes
|
// TODO: These should eventually move into more appropriate classes
|
||||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.openInNewTab"),
|
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.openInNewTab"),
|
||||||
@ -1496,6 +1505,13 @@ var BrowserApp = {
|
|||||||
this.notifyPrefObservers(aData);
|
this.notifyPrefObservers(aData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "Locale:Changed":
|
||||||
|
// TODO: do we need to be more nuanced here -- e.g., checking for the
|
||||||
|
// OS locale -- or should it always be false on Fennec?
|
||||||
|
Services.prefs.setBoolPref("intl.locale.matchOS", false);
|
||||||
|
Services.prefs.setCharPref("general.useragent.locale", aData);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dump('BrowserApp.observe: unexpected topic "' + aTopic + '"\n');
|
dump('BrowserApp.observe: unexpected topic "' + aTopic + '"\n');
|
||||||
break;
|
break;
|
||||||
|
@ -77,7 +77,6 @@ jmethodID GeckoAppShell::jScheduleRestart = 0;
|
|||||||
jmethodID GeckoAppShell::jSendMessageWrapper = 0;
|
jmethodID GeckoAppShell::jSendMessageWrapper = 0;
|
||||||
jmethodID GeckoAppShell::jSetFullScreen = 0;
|
jmethodID GeckoAppShell::jSetFullScreen = 0;
|
||||||
jmethodID GeckoAppShell::jSetKeepScreenOn = 0;
|
jmethodID GeckoAppShell::jSetKeepScreenOn = 0;
|
||||||
jmethodID GeckoAppShell::jSetSelectedLocale = 0;
|
|
||||||
jmethodID GeckoAppShell::jSetURITitle = 0;
|
jmethodID GeckoAppShell::jSetURITitle = 0;
|
||||||
jmethodID GeckoAppShell::jShowAlertNotificationWrapper = 0;
|
jmethodID GeckoAppShell::jShowAlertNotificationWrapper = 0;
|
||||||
jmethodID GeckoAppShell::jShowFilePickerAsyncWrapper = 0;
|
jmethodID GeckoAppShell::jShowFilePickerAsyncWrapper = 0;
|
||||||
@ -158,7 +157,6 @@ void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
|
|||||||
jSendMessageWrapper = getStaticMethod("sendMessage", "(Ljava/lang/String;Ljava/lang/String;I)V");
|
jSendMessageWrapper = getStaticMethod("sendMessage", "(Ljava/lang/String;Ljava/lang/String;I)V");
|
||||||
jSetFullScreen = getStaticMethod("setFullScreen", "(Z)V");
|
jSetFullScreen = getStaticMethod("setFullScreen", "(Z)V");
|
||||||
jSetKeepScreenOn = getStaticMethod("setKeepScreenOn", "(Z)V");
|
jSetKeepScreenOn = getStaticMethod("setKeepScreenOn", "(Z)V");
|
||||||
jSetSelectedLocale = getStaticMethod("setSelectedLocale", "(Ljava/lang/String;)V");
|
|
||||||
jSetURITitle = getStaticMethod("setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
|
jSetURITitle = getStaticMethod("setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||||
jShowAlertNotificationWrapper = getStaticMethod("showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
jShowAlertNotificationWrapper = getStaticMethod("showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||||
jShowFilePickerAsyncWrapper = getStaticMethod("showFilePickerAsync", "(Ljava/lang/String;J)V");
|
jShowFilePickerAsyncWrapper = getStaticMethod("showFilePickerAsync", "(Ljava/lang/String;J)V");
|
||||||
@ -2055,35 +2053,6 @@ void GeckoAppShell::SetKeepScreenOn(bool a0) {
|
|||||||
env->PopLocalFrame(NULL);
|
env->PopLocalFrame(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeckoAppShell::SetSelectedLocale(const nsAString& a0) {
|
|
||||||
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
|
||||||
if (!env) {
|
|
||||||
ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env->PushLocalFrame(1) != 0) {
|
|
||||||
ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__);
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring j0 = AndroidBridge::NewJavaString(env, a0);
|
|
||||||
|
|
||||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jSetSelectedLocale, j0);
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__);
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
env->PopLocalFrame(NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->PopLocalFrame(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeckoAppShell::SetURITitle(const nsAString& a0, const nsAString& a1) {
|
void GeckoAppShell::SetURITitle(const nsAString& a0, const nsAString& a1) {
|
||||||
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
||||||
if (!env) {
|
if (!env) {
|
||||||
|
@ -84,7 +84,6 @@ public:
|
|||||||
static void SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2);
|
static void SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2);
|
||||||
static void SetFullScreen(bool a0);
|
static void SetFullScreen(bool a0);
|
||||||
static void SetKeepScreenOn(bool a0);
|
static void SetKeepScreenOn(bool a0);
|
||||||
static void SetSelectedLocale(const nsAString& a0);
|
|
||||||
static void SetURITitle(const nsAString& a0, const nsAString& a1);
|
static void SetURITitle(const nsAString& a0, const nsAString& a1);
|
||||||
static void ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4);
|
static void ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4);
|
||||||
static void ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1);
|
static void ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1);
|
||||||
|
@ -163,12 +163,8 @@ nsAppShell::NotifyNativeEvent()
|
|||||||
mQueueCond.Notify();
|
mQueueCond.Notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PREFNAME_MATCH_OS "intl.locale.matchOS"
|
|
||||||
#define PREFNAME_UA_LOCALE "general.useragent.locale"
|
|
||||||
#define PREFNAME_COALESCE_TOUCHES "dom.event.touch.coalescing.enabled"
|
#define PREFNAME_COALESCE_TOUCHES "dom.event.touch.coalescing.enabled"
|
||||||
static const char* kObservedPrefs[] = {
|
static const char* kObservedPrefs[] = {
|
||||||
PREFNAME_MATCH_OS,
|
|
||||||
PREFNAME_UA_LOCALE,
|
|
||||||
PREFNAME_COALESCE_TOUCHES,
|
PREFNAME_COALESCE_TOUCHES,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
@ -182,8 +178,6 @@ nsAppShell::Init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsresult rv = nsBaseAppShell::Init();
|
nsresult rv = nsBaseAppShell::Init();
|
||||||
AndroidBridge* bridge = AndroidBridge::Bridge();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIObserverService> obsServ =
|
nsCOMPtr<nsIObserverService> obsServ =
|
||||||
mozilla::services::GetObserverService();
|
mozilla::services::GetObserverService();
|
||||||
if (obsServ) {
|
if (obsServ) {
|
||||||
@ -193,27 +187,7 @@ nsAppShell::Init()
|
|||||||
if (sPowerManagerService)
|
if (sPowerManagerService)
|
||||||
sPowerManagerService->AddWakeLockListener(sWakeLockListener);
|
sPowerManagerService->AddWakeLockListener(sWakeLockListener);
|
||||||
|
|
||||||
if (!bridge)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
Preferences::AddStrongObservers(this, kObservedPrefs);
|
Preferences::AddStrongObservers(this, kObservedPrefs);
|
||||||
|
|
||||||
bool match;
|
|
||||||
rv = Preferences::GetBool(PREFNAME_MATCH_OS, &match);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
GeckoAppShell::SetSelectedLocale(EmptyString());
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString locale;
|
|
||||||
rv = Preferences::GetLocalizedString(PREFNAME_UA_LOCALE, &locale);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
rv = Preferences::GetString(PREFNAME_UA_LOCALE, &locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
GeckoAppShell::SetSelectedLocale(locale);
|
|
||||||
mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
|
mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -228,30 +202,9 @@ nsAppShell::Observe(nsISupports* aSubject,
|
|||||||
// or we'll see crashes, as the app shell outlives XPConnect.
|
// or we'll see crashes, as the app shell outlives XPConnect.
|
||||||
mObserversHash.Clear();
|
mObserversHash.Clear();
|
||||||
return nsBaseAppShell::Observe(aSubject, aTopic, aData);
|
return nsBaseAppShell::Observe(aSubject, aTopic, aData);
|
||||||
} else if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && aData && (
|
} else if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) &&
|
||||||
nsDependentString(aData).Equals(
|
aData &&
|
||||||
NS_LITERAL_STRING(PREFNAME_UA_LOCALE)) ||
|
nsDependentString(aData).Equals(NS_LITERAL_STRING(PREFNAME_COALESCE_TOUCHES))) {
|
||||||
nsDependentString(aData).Equals(
|
|
||||||
NS_LITERAL_STRING(PREFNAME_COALESCE_TOUCHES)) ||
|
|
||||||
nsDependentString(aData).Equals(
|
|
||||||
NS_LITERAL_STRING(PREFNAME_MATCH_OS)))) {
|
|
||||||
bool match;
|
|
||||||
nsresult rv = Preferences::GetBool(PREFNAME_MATCH_OS, &match);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
GeckoAppShell::SetSelectedLocale(EmptyString());
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString locale;
|
|
||||||
if (NS_FAILED(Preferences::GetLocalizedString(PREFNAME_UA_LOCALE,
|
|
||||||
&locale))) {
|
|
||||||
locale = Preferences::GetString(PREFNAME_UA_LOCALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GeckoAppShell::SetSelectedLocale(locale);
|
|
||||||
|
|
||||||
mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
|
mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user