Bug 1319302 - RTL support for Firefox for Android, r=sebastian
authormaliu <max@mxli.us>
Fri, 11 Nov 2016 16:10:21 +0800
changeset 443527 120c84ca53629202c22cce565053fee7973eea72
parent 443526 085baebf9e4aebb4e57d5088df9152c490232806
child 443528 36a118cbe8155070604735f80e81088ce1df7828
push id37019
push userbmo:jsnajdr@gmail.com
push dateThu, 24 Nov 2016 16:10:05 +0000
reviewerssebastian
bugs1319302
milestone53.0a1
Bug 1319302 - RTL support for Firefox for Android, r=sebastian MozReview-Commit-ID: bKzW07YBDy
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/java/org/mozilla/gecko/SnackbarBuilder.java
mobile/android/base/java/org/mozilla/gecko/home/CombinedHistoryItem.java
mobile/android/base/java/org/mozilla/gecko/home/TabMenuStripLayout.java
mobile/android/base/java/org/mozilla/gecko/home/TopSitesGridItemView.java
mobile/android/base/java/org/mozilla/gecko/home/TwoLinePageRow.java
mobile/android/base/java/org/mozilla/gecko/menu/MenuItemActionBar.java
mobile/android/base/java/org/mozilla/gecko/menu/MenuItemDefault.java
mobile/android/base/java/org/mozilla/gecko/preferences/AlignRightLinkPreference.java
mobile/android/base/java/org/mozilla/gecko/prompts/PromptListAdapter.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabPanelBackButton.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarPhoneBase.java
mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarTablet.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ForwardButton.java
mobile/android/base/java/org/mozilla/gecko/toolbar/NavButton.java
mobile/android/base/java/org/mozilla/gecko/toolbar/PhoneTabsButton.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButton.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButtonFrameLayout.java
mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarProgressView.java
mobile/android/base/java/org/mozilla/gecko/widget/BasicColorPicker.java
mobile/android/base/java/org/mozilla/gecko/widget/DoorHanger.java
mobile/android/base/java/org/mozilla/gecko/widget/FadedSingleColorTextView.java
mobile/android/base/resources/drawable/url_bar_translating_edge.xml
mobile/android/base/resources/layout-large-v11/browser_toolbar.xml
mobile/android/base/resources/layout/activity_stream_card_history_item.xml
mobile/android/base/resources/layout/activity_stream_topsites_card.xml
mobile/android/base/resources/layout/bookmark_folder_row.xml
mobile/android/base/resources/layout/browser_toolbar.xml
mobile/android/base/resources/layout/default_doorhanger.xml
mobile/android/base/resources/layout/find_in_page_content.xml
mobile/android/base/resources/layout/home_combined_back_item.xml
mobile/android/base/resources/layout/list_item_header.xml
mobile/android/base/resources/layout/panel_back_item.xml
mobile/android/base/resources/layout/pin_site_dialog.xml
mobile/android/base/resources/layout/preference_rightalign_icon.xml
mobile/android/base/resources/layout/search_activity_main.xml
mobile/android/base/resources/layout/search_bar.xml
mobile/android/base/resources/layout/search_history_row.xml
mobile/android/base/resources/layout/search_suggestions_row.xml
mobile/android/base/resources/layout/site_setting_item.xml
mobile/android/base/resources/layout/tab_history_item_row.xml
mobile/android/base/resources/layout/tab_menu_strip.xml
mobile/android/base/resources/layout/tab_strip_item.xml
mobile/android/base/resources/layout/tab_strip_item_view.xml
mobile/android/base/resources/layout/toolbar_display_layout.xml
mobile/android/base/resources/layout/toolbar_edit_layout.xml
mobile/android/base/resources/layout/tracking_protection_prompt.xml
mobile/android/base/resources/layout/two_line_folder_row.xml
mobile/android/base/resources/layout/two_line_page_row.xml
mobile/android/base/resources/values-large/dimens.xml
mobile/android/base/resources/values/dimens.xml
mobile/android/search/java/org/mozilla/search/autocomplete/SearchBar.java
mobile/android/services/src/main/res/layout/homescreen_prompt.xml
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -22,16 +22,17 @@
      fileincluded here, so that they can be referenced by both APKs. -->
 #include FennecManifest_permissions.xml.in
 
     <application android:label="@string/moz_app_displayname"
                  android:icon="@drawable/icon"
                  android:logo="@drawable/logo"
                  android:name="@MOZ_ANDROID_APPLICATION_CLASS@"
                  android:hardwareAccelerated="true"
+                 android:supportsRtl="true"
                  android:allowBackup="false"
 # The preprocessor does not yet support arbitrary parentheses, so this cannot
 # be parenthesized thus to clarify that the logical AND operator has precedence:
 #   !defined(MOZILLA_OFFICIAL) || (defined(NIGHTLY_BUILD) && defined(MOZ_DEBUG))
 #if !defined(MOZILLA_OFFICIAL) || defined(NIGHTLY_BUILD) && defined(MOZ_DEBUG)
                  android:debuggable="true">
 #else
                  android:debuggable="false">
--- a/mobile/android/base/java/org/mozilla/gecko/SnackbarBuilder.java
+++ b/mobile/android/base/java/org/mozilla/gecko/SnackbarBuilder.java
@@ -10,16 +10,17 @@ import org.mozilla.gecko.util.NativeJSOb
 
 import android.app.Activity;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.InsetDrawable;
 import android.support.annotation.StringRes;
 import android.support.design.widget.Snackbar;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.View;
 import android.widget.TextView;
 
 import java.lang.ref.WeakReference;
 
