Bug 1029646 - Update layout direction of configuration and DecorView, r=sebastian
MozReview-Commit-ID: FiDwoX45yV9
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserLocaleManager.java
@@ -21,16 +21,17 @@ import org.mozilla.gecko.util.GeckoJarRe
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.os.Build;
import android.util.Log;
/**
* This class manages persistence, application, and otherwise handling of
* user-specified locales.
*
* Of note:
*
@@ -290,16 +291,21 @@ public class BrowserLocaleManager implem
@Override
public void updateConfiguration(Context context, Locale locale) {
Resources res = context.getResources();
Configuration config = res.getConfiguration();
// We should use setLocale, but it's unexpectedly missing
// on real devices.
config.locale = locale;
+ // LayoutDirection is also updated in setLocale, do this manually.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ config.setLayoutDirection(locale);
+ }
+
res.updateConfiguration(config, null);
}
private SharedPreferences getSharedPreferences(Context context) {
return GeckoSharedPrefs.forApp(context);
}
/**
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -105,16 +105,17 @@ import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import org.mozilla.gecko.util.ViewUtil;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.ArrayList;
@@ -1444,16 +1445,19 @@ public abstract class GeckoApp
if (!ThreadUtils.isOnUiThread()) {
throw new RuntimeException("onLocaleReady must always be called from the UI thread.");
}
final Locale loc = Locales.parseLocaleCode(locale);
if (loc.equals(mLastLocale)) {
Log.d(LOGTAG, "New locale same as old; onLocaleReady has nothing to do.");
}
+ BrowserLocaleManager.getInstance().updateConfiguration(GeckoApp.this, loc);
+ ViewUtil.setLayoutDirection(getWindow().getDecorView(), loc);
+ refreshChrome();
// The URL bar hint needs to be populated.
TextView urlBar = (TextView) findViewById(R.id.url_bar_title);
if (urlBar != null) {
final String hint = getResources().getString(R.string.url_bar_default_text);
urlBar.setHint(hint);
} else {
Log.d(LOGTAG, "No URL bar in GeckoApp. Not loading localized hint string.");
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -45,16 +45,17 @@ import org.mozilla.gecko.updater.UpdateS
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.ContextUtils;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.InputOptionsUtils;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.ThreadUtils;
+import org.mozilla.gecko.util.ViewUtil;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.NotificationManager;
import android.content.ContentResolver;
@@ -75,22 +76,26 @@ import android.preference.Preference.OnP
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.SwitchPreference;
import android.preference.TwoStatePreference;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.text.TextUtilsCompat;
+import android.support.v4.view.ViewCompat;
import android.support.v7.app.ActionBar;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
@@ -257,16 +262,24 @@ public class GeckoPreferences
setTitle(title);
}
}
private void onLocaleChanged(Locale newLocale) {
Log.d(LOGTAG, "onLocaleChanged: " + newLocale);
BrowserLocaleManager.getInstance().updateConfiguration(getApplicationContext(), newLocale);
+ // If activity is not recreated, also update locale to current activity configuration
+ BrowserLocaleManager.getInstance().updateConfiguration(GeckoPreferences.this, newLocale);
+ ViewUtil.setLayoutDirection(getWindow().getDecorView(), newLocale);
+
+ // Force update navigate up icon by current layout direction
+ final ActionBar actionBar = getSupportActionBar();
+ actionBar.setHomeAsUpIndicator(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_mtrl_am_alpha);
+
this.lastLocale = newLocale;
if (isMultiPane()) {
// This takes care of the left pane.
invalidateHeaders();
// Detach and reattach the current prefs pane so that it
// reflects the new locale.
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
@@ -354,16 +354,17 @@ public abstract class BrowserToolbar ext
this.progressBar = progressBar;
}
public void setTabHistoryController(TabHistoryController tabHistoryController) {
this.tabHistoryController = tabHistoryController;
}
public void refresh() {
+ progressBar.setImageDrawable(getResources().getDrawable(R.drawable.progress));
urlDisplayLayout.dismissSiteIdentityPopup();
}
public boolean onBackPressed() {
// If we exit editing mode during the animation,
// we're put into an inconsistent state (bug 1017276).
if (isEditing() && !isAnimating()) {
Telemetry.sendUIEvent(TelemetryContract.Event.CANCEL,
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarTabletBase.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarTabletBase.java
@@ -123,16 +123,23 @@ abstract class BrowserToolbarTabletBase
@Override
protected void updateNavigationButtons(final Tab tab) {
backButton.setEnabled(canDoBack(tab));
animateForwardButton(
canDoForward(tab) ? ForwardButtonAnimation.SHOW : ForwardButtonAnimation.HIDE);
}
@Override
+ public void refresh() {
+ super.refresh();
+ forwardButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_menu_forward));
+ backButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_menu_back));
+ }
+
+ @Override
public void setNextFocusDownId(int nextId) {
super.setNextFocusDownId(nextId);
backButton.setNextFocusDownId(nextId);
forwardButton.setNextFocusDownId(nextId);
}
@Override
public void setPrivateMode(final boolean isPrivate) {
--- a/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
@@ -1,23 +1,27 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
import android.content.res.TypedArray;
import android.os.Build;
+import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.MarginLayoutParamsCompat;
+import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.R;
+import java.util.Locale;
+
public class ViewUtil {
/**
* Enable a circular touch ripple for a given view. This is intended for borderless views,
* such as (3-dot) menu buttons.
*
* Because of platform limitations a square ripple is used on Android 4.
*/
@@ -46,9 +50,26 @@ public class ViewUtil {
layoutParams.rightMargin = marginStart;
} else {
layoutParams.leftMargin = marginStart;
}
} else {
MarginLayoutParamsCompat.setMarginStart(layoutParams, marginStart);
}
}
+
+ /**
+ * Force set layout direction to RTL or LTR by Locale.
+ * @param view
+ * @param locale
+ */
+ public static void setLayoutDirection(View view, Locale locale) {
+ switch (TextUtilsCompat.getLayoutDirectionFromLocale(locale)) {
+ case ViewCompat.LAYOUT_DIRECTION_RTL:
+ ViewCompat.setLayoutDirection(view, ViewCompat.LAYOUT_DIRECTION_RTL);
+ break;
+ case ViewCompat.LAYOUT_DIRECTION_LTR:
+ default:
+ ViewCompat.setLayoutDirection(view, ViewCompat.LAYOUT_DIRECTION_LTR);
+ break;
+ }
+ }
}