Automatically supply a content description for ToolbarActionBar nav

If the developer hasn't set a navigation content description on the
Toolbar assigned to be an action bar or a home-action content
description via the ActionBar interface, use the framework default
"navigate up" string.

Also make sure that the default Up description is supplied in the
screen_toolbar window decor layout and that it is parsed properly in
all toolbars, even if we don't have an icon set during construction.

Bug 17298370

Change-Id: Ie2f9e34f92046d4d4ffb9a07e38fa89581891f7b
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index ece8aa4..3ba03b8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -248,11 +248,12 @@
         final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
         if (navIcon != null) {
             setNavigationIcon(navIcon);
-            final CharSequence navDesc = a.getText(
-                    R.styleable.Toolbar_navigationContentDescription);
-            if (!TextUtils.isEmpty(navDesc)) {
-                setNavigationContentDescription(navDesc);
-            }
+        }
+
+        final CharSequence navDesc = a.getText(
+                R.styleable.Toolbar_navigationContentDescription);
+        if (!TextUtils.isEmpty(navDesc)) {
+            setNavigationContentDescription(navDesc);
         }
         a.recycle();
     }
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index abe8a9f..6f1c7ec 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -32,6 +33,7 @@
 import android.view.WindowCallbackWrapper;
 import android.widget.SpinnerAdapter;
 import android.widget.Toolbar;
+import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.widget.DecorToolbar;
 import com.android.internal.widget.ToolbarWidgetWrapper;
@@ -44,6 +46,8 @@
     private boolean mToolbarMenuPrepared;
     private Window.Callback mWindowCallback;
 
+    private CharSequence mHomeDescription;
+
     private boolean mLastMenuVisibility;
     private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
             new ArrayList<OnMenuVisibilityListener>();
@@ -70,6 +74,8 @@
         mDecorToolbar.setWindowCallback(mWindowCallback);
         toolbar.setOnMenuItemClickListener(mMenuClicker);
         mDecorToolbar.setWindowTitle(title);
+        mHomeDescription = mToolbar.getNavigationContentDescription();
+        updateNavDescription();
     }
 
     public Window.Callback getWrappedWindowCallback() {
@@ -161,6 +167,7 @@
     @Override
     public void setHomeActionContentDescription(CharSequence description) {
         mToolbar.setNavigationContentDescription(description);
+        mHomeDescription = description;
     }
 
     @Override
@@ -171,6 +178,7 @@
     @Override
     public void setHomeActionContentDescription(int resId) {
         mToolbar.setNavigationContentDescription(resId);
+        mHomeDescription = mToolbar.getNavigationContentDescription();
     }
 
     @Override
@@ -247,8 +255,22 @@
 
     @Override
     public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
-        mDecorToolbar.setDisplayOptions((options & mask) |
-                mDecorToolbar.getDisplayOptions() & ~mask);
+        final int currentOptions = mDecorToolbar.getDisplayOptions();
+        final int changed = (options ^ currentOptions) & mask;
+        mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask);
+        if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+            updateNavDescription();
+        }
+    }
+
+    private void updateNavDescription() {
+        if ((mDecorToolbar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+            if (TextUtils.isEmpty(mHomeDescription)) {
+                mToolbar.setNavigationContentDescription(R.string.action_bar_up_description);
+            } else {
+                mToolbar.setNavigationContentDescription(mHomeDescription);
+            }
+        }
     }
 
     @Override
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
index 039e89f..88c9cf6 100644
--- a/core/res/res/layout/screen_toolbar.xml
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -41,6 +41,7 @@
             android:id="@+id/action_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:navigationContentDescription="@string/action_bar_up_description"
             style="?attr/toolbarStyle" />
         <com.android.internal.widget.ActionBarContextView
             android:id="@+id/action_context_bar"