@@ -209,17 +210,17 @@ public class SnackbarBuilder {
         if (icon != null) {
             int leftPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, activity.getResources().getDisplayMetrics());
 
             final InsetDrawable paddedIcon = new InsetDrawable(icon, 0, 0, leftPadding, 0);
 
             paddedIcon.setBounds(0, 0, leftPadding + icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
 
             TextView textView = (TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
-            textView.setCompoundDrawables(paddedIcon, null, null, null);
+            TextViewCompat.setCompoundDrawablesRelative(textView, paddedIcon, null, null, null);
         }
 
         if (backgroundColor != null) {
             snackbar.getView().setBackgroundColor(backgroundColor);
         }
 
         snackbar.show();
 
--- a/mobile/android/base/java/org/mozilla/gecko/home/CombinedHistoryItem.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/CombinedHistoryItem.java
@@ -1,17 +1,19 @@
 /* -*- 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.home;
 
 import android.content.Context;
 import android.database.Cursor;
+import android.graphics.drawable.Drawable;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.db.RemoteClient;
 import org.mozilla.gecko.db.RemoteTab;
@@ -116,12 +118,16 @@ public abstract class CombinedHistoryIte
                 deviceTypeView.setImageResource(isCollapsed ? R.drawable.sync_desktop_inactive : R.drawable.sync_desktop);
             } else {
                 deviceTypeView.setImageResource(isCollapsed ? R.drawable.sync_mobile_inactive : R.drawable.sync_mobile);
             }
 
             nameView.setTextColor(ContextCompat.getColor(context, isCollapsed ? R.color.tabs_tray_icon_grey : R.color.placeholder_active_grey));
             if (client.tabs.size() > 0) {
                 deviceExpanded.setImageResource(isCollapsed ? R.drawable.home_group_collapsed : R.drawable.arrow_down);
+                Drawable expandedDrawable = deviceExpanded.getDrawable();
+                if (expandedDrawable != null) {
+                    DrawableCompat.setAutoMirrored(expandedDrawable, true);
+                }
             }
         }
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/home/TabMenuStripLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/TabMenuStripLayout.java
@@ -1,15 +1,16 @@
 /* -*- 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.home;
 
+import android.support.v4.view.ViewCompat;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 import android.content.res.ColorStateList;
 import org.mozilla.gecko.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -74,20 +75,23 @@ class TabMenuStripLayout extends LinearL
         // Set titles width to weight, or wrap text width.
         if (titlebarFill) {
             button.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f));
         } else {
             button.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
         }
 
         if (getChildCount() == 0) {
-            button.setPadding(button.getPaddingLeft() + tabContentStart,
-                              button.getPaddingTop(),
-                              button.getPaddingRight(),
-                              button.getPaddingBottom());
+
+            ViewCompat.setPaddingRelative(button,
+                    ViewCompat.getPaddingStart(button) + tabContentStart,
+                    button.getPaddingTop(),
+                    ViewCompat.getPaddingEnd(button),
+                    button.getPaddingBottom()
+            );
         }
 
         addView(button);
         button.setOnClickListener(new ViewClickListener(getChildCount() - 1));
         button.setOnFocusChangeListener(this);
     }
 
     void onPageSelected(final int position) {
@@ -102,19 +106,35 @@ class TabMenuStripLayout extends LinearL
         ViewTreeObserver vto = selectedView.getViewTreeObserver();
         if (vto.isAlive()) {
             vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                 @Override
                 public void onGlobalLayout() {
                     selectedView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
 
                     if (strip != null) {
-                        strip.setBounds(selectedView.getLeft() + (position == 0 ? tabContentStart : 0),
+                        boolean isLayoutRtl = ViewCompat.getLayoutDirection(selectedView) == ViewCompat.LAYOUT_DIRECTION_RTL;
+                        final int startPaddingOffset;
+                        final int endPaddingOffset;
+                        if (position != 0) {
+                            startPaddingOffset = 0;
+                            endPaddingOffset = 0;
+                        } else {
+                            if (isLayoutRtl) {
+                                startPaddingOffset = 0;
+                                endPaddingOffset = -tabContentStart;
+                            } else {
+                                startPaddingOffset = tabContentStart;
+                                endPaddingOffset = 0;
+                            }
+                        }
+
+                        strip.setBounds(selectedView.getLeft() + startPaddingOffset,
                                         selectedView.getTop(),
-                                        selectedView.getRight(),
+                                        selectedView.getRight() + endPaddingOffset,
                                         selectedView.getBottom());
                     }
 
                     prevProgress = position;
                 }
             });
         }
     }
@@ -147,19 +167,21 @@ class TabMenuStripLayout extends LinearL
         } else if (fromPosition == 1 && toPosition == 0) {
             // Slowly add extra padding (tabContentStart) based on scroll progress
             modifier = (int) (tabContentStart * progress);
         } else {
             // We are not scrolling tab 0 in any way, no modifier needed
             modifier = 0;
         }
 
-        strip.setBounds((int) (fromTabLeft + ((toTabLeft - fromTabLeft) * progress)) + modifier,
+        boolean isLayoutRtl = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
+        strip.setBounds(
+                (int) (fromTabLeft + ((toTabLeft - fromTabLeft) * progress)) + (isLayoutRtl ? 0 : modifier),
                 0,
-                (int) (fromTabRight + ((toTabRight - fromTabRight) * progress)),
+                (int) (fromTabRight + ((toTabRight - fromTabRight) * progress)) + (isLayoutRtl ? -modifier : 0),
                 getHeight());
         invalidate();
     }
 
     /*
      * position + positionOffset goes from 0 to 2 as we scroll from page 1 to 3.
      * Normalized progress is relative to the the direction the page is being scrolled towards.
      * For this, we maintain direction of scroll with a state, and the child view we are moving towards and away from.
--- a/mobile/android/base/java/org/mozilla/gecko/home/TopSitesGridItemView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/TopSitesGridItemView.java
@@ -2,16 +2,17 @@
  * 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.home;
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.support.v4.widget.TextViewCompat;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.widget.ImageView.ScaleType;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import org.mozilla.gecko.R;
@@ -272,17 +273,17 @@ public class TopSitesGridItemView extend
         if (mType == type) {
             return false;
         }
 
         mType = type;
         refreshDrawableState();
 
         int pinResourceId = (type == TopSites.TYPE_PINNED ? R.drawable.pin : 0);
-        mTitleView.setCompoundDrawablesWithIntrinsicBounds(pinResourceId, 0, 0, 0);
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTitleView, pinResourceId, 0, 0, 0);
 
         return true;
     }
 
     /**
      * Update the title shown by this view. If both title and url
      * are empty, mark the state as STATE_EMPTY and show a default text.
      */
--- a/mobile/android/base/java/org/mozilla/gecko/home/TwoLinePageRow.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/TwoLinePageRow.java
@@ -5,16 +5,20 @@
 
 package org.mozilla.gecko.home;
 
 import java.lang.ref.WeakReference;
 import java.util.concurrent.Future;
 
 import android.content.Context;
 import android.database.Cursor;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -61,17 +65,17 @@ public class TwoLinePageRow extends Line
 
     public TwoLinePageRow(Context context, AttributeSet attrs) {
         super(context, attrs);
 
         setGravity(Gravity.CENTER_VERTICAL);
 
         LayoutInflater.from(context).inflate(R.layout.two_line_page_row, this);
         // Merge layouts lose their padding, so set it dynamically.
-        setPadding(0, 0, (int) getResources().getDimension(R.dimen.page_row_edge_padding), 0);
+        ViewCompat.setPaddingRelative(this, 0, 0, (int) getResources().getDimension(R.dimen.page_row_edge_padding), 0);
 
         mTitle = (TextView) findViewById(R.id.title);
         mUrl = (TextView) findViewById(R.id.url);
         mStatusIcon = (ImageView) findViewById(R.id.status_icon_bookmark);
 
         mSwitchToTabIconId = NO_ICON;
         mShowIcons = true;
 
@@ -158,17 +162,20 @@ public class TwoLinePageRow extends Line
     }
 
     protected void setSwitchToTabIcon(int iconId) {
         if (mSwitchToTabIconId == iconId) {
             return;
         }
 
         mSwitchToTabIconId = iconId;
-        mUrl.setCompoundDrawablesWithIntrinsicBounds(mSwitchToTabIconId, 0, 0, 0);
+        if (mSwitchToTabIconId != 0) {
+            DrawableCompat.setAutoMirrored(ActivityCompat.getDrawable(getContext(), mSwitchToTabIconId), true);
+        }
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mUrl, mSwitchToTabIconId, 0, 0, 0);
     }
 
     private void updateStatusIcon(boolean isBookmark, boolean isReaderItem) {
         if (isReaderItem) {
             mStatusIcon.setImageResource(R.drawable.status_icon_readercache);
         } else if (isBookmark) {
             mStatusIcon.setImageResource(R.drawable.star_blue);
         }
--- a/mobile/android/base/java/org/mozilla/gecko/menu/MenuItemActionBar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/menu/MenuItemActionBar.java
@@ -5,16 +5,17 @@
 package org.mozilla.gecko.menu;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.util.ResourceDrawableUtils;
 import org.mozilla.gecko.widget.themed.ThemedImageButton;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
 import android.util.AttributeSet;
 
 public class MenuItemActionBar extends ThemedImageButton
                                implements GeckoMenuItem.Layout {
     private static final String LOGTAG = "GeckoMenuItemActionBar";
 
     public MenuItemActionBar(Context context) {
         this(context, null);
@@ -41,16 +42,20 @@ public class MenuItemActionBar extends T
 
     void setIcon(Drawable icon) {
         if (icon == null) {
             setVisibility(GONE);
         } else {
             setVisibility(VISIBLE);
             setImageDrawable(icon);
         }
+        icon = getDrawable();
+        if (icon != null) {
+            DrawableCompat.setAutoMirrored(icon, true);
+        }
     }
 
     void setIcon(int icon) {
         setIcon((icon == 0) ? null : ResourceDrawableUtils.getDrawable(getContext(), icon));
     }
 
     void setTitle(CharSequence title) {
         // set accessibility contentDescription here
--- a/mobile/android/base/java/org/mozilla/gecko/menu/MenuItemDefault.java
+++ b/mobile/android/base/java/org/mozilla/gecko/menu/MenuItemDefault.java
@@ -6,16 +6,18 @@ package org.mozilla.gecko.menu;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.util.ResourceDrawableUtils;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
 public class MenuItemDefault extends TextView
                              implements GeckoMenuItem.Layout {
     private static final int[] STATE_MORE = new int[] { R.attr.state_more };
     private static final int[] STATE_CHECKED = new int[] { android.R.attr.state_checkable, android.R.attr.state_checked };
     private static final int[] STATE_UNCHECKED = new int[] { android.R.attr.state_checkable };
@@ -46,23 +48,25 @@ public class MenuItemDefault extends Tex
         setMinimumWidth(width);
         setMinimumHeight(height);
 
         int stateIconSize = res.getDimensionPixelSize(R.dimen.menu_item_state_icon);
         Rect stateIconBounds = new Rect(0, 0, stateIconSize, stateIconSize);
 
         mState = res.getDrawable(R.drawable.menu_item_state).mutate();
         mState.setBounds(stateIconBounds);
+        //  Support RTL
+        DrawableCompat.setAutoMirrored(mState, true);
 
         if (sIconBounds == null) {
             int iconSize = res.getDimensionPixelSize(R.dimen.menu_item_icon);
             sIconBounds = new Rect(0, 0, iconSize, iconSize);
         }
 
-        setCompoundDrawables(mIcon, null, mState, null);
+        TextViewCompat.setCompoundDrawablesRelative(this, mIcon, null, mState, null);
     }
 
     @Override
     public int[] onCreateDrawableState(int extraSpace) {
         final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
 
         if (mHasSubMenu)
             mergeDrawableStates(drawableState, STATE_MORE);
@@ -83,17 +87,17 @@ public class MenuItemDefault extends Tex
         setIcon(item.getIcon());
         setEnabled(item.isEnabled());
         setCheckable(item.isCheckable());
         setChecked(item.isChecked());
         setSubMenuIndicator(item.hasSubMenu());
     }
 
     private void refreshIcon() {
-        setCompoundDrawables(mShowIcon ? mIcon : null, null, mState, null);
+        TextViewCompat.setCompoundDrawablesRelative(this, mShowIcon ? mIcon : null, null, mState, null);
     }
 
     void setIcon(Drawable icon) {
         mIcon = icon;
 
         if (mIcon != null) {
             mIcon.setBounds(sIconBounds);
             mIcon.setAlpha(isEnabled() ? 255 : 99);
@@ -109,18 +113,19 @@ public class MenuItemDefault extends Tex
     void setTitle(CharSequence title) {
         setText(title);
     }
 
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
 
-        if (mIcon != null)
+        if (mIcon != null) {
             mIcon.setAlpha(enabled ? 255 : 99);
+        }
 
         if (mState != null)
             mState.setAlpha(enabled ? 255 : 99);
     }
 
     private void setCheckable(boolean checkable) {
         if (mCheckable != checkable) {
             mCheckable = checkable;
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/AlignRightLinkPreference.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/AlignRightLinkPreference.java
@@ -3,22 +3,32 @@
  * 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.preferences;
 
 import org.mozilla.gecko.R;
 
 import android.content.Context;
+import android.support.v4.graphics.drawable.DrawableCompat;
 import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
 
 class AlignRightLinkPreference extends LinkPreference {
 
     public AlignRightLinkPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayoutResource(R.layout.preference_rightalign_icon);
     }
 
     public AlignRightLinkPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         setLayoutResource(R.layout.preference_rightalign_icon);
     }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        ImageView imageView = (ImageView) view.findViewById(R.id.menu_icon_more);
+        DrawableCompat.setAutoMirrored(imageView.getDrawable(), true);
+    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/PromptListAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/PromptListAdapter.java
@@ -7,16 +7,20 @@ import org.mozilla.gecko.menu.MenuItemSw
 import org.mozilla.gecko.widget.GeckoActionProvider;
 
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.CheckedTextView;
 import android.widget.TextView;
 import android.widget.ListView;
 import android.widget.ArrayAdapter;
 import android.util.TypedValue;
@@ -76,19 +80,20 @@ public class PromptListAdapter extends A
         }
     }
 
     @Override
     public int getViewTypeCount() {
         return VIEW_TYPE_COUNT;
     }
 
-    private Drawable getMoreDrawable(Resources res) {
+    private Drawable getMoreDrawable(Context context) {
         if (mMoreDrawable == null) {
-            mMoreDrawable = res.getDrawable(R.drawable.menu_item_more);
+            mMoreDrawable = ContextCompat.getDrawable(context, R.drawable.menu_item_more);
+            DrawableCompat.setAutoMirrored(mMoreDrawable, true);
         }
         return mMoreDrawable;
     }
 
     private Drawable getBlankDrawable(Resources res) {
         if (mBlankDrawable == null) {
             mBlankDrawable = res.getDrawable(R.drawable.blank);
         }
@@ -97,17 +102,17 @@ public class PromptListAdapter extends A
 
     public void toggleSelected(int position) {
         PromptListItem item = getItem(position);
         item.setSelected(!item.getSelected());
     }
 
     private void maybeUpdateIcon(PromptListItem item, TextView t) {
         if (item.getIcon() == null && !item.inGroup && !item.isParent) {
-            t.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+            TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(t, null, null, null, null);
             return;
         }
 
         Drawable d = null;
         Resources res = getContext().getResources();
         // Set the padding between the icon and the text.
         t.setCompoundDrawablePadding(mIconTextPadding);
         if (item.getIcon() != null) {
@@ -117,21 +122,21 @@ public class PromptListAdapter extends A
             d = new BitmapDrawable(res, Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true));
         } else if (item.inGroup) {
             // We don't currently support "indenting" items with icons
             d = getBlankDrawable(res);
         }
 
         Drawable moreDrawable = null;
         if (item.isParent) {
-            moreDrawable = getMoreDrawable(res);
+            moreDrawable = getMoreDrawable(getContext());
         }
 
         if (d != null || moreDrawable != null) {
-            t.setCompoundDrawablesWithIntrinsicBounds(d, null, moreDrawable, null);
+            TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(t, d, null, moreDrawable, null);
         }
     }
 
     private void maybeUpdateCheckedState(ListView list, int position, PromptListItem item, ViewHolder viewHolder) {
         viewHolder.textView.setEnabled(!item.disabled && !item.isGroup);
         viewHolder.textView.setClickable(item.isGroup || item.disabled);
         if (viewHolder.textView instanceof CheckedTextView) {
             // Apparently just using ct.setChecked(true) doesn't work, so this
@@ -238,17 +243,17 @@ public class PromptListAdapter extends A
                 }
 
                 LayoutInflater mInflater = LayoutInflater.from(getContext());
                 convertView = mInflater.inflate(resourceId, null);
                 convertView.setMinimumHeight(mMinRowSize);
 
                 TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
                 tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
-                viewHolder = new ViewHolder(tv, tv.getPaddingLeft(), tv.getPaddingRight(),
+                viewHolder = new ViewHolder(tv, ViewCompat.getPaddingStart(tv), ViewCompat.getPaddingEnd(tv),
                                             tv.getPaddingTop(), tv.getPaddingBottom());
 
                 convertView.setTag(viewHolder);
             }
         } else {
             viewHolder = (ViewHolder) convertView.getTag();
         }
 
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabPanelBackButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabPanelBackButton.java
@@ -5,16 +5,18 @@
 package org.mozilla.gecko.tabs;
 
 import org.mozilla.gecko.R;
 
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.ViewGroup;
 import android.widget.ImageButton;
 
 public class TabPanelBackButton extends ImageButton {
 
     private int dividerWidth = 0;
 
@@ -27,29 +29,43 @@ public class TabPanelBackButton extends 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabPanelBackButton);
         divider = a.getDrawable(R.styleable.TabPanelBackButton_rightDivider);
         dividerPadding = (int) a.getDimension(R.styleable.TabPanelBackButton_dividerVerticalPadding, 0);
         a.recycle();
 
         if (divider != null) {
             dividerWidth = divider.getIntrinsicWidth();
         }
+        //  Support RTL
+        DrawableCompat.setAutoMirrored(getDrawable(), true);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         setMeasuredDimension(getMeasuredWidth() + dividerWidth, getMeasuredHeight());
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         if (divider != null) {
             final ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams();
-            final int left = getRight() - lp.rightMargin - dividerWidth;
 
-            divider.setBounds(left, getPaddingTop() + dividerPadding,
-                    left + dividerWidth, getHeight() - getPaddingBottom() - dividerPadding);
-            divider.draw(canvas);
+            if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
+                final int start = getLeft() + lp.getMarginStart();
+                divider.setBounds(
+                        start,
+                        getPaddingTop() + dividerPadding,
+                        start + dividerWidth,
+                        getHeight() - getPaddingBottom() - dividerPadding
+                );
+                divider.draw(canvas);
+            } else {
+                final int left = getRight() - lp.rightMargin - dividerWidth;
+
+                divider.setBounds(left, getPaddingTop() + dividerPadding,
+                        left + dividerWidth, getHeight() - getPaddingBottom() - dividerPadding);
+                divider.draw(canvas);
+            }
         }
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java
@@ -21,16 +21,18 @@ import org.json.JSONObject;
 
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Region;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Checkable;
 import android.widget.ImageView;
 
@@ -205,19 +207,19 @@ public class TabStripItemView extends Th
         if (AboutPages.isAboutHome(tab.getURL())) {
             titleView.setText(R.string.home_title);
         } else {
             titleView.setText(tab.getDisplayTitle());
         }
 
         // TODO: Set content description to indicate audio is playing.
         if (tab.isAudioPlaying()) {
-            titleView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.tab_audio_playing, 0, 0, 0);
+            TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(titleView, R.drawable.tab_audio_playing, 0, 0, 0);
         } else {
-            titleView.setCompoundDrawables(null, null, null, null);
+            TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(titleView, null, null, null, null);
         }
     }
 
     private void updateFavicon(final Bitmap favicon) {
         if (favicon == null) {
             lastFavicon = null;
             faviconView.setImageResource(R.drawable.toolbar_favicon_default);
             return;
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
@@ -9,16 +9,17 @@ import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.widget.TabThumbnailWrapper;
 import org.mozilla.gecko.widget.TouchDelegateWithReset;
 import org.mozilla.gecko.widget.themed.ThemedRelativeLayout;
 
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.v4.widget.TextViewCompat;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.widget.Checkable;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -139,22 +140,22 @@ public class TabsLayoutItemView extends 
             mThumbnailWrapper.setRecording(tab.isRecording());
         }
 
         final String tabTitle = tab.getDisplayTitle();
         mTitle.setText(tabTitle);
         mCloseButton.setTag(this);
 
         if (tab.isAudioPlaying()) {
-            mTitle.setCompoundDrawablesWithIntrinsicBounds(R.drawable.tab_audio_playing, 0, 0, 0);
+            TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTitle, R.drawable.tab_audio_playing, 0, 0, 0);
             final String tabTitleWithAudio =
                     getResources().getString(R.string.tab_title_prefix_is_playing_audio, tabTitle);
             mTitle.setContentDescription(tabTitleWithAudio);
         } else {
-            mTitle.setCompoundDrawables(null, null, null, null);
+            TextViewCompat.setCompoundDrawablesRelative(mTitle, null, null, null, null);
             mTitle.setContentDescription(tabTitle);
         }
     }
 
     public int getTabId() {
         return mTabId;
     }
 
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarPhoneBase.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarPhoneBase.java
@@ -16,16 +16,18 @@ import org.mozilla.gecko.animation.Prope
 import org.mozilla.gecko.animation.ViewHelper;
 import org.mozilla.gecko.widget.themed.ThemedImageView;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.ImageView;
 
 /**
  * A base implementations of the browser toolbar for phones.
@@ -44,35 +46,56 @@ abstract class BrowserToolbarPhoneBase e
     public BrowserToolbarPhoneBase(final Context context, final AttributeSet attrs) {
         super(context, attrs);
         final Resources res = context.getResources();
 
         urlBarTranslatingEdge = (ImageView) findViewById(R.id.url_bar_translating_edge);
 
         // This will clip the translating edge's image at 60% of its width
         urlBarTranslatingEdge.getDrawable().setLevel(6000);
+        //  Support RTL
+        DrawableCompat.setAutoMirrored(urlBarTranslatingEdge.getDrawable(),  true);
 
         editCancel = (ThemedImageView) findViewById(R.id.edit_cancel);
 
         focusOrder.add(this);
         focusOrder.addAll(urlDisplayLayout.getFocusOrder());
         focusOrder.addAll(Arrays.asList(tabsButton, menuButton));
 
         roundCornerShape = new Path();
-        roundCornerShape.moveTo(0, 0);
-        roundCornerShape.lineTo(30, 0);
-        roundCornerShape.cubicTo(0, 0, 0, 0, 0, 30);
-        roundCornerShape.lineTo(0, 0);
+        updateRoundCornerShape();
 
         roundCornerPaint = new Paint();
         roundCornerPaint.setAntiAlias(true);
         roundCornerPaint.setColor(ContextCompat.getColor(context, R.color.text_and_tabs_tray_grey));
         roundCornerPaint.setStrokeWidth(0.0f);
     }
 
+    private void updateRoundCornerShape() {
+        roundCornerShape.reset();
+        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
+            int right = getRight();
+            roundCornerShape.moveTo(right, 0);
+            roundCornerShape.lineTo(right - 30, 0);
+            roundCornerShape.cubicTo(right, 0, right, 0, right, 30);
+            roundCornerShape.lineTo(right, 0);
+        } else {
+            roundCornerShape.moveTo(0, 0);
+            roundCornerShape.lineTo(30, 0);
+            roundCornerShape.cubicTo(0, 0, 0, 0, 0, 30);
+            roundCornerShape.lineTo(0, 0);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        updateRoundCornerShape();
+    }
+
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
 
         editCancel.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 // If we exit editing mode during the animation,
@@ -146,21 +169,29 @@ abstract class BrowserToolbarPhoneBase e
      * Returns the number of pixels the url bar translating edge
      * needs to translate to the right to enter its editing mode state.
      * A negative value means the edge must translate to the left.
      */
     protected int getUrlBarEntryTranslation() {
         // Find the distance from the right-edge of the url bar (where we're translating from) to
         // the left-edge of the cancel button (where we're translating to; note that the cancel
         // button must be laid out, i.e. not View.GONE).
-        return editCancel.getLeft() - urlBarEntry.getRight();
+        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
+            return editCancel.getRight() - urlBarEntry.getLeft();
+        } else {
+            return editCancel.getLeft() - urlBarEntry.getRight();
+        }
     }
 
     protected int getUrlBarCurveTranslation() {
-        return getWidth() - tabsButton.getLeft();
+        if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
+            return 0 - tabsButton.getRight();
+        } else {
+            return getWidth() - tabsButton.getLeft();
+        }
     }
 
     protected void updateTabCountAndAnimate(final int count) {
         // Don't animate if the toolbar is hidden.
         if (!isVisible()) {
             updateTabCount(count);
             return;
         }
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarTablet.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbarTablet.java
@@ -6,16 +6,18 @@
 package org.mozilla.gecko.toolbar;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.animation.PropertyAnimator;
 import org.mozilla.gecko.animation.ViewHelper;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.v4.view.MarginLayoutParamsCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 
 /**
  * The toolbar implementation for tablet.
  */
 class BrowserToolbarTablet extends BrowserToolbarTabletBase {
 
     private static final int FORWARD_ANIMATION_DURATION = 450;
@@ -36,27 +38,31 @@ class BrowserToolbarTablet extends Brows
         super(context, attrs);
 
         forwardButtonTranslationWidth =
                 getResources().getDimensionPixelOffset(R.dimen.tablet_nav_button_width);
 
         // The forward button is initially expanded (in the layout file)
         // so translate it for start of the expansion animation; future
         // iterations translate it to this position when hiding and will already be set up.
-        ViewHelper.setTranslationX(forwardButton, -forwardButtonTranslationWidth);
+        ViewHelper.setTranslationX(forwardButton, forwardButtonTranslationWidth * (isLayoutRtl() ? 1 : -1));
 
         // TODO: Move this to *TabletBase when old tablet is removed.
         // We don't want users clicking the forward button in transitions, but we don't want it to
         // look disabled to avoid flickering complications (e.g. disabled in editing mode), so undo
         // the work of the super class' constructor.
         forwardButton.setEnabled(true);
 
         updateForwardButtonState(ForwardButtonState.HIDDEN);
     }
 
+    private boolean isLayoutRtl() {
+        return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
+    }
+
     private void updateForwardButtonState(final ForwardButtonState state) {
         forwardButtonState = state;
         forwardButton.setEnabled(forwardButtonState == ForwardButtonState.DISPLAYED);
     }
 
     @Override
     public boolean isAnimating() {
         return false;
@@ -88,40 +94,40 @@ class BrowserToolbarTablet extends Brows
         forwardAnim.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
             @Override
             public void onPropertyAnimationStart() {
                 if (!willShowForward) {
                     // Set the margin before the transition when hiding the forward button. We
                     // have to do this so that the favicon isn't clipped during the transition
                     MarginLayoutParams layoutParams =
                         (MarginLayoutParams) urlDisplayLayout.getLayoutParams();
-                    layoutParams.leftMargin = 0;
+                    MarginLayoutParamsCompat.setMarginStart(layoutParams, 0);
 
                     // Do the same on the URL edit container
                     layoutParams = (MarginLayoutParams) urlEditLayout.getLayoutParams();
-                    layoutParams.leftMargin = 0;
+                    MarginLayoutParamsCompat.setMarginStart(layoutParams, 0);
 
                     requestLayout();
                     // Note, we already translated the favicon, site security, and text field
                     // in prepareForwardAnimation, so they should appear to have not moved at
                     // all at this point.
                 }
             }
 
             @Override
             public void onPropertyAnimationEnd() {
                 final ForwardButtonState newForwardButtonState;
                 if (willShowForward) {
                     // Increase the margins to ensure the text does not run outside the View.
                     MarginLayoutParams layoutParams =
                         (MarginLayoutParams) urlDisplayLayout.getLayoutParams();
-                    layoutParams.leftMargin = forwardButtonTranslationWidth;
+                    MarginLayoutParamsCompat.setMarginStart(layoutParams, forwardButtonTranslationWidth);
 
                     layoutParams = (MarginLayoutParams) urlEditLayout.getLayoutParams();
-                    layoutParams.leftMargin = forwardButtonTranslationWidth;
+                    MarginLayoutParamsCompat.setMarginStart(layoutParams, forwardButtonTranslationWidth);
 
                     newForwardButtonState = ForwardButtonState.DISPLAYED;
                 } else {
                     newForwardButtonState = ForwardButtonState.HIDDEN;
                 }
 
                 urlDisplayLayout.finishForwardAnimation();
                 updateForwardButtonState(newForwardButtonState);
@@ -130,20 +136,21 @@ class BrowserToolbarTablet extends Brows
             }
         });
 
         prepareForwardAnimation(forwardAnim, animation, forwardButtonTranslationWidth);
         forwardAnim.start();
     }
 
     private void prepareForwardAnimation(PropertyAnimator anim, ForwardButtonAnimation animation, int width) {
+        boolean isLayoutRtl = isLayoutRtl();
         if (animation == ForwardButtonAnimation.HIDE) {
             anim.attach(forwardButton,
                       PropertyAnimator.Property.TRANSLATION_X,
-                      -width);
+                      width * (isLayoutRtl ? 1 : -1));
             anim.attach(forwardButton,
                       PropertyAnimator.Property.ALPHA,
                       0);
 
         } else {
             anim.attach(forwardButton,
                       PropertyAnimator.Property.TRANSLATION_X,
                       0);
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ForwardButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ForwardButton.java
@@ -1,23 +1,31 @@
 /* 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.toolbar;
 
 import android.content.Context;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 
 public class ForwardButton extends NavButton {
     public ForwardButton(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
     protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
         super.onSizeChanged(width, height, oldWidth, oldHeight);
 
+        boolean isLayoutRtl = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
         mBorderPath.reset();
-        mBorderPath.moveTo(width - mBorderWidth, 0);
-        mBorderPath.lineTo(width - mBorderWidth, height);
+        final float startX;
+        if (isLayoutRtl) {
+            startX = 0 + mBorderWidth;
+        } else {
+            startX = width - mBorderWidth;
+        }
+        mBorderPath.moveTo(startX, 0);
+        mBorderPath.lineTo(startX, height);
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/NavButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/NavButton.java
@@ -9,16 +9,17 @@ import org.mozilla.gecko.R;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
 import android.util.AttributeSet;
 
 abstract class NavButton extends ShapedButton {
     protected final Path mBorderPath;
     protected final Paint mBorderPaint;
     protected final float mBorderWidth;
 
     protected final int mBorderColor;
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/PhoneTabsButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/PhoneTabsButton.java
@@ -1,29 +1,80 @@
 /* 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.toolbar;
 
 import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
+import android.view.View;
 
 import org.mozilla.gecko.tabs.TabCurve;
 
 public class PhoneTabsButton extends ShapedButton {
     public PhoneTabsButton(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
     protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
         super.onSizeChanged(width, height, oldWidth, oldHeight);
+        redrawTabs(width, height);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        redrawTabs(getWidth(), getHeight());
+    }
+
+    private void redrawTabs(int width, int height) {
+        final int layoutDirection = ViewCompat.getLayoutDirection(this);
+
+        Point[] nodes = getDirectionalNodes(width, height, layoutDirection);
+        TabCurve.Direction directionalCurve = getDirectionalCurve(layoutDirection);
 
         mPath.reset();
 
-        mPath.moveTo(0, 0);
-        TabCurve.drawFromTop(mPath, 0, height, TabCurve.Direction.RIGHT);
-        mPath.lineTo(width, height);
-        mPath.lineTo(width, 0);
-        mPath.lineTo(0, 0);
+        mPath.moveTo(nodes[0].x, nodes[0].y);
+        TabCurve.drawFromTop(mPath, nodes[1].x, nodes[1].y, directionalCurve);
+        mPath.lineTo(nodes[2].x, nodes[2].y);
+        mPath.lineTo(nodes[3].x, nodes[3].y);
+        mPath.lineTo(nodes[0].x, nodes[0].y);
+    }
+
+    private static TabCurve.Direction getDirectionalCurve(int direction) {
+        if (direction == ViewCompat.LAYOUT_DIRECTION_RTL) {
+            //  right to LEFT
+            return TabCurve.Direction.LEFT;
+        } else {
+            //  left to RIGHT
+            return TabCurve.Direction.RIGHT;
+        }
     }
+
+    private static Point[] getDirectionalNodes(int width, int height, int layoutDirection) {
+        final Point[] nodes;
+        if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) {
+            nodes = new Point[] {
+                    new Point(width, 0)
+                    , new Point(width, height)
+                    , new Point(0, height)
+                    , new Point(0, 0)
+            };
+        } else {
+            nodes = new Point[]{
+                    new Point(0, 0)
+                    , new Point(0, height)
+                    , new Point(width, height)
+                    , new Point(width, 0)
+            };
+        }
+        return nodes;
+    }
+
 }
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButton.java
@@ -12,16 +12,18 @@ import org.mozilla.gecko.widget.themed.T
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 
 /**
  * A ImageButton with a custom drawn path and lightweight theme support. Note that {@link ShapedButtonFrameLayout}
  * copies the lwt support so if you change it here, you should probably change it there.
  */
 public class ShapedButton extends ThemedImageButton
                           implements CanvasDelegate.DrawManager {
@@ -37,16 +39,20 @@ public class ShapedButton extends Themed
 
         final Paint paint = new Paint();
         paint.setAntiAlias(true);
         paint.setColor(ContextCompat.getColor(context, R.color.canvas_delegate_paint));
         paint.setStrokeWidth(0.0f);
         mCanvasDelegate = new CanvasDelegate(this, Mode.DST_IN, paint);
 
         setWillNotDraw(false);
+        Drawable drawable = getDrawable();
+        if (drawable != null) {
+            DrawableCompat.setAutoMirrored(drawable, true);
+        }
     }
 
     @Override
     @SuppressLint("MissingSuperCall") // Super gets called from defaultDraw().
                                       // It is intentionally not called in the other case.
     public void draw(Canvas canvas) {
         if (mCanvasDelegate != null)
             mCanvasDelegate.draw(canvas, mPath, getWidth(), getHeight());
@@ -86,24 +92,24 @@ public class ShapedButton extends Themed
 
     @Override
     public void setBackgroundDrawable(Drawable drawable) {
         if (getBackground() == null || drawable == null) {
             super.setBackgroundDrawable(drawable);
             return;
         }
 
-        int[] padding =  new int[] { getPaddingLeft(),
+        int[] padding =  new int[] { ViewCompat.getPaddingStart(this),
                                      getPaddingTop(),
-                                     getPaddingRight(),
+                                     ViewCompat.getPaddingEnd(this),
                                      getPaddingBottom()
                                    };
         drawable.setLevel(getBackground().getLevel());
         super.setBackgroundDrawable(drawable);
 
-        setPadding(padding[0], padding[1], padding[2], padding[3]);
+        ViewCompat.setPaddingRelative(this, padding[0], padding[1], padding[2], padding[3]);
     }
 
     @Override
     public void setBackgroundResource(int resId) {
         setBackgroundDrawable(getResources().getDrawable(resId));
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButtonFrameLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ShapedButtonFrameLayout.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko.toolbar;
 import android.support.v4.content.ContextCompat;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.lwt.LightweightThemeDrawable;
 import org.mozilla.gecko.widget.themed.ThemedFrameLayout;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 
 /** A FrameLayout with lightweight theme support. Note that {@link ShapedButton}'s lwt support is basically the same so
  * if you change it here, you should probably change it there. Note also that this doesn't have ShapedButton's path code
  * so shouldn't have "ShapedButton" in the name, but I wanted to make the connection apparent so I left it.
  */
 public class ShapedButtonFrameLayout extends ThemedFrameLayout {
 
@@ -51,24 +52,24 @@ public class ShapedButtonFrameLayout ext
 
     @Override
     public void setBackgroundDrawable(Drawable drawable) {
         if (getBackground() == null || drawable == null) {
             super.setBackgroundDrawable(drawable);
             return;
         }
 
-        int[] padding =  new int[] { getPaddingLeft(),
+        int[] padding =  new int[] { ViewCompat.getPaddingStart(this),
                                      getPaddingTop(),
-                                     getPaddingRight(),
+                                     ViewCompat.getPaddingEnd(this),
                                      getPaddingBottom()
                                    };
         drawable.setLevel(getBackground().getLevel());
         super.setBackgroundDrawable(drawable);
 
-        setPadding(padding[0], padding[1], padding[2], padding[3]);
+        ViewCompat.setPaddingRelative(this, padding[0], padding[1], padding[2], padding[3]);
     }
 
     @Override
     public void setBackgroundResource(int resId) {
         setBackgroundDrawable(getResources().getDrawable(resId));
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko.toolbar;
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.support.design.widget.Snackbar;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.widget.ImageView;
 import android.widget.Toast;
 import org.json.JSONException;
 import org.json.JSONArray;
 import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.R;
@@ -380,23 +381,23 @@ public class SiteIdentityPopup extends A
                 mMixedContentActivity.setVisibility(View.GONE);
                 mLink.setVisibility(View.GONE);
             }
         }
     }
 
     private void clearSecurityStateIcon() {
         mSecurityState.setCompoundDrawablePadding(0);
-        mSecurityState.setCompoundDrawables(null, null, null, null);
+        TextViewCompat.setCompoundDrawablesRelative(mSecurityState, null, null, null, null);
     }
 
     private void setSecurityStateIcon(int resource, int factor) {
         final Drawable stateIcon = ContextCompat.getDrawable(mContext, resource);
         stateIcon.setBounds(0, 0, stateIcon.getIntrinsicWidth() / factor, stateIcon.getIntrinsicHeight() / factor);
-        mSecurityState.setCompoundDrawables(stateIcon, null, null, null);
+        TextViewCompat.setCompoundDrawablesRelative(mSecurityState, stateIcon, null, null, null);
         mSecurityState.setCompoundDrawablePadding((int) mResources.getDimension(R.dimen.doorhanger_drawable_padding));
     }
     private void updateIdentityInformation(final SiteIdentity siteIdentity) {
         String owner = siteIdentity.getOwner();
         if (owner == null) {
             mOwner.setVisibility(View.GONE);
             mOwnerSupplemental.setVisibility(View.GONE);
         } else {
@@ -509,17 +510,17 @@ public class SiteIdentityPopup extends A
             mTitle.setText(selectedTab.getBaseDomain());
 
             final Bitmap favicon = selectedTab.getFavicon();
             if (favicon != null) {
                 final Drawable faviconDrawable = new BitmapDrawable(mResources, favicon);
                 final int dimen = (int) mResources.getDimension(R.dimen.browser_toolbar_favicon_size);
                 faviconDrawable.setBounds(0, 0, dimen, dimen);
 
-                mTitle.setCompoundDrawables(faviconDrawable, null, null, null);
+                TextViewCompat.setCompoundDrawablesRelative(mTitle, faviconDrawable, null, null, null);
                 mTitle.setCompoundDrawablePadding((int) mContext.getResources().getDimension(R.dimen.doorhanger_drawable_padding));
             }
         }
 
         showDividers();
 
         super.show();
     }
@@ -557,17 +558,17 @@ public class SiteIdentityPopup extends A
                                                                     "Permissions:CheckResult");
     }
 
     @Override
     public void dismiss() {
         super.dismiss();
         removeTrackingContentNotification();
         removeSelectLoginDoorhanger();
-        mTitle.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTitle, null, null, null, null);
         mDivider.setVisibility(View.GONE);
     }
 
     private class ContentNotificationButtonListener implements OnButtonClickListener {
         @Override
         public void onButtonClick(JSONObject response, DoorHanger doorhanger) {
             GeckoAppShell.notifyObservers("Session:Reload", response.toString());
             dismiss();
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarDisplayLayout.java
@@ -26,16 +26,17 @@ import org.mozilla.gecko.Experiments;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.widget.themed.ThemedLinearLayout;
 import org.mozilla.gecko.widget.themed.ThemedTextView;
 
 import android.content.Context;
 import android.os.SystemClock;
 import android.support.annotation.NonNull;
+import android.support.v4.view.ViewCompat;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.style.ForegroundColorSpan;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -464,39 +465,43 @@ public class ToolbarDisplayLayout extend
      * Tablet UI has a tablet-specific doorhanger anchor, so update it after all the views
      * are inflated.
      * @param view View to use as the anchor for the Site Identity popup.
      */
     void updateSiteIdentityAnchor(View view) {
         mSiteIdentityPopup.setAnchor(view);
     }
 
+    private boolean isLayoutRtl() {
+        return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
+    }
+
     void prepareForwardAnimation(PropertyAnimator anim, ForwardButtonAnimation animation, int width) {
         if (animation == ForwardButtonAnimation.HIDE) {
             // We animate these items individually, rather than this entire view,
             // so that we don't animate certain views, e.g. the stop button.
             anim.attach(mTitle,
                         PropertyAnimator.Property.TRANSLATION_X,
-                        0);
+                        isLayoutRtl() ? width : 0);
             anim.attach(mSiteSecurity,
                         PropertyAnimator.Property.TRANSLATION_X,
-                        0);
+                        isLayoutRtl() ? width : 0);
 
             // We're hiding the forward button. We're going to reset the margin before
             // the animation starts, so we shift these items to the right so that they don't
             // appear to move initially.
             ViewHelper.setTranslationX(mTitle, width);
             ViewHelper.setTranslationX(mSiteSecurity, width);
         } else {
             anim.attach(mTitle,
                         PropertyAnimator.Property.TRANSLATION_X,
-                        width);
+                        isLayoutRtl() ? 0 : width);
             anim.attach(mSiteSecurity,
                         PropertyAnimator.Property.TRANSLATION_X,
-                        width);
+                        isLayoutRtl() ? 0 : width);
         }
     }
 
     void finishForwardAnimation() {
         ViewHelper.setTranslationX(mTitle, 0);
         ViewHelper.setTranslationX(mSiteSecurity, 0);
     }
 
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarProgressView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarProgressView.java
@@ -25,16 +25,18 @@ import org.mozilla.gecko.util.WeakRefere
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
+import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.Animation;
 
 /**
  * Progress view used for page loads.
  *
  * Because we're given limited information about the page load progress, the
@@ -45,74 +47,74 @@ public class ToolbarProgressView extends
     private static final int MAX_PROGRESS = 10000;
     private static final int MSG_UPDATE = 0;
     private static final int MSG_HIDE = 1;
     private static final int STEPS = 10;
     private static final int DELAY = 40;
 
     private int mTargetProgress;
     private int mIncrement;
-    private Rect mBounds;
+    private ProgressBounds mBounds;
     private Handler mHandler;
     private int mCurrentProgress;
 
     private PorterDuffColorFilter mPrivateBrowsingColorFilter;
 
     public ToolbarProgressView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         init(context);
     }
 
     public ToolbarProgressView(Context context, AttributeSet attrs) {
         super(context, attrs);
         init(context);
     }
 
     private void init(Context ctx) {
-        mBounds = new Rect(0, 0, 0, 0);
+        mBounds = new ProgressBounds();
+
         mTargetProgress = 0;
 
         mPrivateBrowsingColorFilter = new PorterDuffColorFilter(
                 ContextCompat.getColor(ctx, R.color.private_browsing_purple), PorterDuff.Mode.SRC_IN);
 
         mHandler = new ToolbarProgressHandler(this);
     }
 
     @Override
     public void onLayout(boolean f, int l, int t, int r, int b) {
-        mBounds.left = 0;
-        mBounds.right = (r - l) * mCurrentProgress / MAX_PROGRESS;
-        mBounds.top = 0;
-        mBounds.bottom = b - t;
+        mBounds.setLayoutRtl(ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL);
+        mBounds.onLayout(f, l, t, r, b);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         final Drawable d = getDrawable();
-        d.setBounds(mBounds);
+        DrawableCompat.setAutoMirrored(d, true);
+        d.setBounds(mBounds.getBounds());
         d.draw(canvas);
     }
 
     /**
      * Immediately sets the progress bar to the given progress percentage.
      *
-     * @param progress Percentage (0-100) to which progress bar should be set
+     * @param progressPercentage Percentage (0-100) to which progress bar should be set
      */
     void setProgress(int progressPercentage) {
         mCurrentProgress = mTargetProgress = getAbsoluteProgress(progressPercentage);
         updateBounds();
 
         clearMessages();
     }
 
     /**
      * Animates the progress bar from the current progress value to the given
      * progress percentage.
      *
-     * @param progress Percentage (0-100) to which progress bar should be animated
+     * @param progressPercentage Percentage (0-100) to which progress bar should be animated
      */
     void animateProgress(int progressPercentage) {
         final int absoluteProgress = getAbsoluteProgress(progressPercentage);
         if (absoluteProgress <= mTargetProgress) {
             // After we manually click stop, we can still receive page load
             // events (e.g., DOMContentLoaded). Updating for other updates
             // after a STOP event can freeze the progress bar, so guard against
             // that here.
@@ -139,17 +141,17 @@ public class ToolbarProgressView extends
         if (progressPercentage > 100) {
             return 100;
         }
 
         return progressPercentage * MAX_PROGRESS / 100;
     }
 
     private void updateBounds() {
-        mBounds.right = getWidth() * mCurrentProgress / MAX_PROGRESS;
+        mBounds.updateBounds();
         invalidate();
     }
 
     @Override
     public void setPrivateMode(final boolean isPrivate) {
         super.setPrivateMode(isPrivate);
 
         // Note: android:tint is better but ColorStateLists are not supported until API 21.
@@ -187,9 +189,50 @@ public class ToolbarProgressView extends
                     break;
 
                 case MSG_HIDE:
                     that.setVisibility(View.GONE);
                     break;
             }
         }
     };
+
+    private final class ProgressBounds {
+
+        final Rect bounds;
+        boolean isLayoutRtl = false;
+
+        ProgressBounds() {
+            bounds = new Rect();
+        }
+
+        public Rect getBounds() {
+            return bounds;
+        }
+
+        void setLayoutRtl(boolean isLayoutRtl) {
+            this.isLayoutRtl = isLayoutRtl;
+        }
+
+        void updateBounds() {
+            int progressWidth = getWidth() * mCurrentProgress / MAX_PROGRESS;
+            if (isLayoutRtl) {
+                bounds.left = getWidth() - progressWidth;
+            } else {
+                bounds.right = progressWidth;
+            }
+        }
+
+        void onLayout(boolean f, int l, int t, int r, int b) {
+            bounds.top = 0;
+            bounds.bottom = b - t;
+            int progressWidth = (r - l) * mCurrentProgress / MAX_PROGRESS;
+            ;
+            if (isLayoutRtl) {
+                bounds.left = r - progressWidth;
+                bounds.right = r;
+            } else {
+                bounds.left = 0;
+                bounds.right = progressWidth;
+            }
+        }
+    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/widget/BasicColorPicker.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/BasicColorPicker.java
@@ -12,16 +12,17 @@ import java.util.Arrays;
 import java.util.List;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.v4.widget.TextViewCompat;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.ArrayAdapter;
 import android.widget.AdapterView;
 import android.widget.CheckedTextView;
 import android.widget.ListView;
 import android.util.AttributeSet;
@@ -126,15 +127,15 @@ public class BasicColorPicker extends Li
             v.setBackgroundDrawable(d);
 
             Drawable check = null;
             CheckedTextView checked = ((CheckedTextView) v);
             if (mSelected == position) {
                 check = getCheckDrawable();
             }
 
-            checked.setCompoundDrawables(check, null, null, null);
+            TextViewCompat.setCompoundDrawablesRelative(checked, check, null, null, null);
             checked.setText("");
 
             return v;
         }
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/widget/DoorHanger.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/DoorHanger.java
@@ -5,16 +5,17 @@
 
 package org.mozilla.gecko.widget;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.support.v4.content.ContextCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewStub;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import org.json.JSONObject;
@@ -202,17 +203,17 @@ public abstract class DoorHanger extends
             return false;
         }
 
         return true;
     }
 
     public void showTitle(Bitmap favicon, String title) {
         mDoorhangerTitle.setText(title);
-        mDoorhangerTitle.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(getResources(), favicon), null, null, null);
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mDoorhangerTitle, new BitmapDrawable(getResources(), favicon), null, null, null);
         if (favicon != null) {
             mDoorhangerTitle.setCompoundDrawablePadding((int) mContext.getResources().getDimension(R.dimen.doorhanger_drawable_padding));
         }
         mDoorhangerTitle.setVisibility(VISIBLE);
     }
 
     public void hideTitle() {
         mDoorhangerTitle.setVisibility(GONE);
--- a/mobile/android/base/java/org/mozilla/gecko/widget/FadedSingleColorTextView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/FadedSingleColorTextView.java
@@ -4,17 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.widget;
 
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.LinearGradient;
 import android.graphics.Shader;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
+import android.view.View;
 
 /**
  * Fades the end of the text by gecko:fadeWidth amount,
  * if the text is too long and requires an ellipsis.
  *
  * This implementation is an improvement over Android's built-in fadingEdge
  * and the fastest of Fennec's implementations. However, it only works for
  * text of one color. It works by applying a linear gradient directly to the text.
@@ -32,36 +34,38 @@ public class FadedSingleColorTextView ex
         final int width = getAvailableWidth();
 
         final boolean needsNewGradient = (mTextGradient == null ||
                                           mTextGradient.getColor() != color ||
                                           mTextGradient.getWidth() != width);
 
         final boolean needsEllipsis = needsEllipsis();
         if (needsEllipsis && needsNewGradient) {
-            mTextGradient = new FadedTextGradient(width, fadeWidth, color);
+            final boolean isRTL = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
+            mTextGradient = new FadedTextGradient(width, fadeWidth, color, isRTL);
         }
 
         getPaint().setShader(needsEllipsis ? mTextGradient : null);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         updateGradientShader();
         super.onDraw(canvas);
     }
 
     private static class FadedTextGradient extends LinearGradient {
         private final int mWidth;
         private final int mColor;
 
-        public FadedTextGradient(int width, int fadeWidth, int color) {
-            super(0, 0, width, 0,
-                  new int[] { color, color, 0x0 },
-                  new float[] { 0,  ((float) (width - fadeWidth) / width), 1.0f },
+        public FadedTextGradient(int width, int fadeWidth, int color, boolean isRTL) {
+            super(isRTL ? width : 0, 0,
+                  isRTL ? 0 : width, 0,
+                  new int[]{color, color, 0x0},
+                  new float[]{0, ((float) (width - fadeWidth) / width), 1.0f},
                   Shader.TileMode.CLAMP);
 
             mWidth = width;
             mColor = color;
         }
 
         public int getWidth() {
             return mWidth;
--- a/mobile/android/base/resources/drawable/url_bar_translating_edge.xml
+++ b/mobile/android/base/resources/drawable/url_bar_translating_edge.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <clip xmlns:android="http://schemas.android.com/apk/res/android"
       android:drawable="@drawable/url_bar_entry"
       android:clipOrientation="horizontal"
-      android:gravity="right"/>
\ No newline at end of file
+      android:gravity="right|end"/>
\ No newline at end of file
--- a/mobile/android/base/resources/layout-large-v11/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout-large-v11/browser_toolbar.xml
@@ -5,17 +5,20 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:gecko="http://schemas.android.com/apk/res-auto">
 
     <ImageView android:id="@+id/url_bar_entry"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignLeft="@+id/back"
+               android:layout_alignStart="@+id/back"
                android:layout_toLeftOf="@id/menu_items"
+               android:layout_toStartOf="@id/menu_items"
+               android:layout_marginStart="@dimen/tablet_nav_button_width_half"
                android:layout_marginLeft="@dimen/tablet_nav_button_width_half"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:duplicateParentState="true"
                android:clickable="false"
                android:focusable="false"
                android:background="@drawable/url_bar_entry"/>
 
@@ -35,98 +38,122 @@
          but only need to hide halfway underneath.
 
          (for paddingLeft) We use left padding to center the
          arrow in the visible area as opposed to the true width. -->
     <org.mozilla.gecko.toolbar.ForwardButton
             style="@style/UrlBar.ImageButton.BrowserToolbarColors"
             android:id="@+id/forward"
             android:layout_alignLeft="@id/back"
+            android:layout_alignStart="@id/back"
             android:contentDescription="@string/forward"
             android:layout_height="match_parent"
             android:paddingTop="0dp"
             android:paddingBottom="0dp"
             android:layout_marginTop="11.5dp"
             android:layout_marginBottom="11.5dp"
             android:layout_gravity="center_vertical"
             android:layout_centerVertical="true"
             android:src="@drawable/ic_menu_forward"
             android:background="@drawable/url_bar_nav_button"
             android:alpha="0"
             android:layout_width="@dimen/tablet_nav_button_width_plus_half"
             android:layout_marginLeft="@dimen/tablet_nav_button_width_half"
-            android:paddingLeft="18dp"/>
+            android:layout_marginStart="@dimen/tablet_nav_button_width_half"
+            android:paddingLeft="@dimen/tablet_fwd_button_padding_start"
+            android:paddingStart="@dimen/tablet_fwd_button_padding_start"
+            android:paddingRight="@dimen/tablet_fwd_button_padding_end"
+            android:paddingEnd="@dimen/tablet_fwd_button_padding_end"
+        />
 
     <org.mozilla.gecko.toolbar.BackButton android:id="@id/back"
                                           style="@style/UrlBar.ImageButton.BrowserToolbarColors"
                                           android:layout_width="@dimen/tablet_nav_button_width"
                                           android:layout_height="@dimen/tablet_nav_button_width"
                                           android:layout_centerVertical="true"
                                           android:layout_marginLeft="12dp"
+                                          android:layout_marginStart="12dp"
                                           android:layout_alignParentLeft="true"
+                                          android:layout_alignParentStart="true"
                                           android:src="@drawable/ic_menu_back"
                                           android:contentDescription="@string/back"
-                                          android:background="@drawable/url_bar_nav_button"/>
+                                          android:background="@drawable/url_bar_nav_button"
+        />
 
     <org.mozilla.gecko.toolbar.ToolbarEditLayout android:id="@+id/edit_layout"
                   style="@style/UrlBar.Button"
                   android:paddingRight="12dp"
+                  android:paddingEnd="12dp"
                   android:visibility="gone"
                   android:orientation="horizontal"
+                  android:layout_toLeftOf="@id/menu_items"
+                  android:layout_toStartOf="@id/menu_items"
                   android:layout_toRightOf="@id/back"
-                  android:layout_toLeftOf="@id/menu_items"/>
+                  android:layout_toEndOf="@id/back"/>
 
     <!-- Note: we set the padding on the site security icon to increase its tappable area. -->
     <org.mozilla.gecko.toolbar.ToolbarDisplayLayout android:id="@+id/display_layout"
                   style="@style/UrlBar.Button.Container"
-                  android:layout_toRightOf="@id/back"
-                  android:layout_toLeftOf="@id/menu_items"
-                  android:paddingRight="4dip"/>
+            android:layout_toRightOf="@id/back"
+            android:layout_toEndOf="@id/back"
+            android:layout_toLeftOf="@id/menu_items"
+            android:layout_toStartOf="@id/menu_items"
+            android:paddingRight="4dip"
+            android:paddingEnd="4dip"/>
 
     <LinearLayout android:id="@+id/menu_items"
                   android:layout_width="wrap_content"
                   android:layout_height="match_parent"
                   android:gravity="center_vertical"
                   android:layout_marginLeft="6dp"
-                  android:orientation="horizontal"
-                  android:layout_toLeftOf="@id/tabs"/>
+                  android:layout_marginStart="6dp"
+                  android:layout_toLeftOf="@id/tabs"
+                  android:layout_toStartOf="@id/tabs"
+                  android:orientation="horizontal"/>
 
     <org.mozilla.gecko.widget.themed.ThemedImageButton
             android:id="@+id/tabs"
             style="@style/UrlBar.ImageButton"
             android:layout_toLeftOf="@id/menu"
+            android:layout_toStartOf="@id/menu"
             android:layout_alignWithParentIfMissing="true"
             android:background="@drawable/browser_toolbar_action_bar_button"/>
 
     <!-- In a 56x60dp space, centering 24dp image will leave 16x18dp. -->
     <org.mozilla.gecko.toolbar.TabCounter android:id="@+id/tabs_counter"
                         style="@style/UrlBar.ImageButton"
                         android:layout_alignLeft="@id/tabs"
+                        android:layout_alignStart="@id/tabs"
                         android:layout_alignRight="@id/tabs"
+                        android:layout_alignEnd="@id/tabs"
                         android:layout_alignTop="@id/tabs"
                         android:layout_alignBottom="@id/tabs"
                         android:layout_marginTop="18dp"
                         android:layout_marginBottom="18dp"
                         android:layout_marginLeft="16dp"
+                        android:layout_marginStart="16dp"
                         android:layout_marginRight="16dp"
+                        android:layout_marginEnd="16dp"
                         android:background="@drawable/tabs_count"/>
 
     <!-- Bug 1144707. Use clickable View instead of menu button margin to prevent
          edit mode actiivation when user clicks on the edge of the screen. -->
     <View android:id="@id/menu_margin"
           android:layout_width="6dp"
           android:layout_height="match_parent"
           android:layout_alignParentRight="true"
+          android:layout_alignParentEnd="true"
           android:clickable="true"
           android:visibility="gone"/>
 
     <org.mozilla.gecko.widget.themed.ThemedFrameLayout
             android:id="@+id/menu"
             style="@style/UrlBar.ImageButton"
             android:layout_toLeftOf="@id/menu_margin"
+            android:layout_toStartOf="@id/menu_margin"
             android:layout_alignWithParentIfMissing="true"
             android:contentDescription="@string/menu"
             android:background="@drawable/browser_toolbar_action_bar_button">
 
         <org.mozilla.gecko.widget.themed.ThemedImageView
                 android:id="@+id/menu_icon"
                 style="@style/UrlBar.ImageButton.BrowserToolbarColors"
                 android:layout_height="@dimen/browser_toolbar_menu_icon_height"
@@ -141,13 +168,14 @@
          which is thus drawn on top, may be pressed. -->
     <org.mozilla.gecko.widget.themed.ThemedImageView
             android:id="@+id/edit_cancel"
             style="@style/UrlBar.ImageButton"
             android:layout_width="@dimen/browser_toolbar_icon_width"
             android:layout_height="@dimen/browser_toolbar_height"
             android:layout_weight="0.0"
             android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
             android:src="@drawable/close_edit_mode_selector"
             android:contentDescription="@string/edit_mode_cancel"
             android:visibility="gone"/>
 
 </merge>
--- a/mobile/android/base/resources/layout/activity_stream_card_history_item.xml
+++ b/mobile/android/base/resources/layout/activity_stream_card_history_item.xml
@@ -36,17 +36,17 @@
         <ImageView
             android:id="@+id/menu"
             android:layout_width="wrap_content"
             android:layout_height="36dp"
             android:layout_margin="2dp"
             android:layout_alignParentEnd="true"
             android:layout_alignParentRight="true"
             android:layout_alignParentTop="true"
-            android:layout_gravity="right|top"
+            android:layout_gravity="right|end|top"
             android:contentDescription="@string/menu"
             android:src="@drawable/menu"
             android:padding="@dimen/activity_stream_base_margin" />
 
         <TextView
             android:id="@+id/page"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
--- a/mobile/android/base/resources/layout/activity_stream_topsites_card.xml
+++ b/mobile/android/base/resources/layout/activity_stream_topsites_card.xml
@@ -47,15 +47,15 @@
 
         <ImageView
             android:id="@+id/menu"
             android:layout_width="wrap_content"
             android:layout_height="28dp"
             android:layout_alignParentEnd="true"
             android:layout_alignParentRight="true"
             android:layout_alignParentTop="true"
-            android:layout_gravity="right|top"
+            android:layout_gravity="right|end|top"
             android:padding="6dp"
             android:contentDescription="@string/menu"
             android:src="@drawable/menu" />
 
     </RelativeLayout>
 </org.mozilla.gecko.widget.FilledCardView>
\ No newline at end of file
--- a/mobile/android/base/resources/layout/bookmark_folder_row.xml
+++ b/mobile/android/base/resources/layout/bookmark_folder_row.xml
@@ -2,12 +2,14 @@
 <!-- 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/. -->
 
 <org.mozilla.gecko.home.BookmarkFolderView xmlns:android="http://schemas.android.com/apk/res/android"
                                            style="@style/Widget.FolderView"
                                            android:layout_width="match_parent"
                                            android:paddingLeft="0dp"
+                                           android:paddingStart="0dp"
+                                           android:paddingRight="16dp"
+                                           android:paddingEnd="16dp"
                                            android:paddingTop="0dp"
                                            android:paddingBottom="0dp"
-                                           android:paddingRight="16dp"
                                            android:gravity="center_vertical"/>
--- a/mobile/android/base/resources/layout/browser_toolbar.xml
+++ b/mobile/android/base/resources/layout/browser_toolbar.xml
@@ -5,46 +5,52 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <!-- Note: any layout parameters setting the right edge of
          this View should be matched in the url_bar_translating_edge. -->
     <ImageView android:id="@+id/url_bar_entry"
                style="@style/UrlBar.Button"
                android:layout_marginLeft="8dp"
+               android:layout_marginStart="8dp"
                android:layout_marginRight="-6dp"
+               android:layout_marginEnd="-6dp"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"
                android:layout_toLeftOf="@+id/tabs"
+               android:layout_toStartOf="@+id/tabs"
                android:duplicateParentState="true"
                android:clickable="false"
                android:focusable="false"
                android:src="@drawable/url_bar_entry"
                android:scaleType="fitXY"/>
 
     <!-- A View that clips with url_bar_entry and translates
          around it to animate growing the url bar,
          which occurs in the display/editing mode transitions. -->
     <ImageView android:id="@+id/url_bar_translating_edge"
                style="@style/UrlBar.Button"
                android:layout_alignLeft="@id/url_bar_entry"
+               android:layout_alignStart="@id/url_bar_entry"
                android:layout_alignRight="@+id/url_bar_entry"
+               android:layout_alignEnd="@+id/url_bar_entry"
                android:layout_alignTop="@id/url_bar_entry"
                android:layout_alignBottom="@id/url_bar_entry"
                android:duplicateParentState="true"
                android:clickable="false"
                android:focusable="false"
                android:visibility="invisible"
                android:src="@drawable/url_bar_translating_edge"
                android:scaleType="fitXY"/>
 
     <org.mozilla.gecko.toolbar.ShapedButtonFrameLayout
             android:id="@+id/menu"
             style="@style/UrlBar.ImageButton"
             android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
             android:contentDescription="@string/menu"
             android:background="@drawable/shaped_button">
 
         <org.mozilla.gecko.widget.themed.ThemedImageView
                 android:id="@+id/menu_icon"
                 style="@style/UrlBar.ImageButton"
                 android:layout_height="@dimen/browser_toolbar_menu_icon_height"
                 android:layout_width="wrap_content"
@@ -54,59 +60,71 @@
                 android:tint="@color/tabs_tray_icon_grey"/>
 
     </org.mozilla.gecko.toolbar.ShapedButtonFrameLayout>
 
     <org.mozilla.gecko.toolbar.PhoneTabsButton android:id="@+id/tabs"
                                                style="@style/UrlBar.ImageButton"
                                                android:layout_width="64dip"
                                                android:layout_toLeftOf="@id/menu"
+                                               android:layout_toStartOf="@id/menu"
                                                android:layout_alignWithParentIfMissing="true"
                                                android:background="@drawable/shaped_button"/>
 
     <!-- The TextSwitcher should be shifted 24dp on the left, to avoid
          the curve. On a 48dp space, centering 24dp image will leave
          12dp on all sides. However this image has a perception of
          2 layers. Hence to center this, an additional 4dp is added to the left.
          The margins will be 40dp on left, 8dp on right, instead of ideal 30dp
          and 12dp. -->
     <org.mozilla.gecko.toolbar.TabCounter android:id="@+id/tabs_counter"
                         style="@style/UrlBar.ImageButton"
                         android:layout_width="24dip"
                         android:layout_height="24dip"
                         android:layout_centerVertical="true"
                         android:layout_marginRight="8dip"
+                        android:layout_marginEnd="8dip"
                         android:layout_alignRight="@id/tabs"
+                        android:layout_alignEnd="@id/tabs"
                         android:background="@drawable/tabs_count"
                         android:gravity="center_horizontal"
                         android:clipChildren="false"
                         android:clipToPadding="false"/>
 
     <!-- Note that the edit components are invisible so that the views
          depending on their location can properly layout. -->
     <org.mozilla.gecko.widget.themed.ThemedImageView
             android:id="@+id/edit_cancel"
             style="@style/UrlBar.ImageButton"
             android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
             android:src="@drawable/close_edit_mode_selector"
             android:contentDescription="@string/edit_mode_cancel"
             android:background="@drawable/action_bar_button"
             android:visibility="invisible"/>
 
     <!-- The space to the left of the cancel button would be larger than the right because
          the url bar drawable contains some whitespace, so we compensate by removing
          some padding from the right (value determined through experimentation). -->
     <org.mozilla.gecko.toolbar.ToolbarEditLayout android:id="@+id/edit_layout"
                   style="@style/UrlBar.Button"
                   android:layout_alignLeft="@id/url_bar_entry"
+                  android:layout_alignStart="@id/url_bar_entry"
                   android:layout_toLeftOf="@id/edit_cancel"
+                  android:layout_toStartOf="@id/edit_cancel"
                   android:visibility="invisible"
                   android:paddingLeft="8dp"
-                  android:paddingRight="8dp"/>
+                  android:paddingStart="8dp"
+                  android:paddingRight="8dp"
+                  android:paddingEnd="8dp"/>
 
     <org.mozilla.gecko.toolbar.ToolbarDisplayLayout android:id="@+id/display_layout"
                   style="@style/UrlBar.Button"
                   android:layout_alignLeft="@id/url_bar_entry"
+                  android:layout_alignStart="@id/url_bar_entry"
                   android:layout_alignRight="@id/url_bar_entry"
+                  android:layout_alignEnd="@id/url_bar_entry"
                   android:paddingLeft="1dip"
-                  android:paddingRight="4dip"/>
+                  android:paddingStart="1dip"
+                  android:paddingRight="4dip"
+                  android:paddingEnd="4dip" />
 
 </merge>
--- a/mobile/android/base/resources/layout/default_doorhanger.xml
+++ b/mobile/android/base/resources/layout/default_doorhanger.xml
@@ -14,17 +14,17 @@
               android:layout_height="wrap_content"
               android:textAppearance="@style/TextAppearance.DoorHanger.Medium"/>
 
     <LinearLayout android:id="@+id/doorhanger_inputs"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:orientation="vertical"
               android:layout_marginTop="@dimen/doorhanger_section_padding_medium"
-              android:gravity="right"
+              android:gravity="right|end"
               android:visibility="gone"/>
 
     <android.support.v7.widget.AppCompatCheckBox
               android:id="@+id/doorhanger_checkbox"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_marginTop="@dimen/doorhanger_section_padding_medium"
               android:checked="true"
--- a/mobile/android/base/resources/layout/find_in_page_content.xml
+++ b/mobile/android/base/resources/layout/find_in_page_content.xml
@@ -1,35 +1,40 @@
 <?xml version="1.0" encoding="utf-8"?>
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <view class="org.mozilla.gecko.CustomEditText"
               android:id="@+id/find_text"
               android:layout_width="0dip"
               android:layout_height="wrap_content"
               android:layout_weight="1.0"
-              android:layout_marginLeft="@dimen/find_in_page_text_margin_left"
-              android:layout_marginRight="@dimen/find_in_page_text_margin_right"
+              android:layout_marginLeft="@dimen/find_in_page_text_margin_start"
+              android:layout_marginStart="@dimen/find_in_page_text_margin_start"
+              android:layout_marginRight="@dimen/find_in_page_text_margin_end"
+              android:layout_marginEnd="@dimen/find_in_page_text_margin_end"
               android:contentDescription="@string/find_text"
               android:background="@drawable/url_bar_entry"
               android:singleLine="true"
               android:textColor="#000000"
               android:textCursorDrawable="@null"
               android:inputType="text"
-              android:paddingLeft="@dimen/find_in_page_text_padding_left"
-              android:paddingRight="@dimen/find_in_page_text_padding_right"
+              android:paddingLeft="@dimen/find_in_page_text_padding_start"
+              android:paddingStart="@dimen/find_in_page_text_padding_start"
+              android:paddingRight="@dimen/find_in_page_text_padding_end"
+              android:paddingEnd="@dimen/find_in_page_text_padding_end"
               android:textColorHighlight="@color/fennec_ui_orange"
               android:imeOptions="actionSearch"
               android:selectAllOnFocus="true"
-              android:gravity="center_vertical|left"/>
+              android:gravity="center_vertical|left|start"/>
 
     <TextView android:id="@+id/find_status"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:layout_marginRight="@dimen/find_in_page_status_margin_right"
+              android:layout_marginRight="@dimen/find_in_page_status_margin_end"
+              android:layout_marginEnd="@dimen/find_in_page_status_margin_end"
               android:textColor="@color/tabs_tray_icon_grey"
               android:visibility="gone"/>
 
     <ImageButton android:id="@+id/find_prev"
                  style="@style/FindBar.ImageButton"
                  android:contentDescription="@string/find_prev"
                  android:layout_marginTop="@dimen/find_in_page_control_margin_top"
                  android:src="@drawable/find_prev"/>
--- a/mobile/android/base/resources/layout/home_combined_back_item.xml
+++ b/mobile/android/base/resources/layout/home_combined_back_item.xml
@@ -3,11 +3,13 @@
    - 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/. -->
 
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
           style="@style/Widget.FolderView"
           android:layout_width="match_parent"
           android:text="@string/home_history_back_to"
           android:paddingLeft="24dp"
+          android:paddingStart="24dp"
           android:drawablePadding="24dp"
           android:drawableLeft="@drawable/arrow_up"
+          android:drawableStart="@drawable/arrow_up"
           android:gravity="center_vertical"/>
--- a/mobile/android/base/resources/layout/list_item_header.xml
+++ b/mobile/android/base/resources/layout/list_item_header.xml
@@ -4,11 +4,12 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
     android:id="@android:id/text1"  
     android:layout_width="match_parent"
     android:layout_height="wrap_content"  
     android:paddingTop="2dip"  
-    android:paddingBottom="2dip"  
-    android:paddingLeft="5dip"  
-    style="?android:attr/listSeparatorTextViewStyle" /> 
+    android:paddingBottom="2dip"
+    android:paddingLeft="5dip"
+    android:paddingStart="5dip"
+    style="?android:attr/listSeparatorTextViewStyle" />
--- a/mobile/android/base/resources/layout/panel_back_item.xml
+++ b/mobile/android/base/resources/layout/panel_back_item.xml
@@ -5,16 +5,17 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <ImageView android:id="@+id/image"
                android:layout_width="54dp"
                android:layout_height="44dp"
                android:layout_marginTop="10dip"
                android:layout_marginLeft="10dip"
+               android:layout_marginStart="10dip"
                android:scaleType="centerCrop"/>
 
     <TextView android:id="@+id/title"
               style="@style/Widget.PanelItemView.Title"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:paddingTop="5dip"
               android:paddingBottom="5dip"
--- a/mobile/android/base/resources/layout/pin_site_dialog.xml
+++ b/mobile/android/base/resources/layout/pin_site_dialog.xml
@@ -26,17 +26,17 @@
                   android:textColorHighlight="@color/fennec_ui_orange"
                   android:textSelectHandle="@drawable/handle_middle"
                   android:textSelectHandleLeft="@drawable/handle_start"
                   android:textSelectHandleRight="@drawable/handle_end"
                   android:textCursorDrawable="@null"
                   android:inputType="textUri|textNoSuggestions"
                   android:imeOptions="actionGo|flagNoExtractUi|flagNoFullscreen"
                   android:singleLine="true"
-                  android:gravity="center_vertical|left"/>
+                  android:gravity="center_vertical|left|start"/>
 
     </LinearLayout>
 
     <org.mozilla.gecko.home.HomeListView android:id="@+id/list"
                                          android:layout_width="match_parent"
                                          android:layout_height="0dip"
                                          android:layout_weight="1.0"/>
 
--- a/mobile/android/base/resources/layout/preference_rightalign_icon.xml
+++ b/mobile/android/base/resources/layout/preference_rightalign_icon.xml
@@ -5,39 +5,47 @@
 
 <!-- This custom layout matches the Android layout for preferences in
      padding and margins, so it is visually consistent. -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal"
-      android:paddingRight="?android:attr/scrollbarSize">
+      android:paddingRight="?android:attr/scrollbarSize"
+      android:paddingEnd="?android:attr/scrollbarSize"
+    >
 
     <RelativeLayout
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:gravity="right"
+        android:gravity="right|end"
         android:layout_marginLeft="15dip"
+        android:layout_marginStart="15dip"
         android:layout_marginRight="6dip"
+        android:layout_marginEnd="6dip"
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
         android:paddingRight="6dip"
+        android:paddingEnd="6dip"
         android:layout_weight="1">
 
         <TextView android:id="@+android:id/title"
-            android:layout_gravity="right"
+            android:layout_gravity="right|end"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:singleLine="true"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal" />
 
     </RelativeLayout>
 
-    <ImageView android:src="@drawable/menu_item_more"
+    <ImageView
+               android:id="@+id/menu_icon_more"
+               android:src="@drawable/menu_item_more"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
-               android:paddingRight="16dp" />
+               android:paddingRight="16dp"
+               android:paddingEnd="16dp" />
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/search_activity_main.xml
+++ b/mobile/android/base/resources/layout/search_activity_main.xml
@@ -45,17 +45,17 @@
 
     <ImageButton
         android:id="@+id/settings_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:background="@android:color/transparent"
         android:padding="15dp"
         android:src="@drawable/ic_action_settings"
-        android:layout_gravity="bottom|right"
+        android:layout_gravity="bottom|right|end"
         android:contentDescription="@string/search_pref_button_content_description"/>
 
     <View
         android:id="@+id/animation_card"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginTop="@dimen/search_bar_height"
         android:background="@color/row_background"
--- a/mobile/android/base/resources/layout/search_bar.xml
+++ b/mobile/android/base/resources/layout/search_bar.xml
@@ -7,37 +7,42 @@
     <org.mozilla.search.ui.BackCaptureEditText
         android:id="@+id/edit_text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:imeOptions="actionSearch"
         android:inputType="textNoSuggestions"
         android:drawableLeft="@drawable/search_icon_inactive"
+        android:drawableStart="@drawable/search_icon_inactive"
+        android:paddingRight="30dp"
+        android:paddingEnd="30dp"
         android:drawablePadding="5dp"
         android:textSize="@dimen/query_text_size"
         android:focusable="false"
         android:focusableInTouchMode="false"
         android:textColorHighlight="@color/fennec_ui_orange"
         android:textSelectHandle="@drawable/handle_middle"
         android:textSelectHandleLeft="@drawable/handle_start"
-        android:textSelectHandleRight="@drawable/handle_end" />
+        android:textSelectHandleRight="@drawable/handle_end"
+        />
 
     <ImageButton
         android:id="@+id/clear_button"
         android:layout_width="30dp"
         android:layout_height="30dp"
         android:paddingLeft="10dp"
-        android:layout_gravity="right|center_vertical"
+        android:paddingStart="10dp"
+        android:layout_gravity="right|end|center_vertical"
         android:background="@android:color/transparent"
         android:src="@drawable/search_clear"
         android:scaleType="centerInside"
         android:visibility="gone"/>
 
     <ImageView
         android:id="@+id/engine_icon"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_gravity="right|center_vertical"
+        android:layout_gravity="right|end|center_vertical"
         android:background="@android:color/transparent"
         android:visibility="gone"/>
 
 </merge>
--- a/mobile/android/base/resources/layout/search_history_row.xml
+++ b/mobile/android/base/resources/layout/search_history_row.xml
@@ -4,11 +4,12 @@
 
 <TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/site_name"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/search_row_background"
     android:drawableLeft="@drawable/search_history"
+    android:drawableStart="@drawable/search_history"
     android:drawablePadding="@dimen/search_history_drawable_padding"
     android:padding="@dimen/search_row_padding"
     android:textSize="@dimen/query_text_size"/>
--- a/mobile/android/base/resources/layout/search_suggestions_row.xml
+++ b/mobile/android/base/resources/layout/search_suggestions_row.xml
@@ -17,15 +17,16 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:textSize="@dimen/query_text_size"/>
 
     <ImageButton
         android:id="@+id/auto_complete_row_jump_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="right|center_vertical"
+        android:layout_gravity="right|end|center_vertical"
         android:paddingLeft="@dimen/search_row_padding"
+        android:paddingStart="@dimen/search_row_padding"
         android:src="@drawable/search_plus"
         android:contentDescription="@string/search_plus_content_description"
         android:background="@android:color/transparent" />
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/site_setting_item.xml
+++ b/mobile/android/base/resources/layout/site_setting_item.xml
@@ -2,17 +2,19 @@
 
 <org.mozilla.gecko.widget.CheckableLinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:gravity="center_vertical"
     android:paddingLeft="16dip"
+    android:paddingStart="16dip"
     android:paddingRight="12dip"
+    android:paddingEnd="12dip"
     android:minHeight="?android:attr/listPreferredItemHeight"
     android:focusable="false">
 
     <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:orientation="vertical"
@@ -20,34 +22,35 @@
         android:focusable="false">
 
         <TextView
             android:id="@+id/setting"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
             style="Widget.ListItem"
-            android:gravity="center_vertical|left"
+            android:gravity="center_vertical|left|start"
             android:singleLine="true"
             android:ellipsize="marquee"/>
 
         <TextView
             android:id="@+id/value"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceSmall"
             style="Widget.ListItem"
-            android:gravity="center_vertical|left"
+            android:gravity="center_vertical|left|start"
             android:singleLine="true"
             android:ellipsize="marquee"/>
 
     </LinearLayout>
 
     <android.support.v7.widget.AppCompatCheckBox
         android:id="@+id/checkbox"
         android:layout_width="35dip"
         android:layout_height="wrap_content"
         android:paddingRight="12dip"
+        android:paddingEnd="12dip"
         android:gravity="center_vertical"
         android:focusable="false"
         android:clickable="false"/>
 
 </org.mozilla.gecko.widget.CheckableLinearLayout>
--- a/mobile/android/base/resources/layout/tab_history_item_row.xml
+++ b/mobile/android/base/resources/layout/tab_history_item_row.xml
@@ -9,18 +9,21 @@
                 android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 android:background="@color/state_pressed_toolbar_grey_pressed" >
 
     <LinearLayout android:id="@+id/tab_history_timeline_combo"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:orientation="vertical"
-                    android:layout_marginLeft="@dimen/tab_history_combo_margin_left"
-                    android:layout_marginRight="@dimen/tab_history_combo_margin_right" >
+                    android:layout_marginLeft="@dimen/tab_history_combo_margin_start"
+                    android:layout_marginStart="@dimen/tab_history_combo_margin_start"
+                    android:layout_marginRight="@dimen/tab_history_combo_margin_end"
+                    android:layout_marginEnd="@dimen/tab_history_combo_margin_end"
+        >
 
         <ImageView android:id="@+id/tab_history_timeline_top"
                    android:layout_width="@dimen/tab_history_timeline_width"
                    android:layout_height="@dimen/tab_history_timeline_height"
                    android:layout_gravity="center_horizontal"
                    android:background="@color/tab_history_timeline_separator" />
 
         <org.mozilla.gecko.widget.FaviconView android:id="@+id/tab_history_icon"
@@ -44,15 +47,16 @@
          (bug 1271797). So we override the override and set the background equal to null. -->
     <org.mozilla.gecko.widget.FadedSingleColorTextView
             android:id="@+id/tab_history_title"
             style="@style/Widget.TwoLinePageRow.Title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
             android:background="@null"
-            android:paddingRight="@dimen/tab_history_title_margin_right"
+            android:paddingRight="@dimen/tab_history_title_margin_end"
+            android:paddingEnd="@dimen/tab_history_title_margin_end"
             android:text="@+id/tab_history_title"
             android:textSize="@dimen/tab_history_title_text_size"
             android:textColor="@color/text_and_tabs_tray_grey"
             gecko:fadeWidth="@dimen/tab_history_title_fading_width"/>
 
 </LinearLayout>
--- a/mobile/android/base/resources/layout/tab_menu_strip.xml
+++ b/mobile/android/base/resources/layout/tab_menu_strip.xml
@@ -3,13 +3,13 @@
    - 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/. -->
 
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="0dp"
           android:layout_height="match_parent"
           android:minWidth="@dimen/tabs_strip_button_width"
           android:background="@drawable/tabs_strip_indicator"
-          android:paddingLeft="@dimen/tabs_strip_button_padding"
-          android:paddingRight="@dimen/tabs_strip_button_padding"
+          android:paddingStart="@dimen/tabs_strip_button_padding"
+          android:paddingEnd="@dimen/tabs_strip_button_padding"
           android:gravity="center"
           android:focusable="true"
           style="@style/TextAppearance.Widget.HomePagerTabMenuStrip"/>
--- a/mobile/android/base/resources/layout/tab_strip_item.xml
+++ b/mobile/android/base/resources/layout/tab_strip_item.xml
@@ -5,9 +5,12 @@
 
 <!-- The paddings are asymmetric here to compensate the padding around the
      the close button within the TabStripItemView -->
 <org.mozilla.gecko.tabs.TabStripItemView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/tablet_tab_strip_item_width"
     android:layout_height="match_parent"
     android:paddingLeft="28dp"
-    android:paddingRight="12dp"/>
+    android:paddingStart="28dp"
+    android:paddingRight="12dp"
+    android:paddingEnd="12dp"
+    />
--- a/mobile/android/base/resources/layout/tab_strip_item_view.xml
+++ b/mobile/android/base/resources/layout/tab_strip_item_view.xml
@@ -6,25 +6,27 @@
 <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:gecko="http://schemas.android.com/apk/res-auto">
 
    <ImageView
         android:id="@+id/favicon"
         android:layout_width="@dimen/browser_toolbar_favicon_size"
         android:layout_height="match_parent"
         android:layout_marginRight="8dp"
+        android:layout_marginEnd="8dp"
         android:scaleType="centerInside"
         android:duplicateParentState="true"/>
 
     <org.mozilla.gecko.widget.FadedSingleColorTextView
         android:id="@+id/title"
         android:layout_width="0dip"
         android:layout_height="match_parent"
         android:layout_weight="1.0"
         android:layout_marginRight="-5dp"
+        android:layout_marginEnd="-5dp"
         android:drawablePadding="6dp"
         android:gravity="center_vertical"
         android:textSize="14sp"
         android:ellipsize="end"
         android:textColor="@color/tab_strip_item_title"
         android:maxLines="1"
         gecko:fadeWidth="30dip"
         android:duplicateParentState="true"/>
--- a/mobile/android/base/resources/layout/toolbar_display_layout.xml
+++ b/mobile/android/base/resources/layout/toolbar_display_layout.xml
@@ -10,20 +10,23 @@
          we add a bottom margin to align their bottoms.
          Site security icon must have exact position and size as search icon in
          edit layout -->
     <ImageButton android:id="@+id/site_security"
                  style="@style/UrlBar.ImageButton"
                  android:layout_width="@dimen/browser_toolbar_site_security_width"
                  android:layout_height="@dimen/browser_toolbar_site_security_height"
                  android:scaleType="fitCenter"
-                 android:layout_marginRight="@dimen/browser_toolbar_site_security_margin_right"
+                 android:layout_marginRight="@dimen/browser_toolbar_site_security_margin_end"
+                 android:layout_marginEnd="@dimen/browser_toolbar_site_security_margin_end"
                  android:layout_marginBottom="@dimen/browser_toolbar_site_security_margin_bottom"
                  android:paddingLeft="@dimen/browser_toolbar_site_security_padding_horizontal"
+                 android:paddingStart="@dimen/browser_toolbar_site_security_padding_horizontal"
                  android:paddingRight="@dimen/browser_toolbar_site_security_padding_horizontal"
+                 android:paddingEnd="@dimen/browser_toolbar_site_security_padding_horizontal"
                  android:paddingTop="@dimen/browser_toolbar_site_security_padding_vertical"
                  android:paddingBottom="@dimen/browser_toolbar_site_security_padding_vertical"
                  android:src="@drawable/site_security_level"
                  android:contentDescription="@string/site_security"
                  android:layout_gravity="center_vertical" />
 
     <org.mozilla.gecko.widget.FadedMultiColorTextView
             android:id="@+id/url_bar_title"
--- a/mobile/android/base/resources/layout/toolbar_edit_layout.xml
+++ b/mobile/android/base/resources/layout/toolbar_edit_layout.xml
@@ -7,36 +7,40 @@
        xmlns:gecko="http://schemas.android.com/apk/res-auto">
 
     <!-- Search icon must have exact position and size as site security in
          display layout -->
     <ImageView android:id="@+id/search_icon"
         android:layout_width="@dimen/browser_toolbar_site_security_width"
         android:layout_height="@dimen/browser_toolbar_site_security_height"
         android:layout_marginBottom="@dimen/browser_toolbar_site_security_margin_bottom"
-        android:layout_marginRight="@dimen/browser_toolbar_site_security_margin_right"
+        android:layout_marginRight="@dimen/browser_toolbar_site_security_margin_end"
+        android:layout_marginEnd="@dimen/browser_toolbar_site_security_margin_end"
         android:paddingBottom="@dimen/browser_toolbar_site_security_padding_vertical"
         android:paddingLeft="@dimen/browser_toolbar_site_security_padding_horizontal"
+        android:paddingStart="@dimen/browser_toolbar_site_security_padding_horizontal"
         android:paddingRight="@dimen/browser_toolbar_site_security_padding_horizontal"
+        android:paddingEnd="@dimen/browser_toolbar_site_security_padding_horizontal"
         android:paddingTop="@dimen/browser_toolbar_site_security_padding_vertical"
         android:scaleType="fitCenter"
         android:src="@drawable/search_icon_inactive"
         android:visibility="gone"/>
 
     <org.mozilla.gecko.toolbar.ToolbarEditText
           android:id="@+id/url_edit_text"
           style="@style/UrlBar.Title"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_weight="1.0"
           android:inputType="textUri|textNoSuggestions"
           android:imeOptions="actionGo|flagNoExtractUi|flagNoFullscreen"
           android:selectAllOnFocus="true"
           android:contentDescription="@string/url_bar_default_text"
           android:paddingRight="8dp"
+          android:paddingEnd="8dp"
           gecko:autoUpdateTheme="false"/>
 
     <ImageButton android:id="@+id/qrcode"
                  android:layout_width="@dimen/page_action_button_width"
                  android:layout_height="match_parent"
                  android:src="@drawable/ab_qrcode"
                  android:background="@android:color/transparent"/>
 
--- a/mobile/android/base/resources/layout/tracking_protection_prompt.xml
+++ b/mobile/android/base/resources/layout/tracking_protection_prompt.xml
@@ -93,14 +93,16 @@
                 android:layout_height="52dp"
                 android:layout_gravity="center"
                 android:background="@drawable/button_background_action_orange_round"
                 android:text="@string/tracking_protection_prompt_action_button"
                 android:textColor="@android:color/white"
                 android:textSize="16sp"
 
                 android:layout_marginLeft="32dp"
+                android:layout_marginStart="32dp"
                 android:layout_marginRight="32dp"
+                android:layout_marginEnd="32dp"
                 tools:text="Got it"/>
 
     </LinearLayout>
 
 </merge>
--- a/mobile/android/base/resources/layout/two_line_folder_row.xml
+++ b/mobile/android/base/resources/layout/two_line_folder_row.xml
@@ -15,16 +15,17 @@
                android:scaleType="fitXY"
                android:layout_margin="20dp"/>
 
     <LinearLayout android:layout_width="0dp"
                   android:layout_height="wrap_content"
                   android:layout_weight="1"
                   android:layout_gravity="center_vertical"
                   android:paddingRight="10dp"
+                  android:paddingEnd="10dp"
                   android:orientation="vertical">
 
         <org.mozilla.gecko.widget.FadedSingleColorTextView
                 android:id="@+id/title"
                 style="@style/Widget.TwoLinePageRow.Title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 gecko:fadeWidth="90dp"
--- a/mobile/android/base/resources/layout/two_line_page_row.xml
+++ b/mobile/android/base/resources/layout/two_line_page_row.xml
@@ -14,16 +14,17 @@
                                           android:layout_margin="16dp"
                                           tools:background="@drawable/favicon_globe"/>
 
     <LinearLayout android:layout_width="0dp"
                   android:layout_height="wrap_content"
                   android:layout_weight="1"
                   android:layout_gravity="center_vertical"
                   android:paddingRight="10dp"
+                  android:paddingEnd="10dp"
                   android:orientation="vertical">
 
         <org.mozilla.gecko.widget.FadedSingleColorTextView
                 android:id="@+id/title"
                 style="@style/Widget.TwoLinePageRow.Title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 gecko:fadeWidth="90dp"
@@ -32,17 +33,19 @@
         <org.mozilla.gecko.widget.FadedSingleColorTextView android:id="@+id/url"
                   style="@style/Widget.TwoLinePageRow.Url"
                   android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:drawablePadding="5dp"
                   android:maxLength="1024"
                   gecko:fadeWidth="90dp"
                   tools:text="http://test.com/test"
-                  tools:drawableLeft="@drawable/ic_url_bar_tab"/>
+                  tools:drawableLeft="@drawable/ic_url_bar_tab"
+                  tools:drawableStart="@drawable/ic_url_bar_tab"
+            />
 
     </LinearLayout>
 
     <ImageView android:id="@+id/status_icon_bookmark"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_gravity="center"
                android:visibility="gone"
--- a/mobile/android/base/resources/values-large/dimens.xml
+++ b/mobile/android/base/resources/values-large/dimens.xml
@@ -14,17 +14,17 @@
     <dimen name="tabs_panel_indicator_selected_padding_top">50dp</dimen>
 
     <dimen name="browser_toolbar_height_flipper">60dp</dimen>
     <dimen name="browser_toolbar_button_padding">16dp</dimen>
     <dimen name="browser_toolbar_favicon_size">16dp</dimen>
 
     <dimen name="browser_toolbar_site_security_height">60dp</dimen>
     <dimen name="browser_toolbar_site_security_width">34dp</dimen>
-    <dimen name="browser_toolbar_site_security_margin_right">1dp</dimen>
+    <dimen name="browser_toolbar_site_security_margin_end">1dp</dimen>
     <!-- We primarily use padding (instead of margins) to increase the hit area. -->
     <dimen name="browser_toolbar_site_security_padding_vertical">21dp</dimen>
     <dimen name="browser_toolbar_site_security_padding_horizontal">8dp</dimen>
 
     <dimen name="firstrun_background_height">300dp</dimen>
 
     <dimen name="tabs_panel_indicator_width">72dp</dimen>
     <dimen name="tabs_panel_button_width">60dp</dimen>
--- a/mobile/android/base/resources/values/dimens.xml
+++ b/mobile/android/base/resources/values/dimens.xml
@@ -28,16 +28,19 @@
     <dimen name="browser_toolbar_favicon_size">21.33dip</dimen>
     <dimen name="browser_toolbar_shadow_size">2dp</dimen>
 
     <!-- If you update one of these values, update the others. -->
     <dimen name="tablet_nav_button_width">42dp</dimen>
     <dimen name="tablet_nav_button_width_half">21dp</dimen>
     <dimen name="tablet_nav_button_width_plus_half">63dp</dimen>
 
+    <dimen name="tablet_fwd_button_padding_start">18dp</dimen>
+    <dimen name="tablet_fwd_button_padding_end">0dp</dimen>
+
     <!-- This is the system default for the vertical padding for the divider of the TabWidget.
          Used to mimic the divider padding on the tablet tabs panel back button. -->
     <dimen name="tab_panel_divider_vertical_padding">12dp</dimen>
 
     <dimen name="tablet_tab_strip_height">48dp</dimen>
     <dimen name="tablet_tab_strip_item_width">208dp</dimen>
     <dimen name="tablet_tab_strip_item_margin">-28dp</dimen>
     <dimen name="tablet_tab_strip_fading_edge_size">15dp</dimen>
@@ -65,17 +68,17 @@
 
     <dimen name="overlay_prompt_content_width">260dp</dimen>
     <dimen name="overlay_prompt_button_width">148dp</dimen>
     <dimen name="overlay_prompt_container_width">@dimen/match_parent</dimen>
 
     <!-- Site security icon -->
     <dimen name="browser_toolbar_site_security_height">32dp</dimen>
     <dimen name="browser_toolbar_site_security_width">32dp</dimen>
-    <dimen name="browser_toolbar_site_security_margin_right">0dp</dimen>
+    <dimen name="browser_toolbar_site_security_margin_end">0dp</dimen>
     <dimen name="browser_toolbar_site_security_padding_vertical">7dp</dimen>
     <dimen name="browser_toolbar_site_security_padding_horizontal">7dp</dimen>
 
     <!-- If one of these values changes, they all should. -->
     <dimen name="browser_toolbar_site_security_margin_bottom">.5dp</dimen>
     <dimen name="site_security_unknown_inset_top">1dp</dimen>
     <dimen name="site_security_unknown_inset_bottom">-1dp</dimen>
 
@@ -180,34 +183,34 @@
 
     <!-- TabHistoryItemRow dimensions. -->
     <dimen name="tab_history_timeline_width">3dp</dimen>
     <dimen name="tab_history_timeline_height">14dp</dimen>
     <dimen name="tab_history_favicon_bg">32dp</dimen>
     <dimen name="tab_history_favicon_padding">5dp</dimen>
     <dimen name="tab_history_favicon_border_enabled">3dp</dimen>
     <dimen name="tab_history_favicon_border_disabled">1dp</dimen>
-    <dimen name="tab_history_combo_margin_left">15dp</dimen>
-    <dimen name="tab_history_combo_margin_right">15dp</dimen>
+    <dimen name="tab_history_combo_margin_start">15dp</dimen>
+    <dimen name="tab_history_combo_margin_end">15dp</dimen>
     <dimen name="tab_history_title_fading_width">50dp</dimen>
-    <dimen name="tab_history_title_margin_right">15dp</dimen>
+    <dimen name="tab_history_title_margin_end">15dp</dimen>
     <dimen name="tab_history_title_text_size">14sp</dimen>
     <dimen name="tab_history_bg_width">2dp</dimen>
     <dimen name="tab_history_border_padding">2dp</dimen>
 
     <!-- ZoomedView dimensions. -->
     <dimen name="zoomed_view_toolbar_height">44dp</dimen>
     <dimen name="drawable_dropshadow_size">3dp</dimen>
 
     <!-- Find-In-Page dialog dimensions. -->
-    <dimen name="find_in_page_text_margin_left">5dip</dimen>
-    <dimen name="find_in_page_text_margin_right">12dip</dimen>
-    <dimen name="find_in_page_text_padding_left">10dip</dimen>
-    <dimen name="find_in_page_text_padding_right">10dip</dimen>
-    <dimen name="find_in_page_status_margin_right">10dip</dimen>
+    <dimen name="find_in_page_text_margin_start">5dip</dimen>
+    <dimen name="find_in_page_text_margin_end">12dip</dimen>
+    <dimen name="find_in_page_text_padding_start">10dip</dimen>
+    <dimen name="find_in_page_text_padding_end">10dip</dimen>
+    <dimen name="find_in_page_status_margin_end">10dip</dimen>
     <dimen name="find_in_page_control_margin_top">2dip</dimen>
     <dimen name="progress_bar_scroll_offset">1.5dp</dimen>
 
     <!-- Matches the built-in divider height. fwiw, in the framework
          I suspect this is a drawable rather than a dimen.  -->
     <dimen name="action_bar_divider_height">2dp</dimen>
 
     <!-- http://blog.danlew.net/2015/01/06/handling-android-resources-with-non-standard-formats/ -->
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/SearchBar.java
+++ b/mobile/android/search/java/org/mozilla/search/autocomplete/SearchBar.java
@@ -12,16 +12,17 @@ import org.mozilla.gecko.search.SearchEn
 
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.support.v4.widget.TextViewCompat;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.inputmethod.EditorInfo;
@@ -158,18 +159,18 @@ public class SearchBar extends FrameLayo
         }
         this.active = active;
 
         updateClearButtonVisibility();
 
         editText.setFocusable(active);
         editText.setFocusableInTouchMode(active);
 
-        final int leftDrawable = active ? R.drawable.search_icon_active : R.drawable.search_icon_inactive;
-        editText.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, 0, 0, 0);
+        final int startDrawable = active ? R.drawable.search_icon_active : R.drawable.search_icon_inactive;
+        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(editText, startDrawable, 0, 0, 0);
 
         // We can't use a selector drawable because we apply a color filter to the focused
         // background at run time.
         // TODO: setBackgroundDrawable is deprecated in API level 16
         editText.setBackgroundDrawable(active ? focusedBackground : defaultBackground);
 
         if (active) {
             editText.requestFocus();
--- a/mobile/android/services/src/main/res/layout/homescreen_prompt.xml
+++ b/mobile/android/services/src/main/res/layout/homescreen_prompt.xml
@@ -20,73 +20,86 @@
         android:clickable="true"
         android:orientation="vertical">
 
         <ImageView
             android:id="@+id/close"
             android:layout_width="24dp"
             android:layout_height="24dp"
             android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
             android:layout_marginLeft="10dp"
+            android:layout_marginStart="10dp"
             android:layout_marginRight="30dp"
+            android:layout_marginEnd="30dp"
             android:layout_marginTop="30dp"
             android:ellipsize="end"
             android:maxLines="2"
             android:padding="6dp"
             android:src="@drawable/tab_close_active" />
 
         <TextView
             android:id="@+id/title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginBottom="6dp"
             android:layout_marginLeft="30dp"
+            android:layout_marginStart="30dp"
             android:layout_marginTop="30dp"
             android:layout_toLeftOf="@id/close"
+            android:layout_toStartOf="@id/close"
             android:fontFamily="sans-serif-light"
             android:textColor="@color/text_and_tabs_tray_grey"
             android:textSize="20sp"
             tools:text="The Pokedex" />
 
         <TextView
             android:id="@+id/host"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_below="@id/title"
             android:layout_marginBottom="20dp"
             android:layout_marginLeft="30dp"
+            android:layout_marginStart="30dp"
             android:layout_marginRight="30dp"
+            android:layout_marginEnd="30dp"
             android:ellipsize="end"
             android:maxLines="1"
             android:textColor="@color/placeholder_grey"
             android:textSize="16sp"
             tools:text="pokedex.org" />
 
         <ImageView
             android:id="@+id/icon"
             android:layout_width="50dp"
             android:layout_height="50dp"
             android:layout_below="@id/host"
             android:layout_marginBottom="20dp"
             android:layout_marginLeft="30dp"
+            android:layout_marginStart="30dp"
             android:src="@drawable/icon" />
 
         <Button
             android:id="@+id/add"
             style="@style/Widget.BaseButton"
             android:layout_width="wrap_content"
             android:layout_height="50dp"
             android:layout_alignParentRight="true"
+            android:layout_alignParentEnd="true"
             android:layout_below="@id/host"
             android:layout_marginBottom="20dp"
             android:layout_marginLeft="100dp"
+            android:layout_marginStart="100dp"
             android:layout_marginRight="30dp"
+            android:layout_marginEnd="30dp"
             android:background="@drawable/button_background_action_orange_round"
             android:paddingLeft="16dp"
+            android:paddingStart="16dp"
             android:paddingRight="16dp"
+            android:paddingEnd="16dp"
             android:text="@string/promotion_add_to_homescreen"
             android:maxLines="2"
             android:ellipsize="end"
             android:textColor="@android:color/white"
             android:textSize="16sp" />
 
     </RelativeLayout>
 </merge>