am ecce91d6: am f9fd9749: am 26d0f7a7: Merge "Remove unused LOCAL_LDLIBS."
* commit 'ecce91d619d659ef920fc797c4f18b26445c85d2':
Remove unused LOCAL_LDLIBS.
diff --git a/build.gradle b/build.gradle
index ae2f294..da14cf5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,8 +9,8 @@
}
}
-ext.supportVersion = '19.2.0'
-ext.extraVersion = 6
+ext.supportVersion = '20.0.0'
+ext.extraVersion = 7
ext.supportRepoOut = ''
/*
diff --git a/v17/leanback/Android.mk b/v17/leanback/Android.mk
index 01a8ae3..bf9e3af 100644
--- a/v17/leanback/Android.mk
+++ b/v17/leanback/Android.mk
@@ -119,6 +119,7 @@
LOCAL_SRC_FILES := $(leanback.docs.src_files)
LOCAL_JAVA_LIBRARIES := $(leanback.docs.java_libraries)
+LOCAL_SDK_VERSION := current
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sdk
LOCAL_UNINSTALLABLE_MODULE := true
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/app/TransitionHelperKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/app/TransitionHelperKitkat.java
index 4ad20b0..529c307 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/app/TransitionHelperKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/app/TransitionHelperKitkat.java
@@ -33,10 +33,7 @@
class TransitionHelperKitkat {
- private final Context mContext;
-
- TransitionHelperKitkat(Context context) {
- mContext = context;
+ TransitionHelperKitkat() {
}
Object createScene(ViewGroup sceneRoot, Runnable enterAction) {
diff --git a/v17/leanback/res/layout/lb_browse_fragment.xml b/v17/leanback/res/layout/lb_browse_fragment.xml
index 0315daa..167c972 100644
--- a/v17/leanback/res/layout/lb_browse_fragment.xml
+++ b/v17/leanback/res/layout/lb_browse_fragment.xml
@@ -31,7 +31,7 @@
<include layout="@layout/lb_browse_title" />
<android.support.v17.leanback.app.BrowseRowsFrameLayout
android:id="@+id/browse_container_dock"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/browse_headers_dock"
diff --git a/v17/leanback/res/layout/lb_list_row.xml b/v17/leanback/res/layout/lb_list_row.xml
index a432518..80d7bef 100644
--- a/v17/leanback/res/layout/lb_list_row.xml
+++ b/v17/leanback/res/layout/lb_list_row.xml
@@ -19,5 +19,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/row_content"
android:layout_width="match_parent"
- android:layout_height="@dimen/lb_browse_row_list_height"
+ android:layout_height="wrap_content"
style="?attr/rowHorizontalGridStyle" />
diff --git a/v17/leanback/res/layout/lb_rows_fragment.xml b/v17/leanback/res/layout/lb_rows_fragment.xml
index 5b147c5..c4ffdc3 100644
--- a/v17/leanback/res/layout/lb_rows_fragment.xml
+++ b/v17/leanback/res/layout/lb_rows_fragment.xml
@@ -16,8 +16,8 @@
-->
<android.support.v17.leanback.widget.VerticalGridView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:lb="http://schemas.android.com/apk/res-auto"
android:id="@+id/container_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?attr/rowsVerticalGridStyle" />
+
diff --git a/v17/leanback/res/layout/lb_search_orb.xml b/v17/leanback/res/layout/lb_search_orb.xml
index c6bf690..1822d4a 100644
--- a/v17/leanback/res/layout/lb_search_orb.xml
+++ b/v17/leanback/res/layout/lb_search_orb.xml
@@ -18,8 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- android:orientation="horizontal"
- android:focusable="true">
+ android:orientation="horizontal">
<TextView
android:layout_height="wrap_content"
@@ -55,4 +54,4 @@
android:src="@drawable/ic_action_search"
android:contentDescription="@string/orb_search_action" />
</FrameLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/v17/leanback/res/layout/lb_vertical_grid_fragment.xml b/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
index 902c483..0720501 100644
--- a/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
+++ b/v17/leanback/res/layout/lb_vertical_grid_fragment.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -27,4 +27,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
-</LinearLayout>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/v17/leanback/res/values/attrs.xml b/v17/leanback/res/values/attrs.xml
index 78456c6..4cbb72f 100644
--- a/v17/leanback/res/values/attrs.xml
+++ b/v17/leanback/res/values/attrs.xml
@@ -26,18 +26,24 @@
<attr name="horizontalMargin" format="dimension" />
<!-- Defining margin between two items vertically -->
<attr name="verticalMargin" format="dimension" />
+ <!-- Defining gravity of child view -->
+ <attr name="android:gravity" />
</declare-styleable>
<declare-styleable name="lbHorizontalGridView">
<!-- Defining height of each row of HorizontalGridView -->
- <attr name="rowHeight" format="dimension" />
+ <attr name="rowHeight" format="dimension" >
+ <enum name="wrap_content" value="-2" />
+ </attr>
<!-- Defining number of rows -->
<attr name="numberOfRows" format="integer" />
</declare-styleable>
<declare-styleable name="lbVerticalGridView">
<!-- Defining width of each column of VerticalGridView -->
- <attr name="columnWidth" format="dimension" />
+ <attr name="columnWidth" format="dimension" >
+ <enum name="wrap_content" value="-2" />
+ </attr>
<!-- Defining number of columns -->
<attr name="numberOfColumns" format="integer" />
</declare-styleable>
diff --git a/v17/leanback/res/values/dimens.xml b/v17/leanback/res/values/dimens.xml
index 61792fa..6f2df61 100644
--- a/v17/leanback/res/values/dimens.xml
+++ b/v17/leanback/res/values/dimens.xml
@@ -15,6 +15,8 @@
limitations under the License.
-->
<resources>
+ <dimen name="lb_list_row_height">224dp</dimen>
+
<dimen name="lb_browse_padding_left">56dp</dimen>
<dimen name="lb_browse_padding_top">27dp</dimen>
<dimen name="lb_browse_padding_right">56dp</dimen>
@@ -41,7 +43,6 @@
<item name="lb_browse_header_unselect_alpha" format="float" type="dimen">0.5</item>
<item name="lb_browse_header_select_scale" format="float" type="dimen">1.1</item>
- <dimen name="lb_browse_row_list_height">224dp</dimen>
<dimen name="lb_browse_row_title_height">24dp</dimen>
<dimen name="lb_browse_row_hovercard_max_width">420dp</dimen>
<dimen name="lb_browse_row_hovercard_title_font_size">18sp</dimen>
diff --git a/v17/leanback/res/values/styles.xml b/v17/leanback/res/values/styles.xml
index 955e9fe..737e054 100644
--- a/v17/leanback/res/values/styles.xml
+++ b/v17/leanback/res/values/styles.xml
@@ -137,6 +137,7 @@
<item name="horizontalMargin">@dimen/lb_browse_item_margin</item>
<item name="verticalMargin">@dimen/lb_browse_item_margin</item>
<item name="focusOutFront">true</item>
+ <item name="rowHeight">wrap_content</item>
</style>
<style name="Widget.Leanback.GridItems.VerticalGridView">
@@ -146,7 +147,8 @@
<item name="android:paddingLeft">?attr/browsePaddingLeft</item>
<item name="android:paddingRight">?attr/browsePaddingRight</item>
<item name="android:paddingBottom">@dimen/lb_browse_item_margin_vertical</item>
- <item name="android:paddingTop">@dimen/lb_browse_item_margin_vertical</item>
+ <item name="android:paddingTop">?attr/browseRowsMarginTop</item>
+ <item name="android:gravity">center_horizontal</item>
<item name="horizontalMargin">@dimen/lb_browse_item_margin</item>
<item name="verticalMargin">@dimen/lb_browse_item_margin</item>
<item name="focusOutFront">true</item>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 0df07f4..74c1924 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -16,6 +16,7 @@
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.HorizontalGridView;
import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.PresenterSelector;
import android.support.v17.leanback.widget.VerticalGridView;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.ObjectAdapter;
@@ -74,13 +75,15 @@
private boolean mCanShowHeaders = true;
private int mContainerListMarginLeft;
private int mContainerListAlignTop;
- private TransitionHelper mTransitionHelper;
private OnItemSelectedListener mExternalOnItemSelectedListener;
private OnClickListener mExternalOnSearchClickedListener;
private OnItemClickedListener mOnItemClickedListener;
private int mSelectedPosition = -1;
+ private PresenterSelector mHeaderPresenterSelector;
+
// transition related:
+ private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
private static int sReparentHeaderId = View.generateViewId();
private Object mSceneWithTitle;
private Object mSceneWithoutTitle;
@@ -303,12 +306,12 @@
if (childId == R.id.browse_container_dock && mShowingHeaders) {
mShowingHeaders = false;
onHeadersTransitionStart(false);
- mTransitionHelper.runTransition(mSceneWithoutHeaders, mHeadersTransition);
+ sTransitionHelper.runTransition(mSceneWithoutHeaders, mHeadersTransition);
} else if (childId == R.id.browse_headers_dock && !mShowingHeaders) {
mShowingHeaders = true;
//mHeadersFragment.getView().setAlpha(1f);
onHeadersTransitionStart(true);
- mTransitionHelper.runTransition(mSceneWithHeaders, mHeadersTransition);
+ sTransitionHelper.runTransition(mSceneWithHeaders, mHeadersTransition);
}
}
};
@@ -342,6 +345,9 @@
.findFragmentById(R.id.browse_container_dock);
}
mRowsFragment.setAdapter(mAdapter);
+ if (mHeaderPresenterSelector != null) {
+ mHeadersFragment.setPresenterSelector(mHeaderPresenterSelector);
+ }
mHeadersFragment.setAdapter(mAdapter);
mRowsFragment.setOnItemSelectedListener(mRowSelectedListener);
@@ -370,34 +376,33 @@
setHeadersState(mParams.mHeadersState);
}
- mTransitionHelper = new TransitionHelper(getActivity());
- mSceneWithTitle = mTransitionHelper.createScene(mBrowseFrame, new Runnable() {
+ mSceneWithTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
showTitle(true);
}
});
- mSceneWithoutTitle = mTransitionHelper.createScene(mBrowseFrame, new Runnable() {
+ mSceneWithoutTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
showTitle(false);
}
});
- mSceneWithHeaders = mTransitionHelper.createScene(mBrowseFrame, new Runnable() {
+ mSceneWithHeaders = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
showHeaders(true);
}
});
- mSceneWithoutHeaders = mTransitionHelper.createScene(mBrowseFrame, new Runnable() {
+ mSceneWithoutHeaders = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
showHeaders(false);
}
});
- mTitleTransition = mTransitionHelper.createAutoTransition();
- mTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_headers, true);
- mTransitionHelper.excludeChildren(mTitleTransition, R.id.container_list, true);
+ mTitleTransition = sTransitionHelper.createAutoTransition();
+ sTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_headers, true);
+ sTransitionHelper.excludeChildren(mTitleTransition, R.id.container_list, true);
return root;
}
@@ -411,13 +416,13 @@
mHeadersFragment.getHeaderViews(fastHeaders, fastHeaderPositions);
mRowsFragment.getHeaderViews(headers, headerPositions);
- mHeadersTransition = mTransitionHelper.createTransitionSet(true);
- mTransitionHelper.excludeChildren(mHeadersTransition, R.id.browse_title_group, true);
- Object changeBounds = mTransitionHelper.createChangeBounds(true);
- Object fadeIn = mTransitionHelper.createFadeTransition(TransitionHelper.FADE_IN);
- Object fadeOut = mTransitionHelper.createFadeTransition(TransitionHelper.FADE_OUT);
+ mHeadersTransition = sTransitionHelper.createTransitionSet(true);
+ sTransitionHelper.excludeChildren(mHeadersTransition, R.id.browse_title_group, true);
+ Object changeBounds = sTransitionHelper.createChangeBounds(true);
+ Object fadeIn = sTransitionHelper.createFadeTransition(TransitionHelper.FADE_IN);
+ Object fadeOut = sTransitionHelper.createFadeTransition(TransitionHelper.FADE_OUT);
if (!withHeaders) {
- mTransitionHelper.setChangeBoundsDefaultStartDelay(changeBounds,
+ sTransitionHelper.setChangeBoundsDefaultStartDelay(changeBounds,
mHeadersTransitionStartDelay);
}
@@ -425,10 +430,10 @@
Integer position = headerPositions.get(i);
if (position == mSelectedPosition) {
headers.get(i).setId(sReparentHeaderId);
- mTransitionHelper.setChangeBoundsStartDelay(changeBounds, sReparentHeaderId,
+ sTransitionHelper.setChangeBoundsStartDelay(changeBounds, sReparentHeaderId,
withHeaders ? mHeadersTransitionStartDelay : 0);
- mTransitionHelper.exclude(fadeIn, headers.get(i), true);
- mTransitionHelper.exclude(fadeOut, headers.get(i), true);
+ sTransitionHelper.exclude(fadeIn, headers.get(i), true);
+ sTransitionHelper.exclude(fadeOut, headers.get(i), true);
} else {
headers.get(i).setId(View.NO_ID);
}
@@ -437,20 +442,20 @@
Integer position = fastHeaderPositions.get(i);
if (position == mSelectedPosition) {
fastHeaders.get(i).setId(sReparentHeaderId);
- mTransitionHelper.setChangeBoundsStartDelay(changeBounds, sReparentHeaderId,
+ sTransitionHelper.setChangeBoundsStartDelay(changeBounds, sReparentHeaderId,
withHeaders ? mHeadersTransitionStartDelay : 0);
- mTransitionHelper.exclude(fadeIn, fastHeaders.get(i), true);
- mTransitionHelper.exclude(fadeOut, fastHeaders.get(i), true);
+ sTransitionHelper.exclude(fadeIn, fastHeaders.get(i), true);
+ sTransitionHelper.exclude(fadeOut, fastHeaders.get(i), true);
} else {
fastHeaders.get(i).setId(View.NO_ID);
}
}
- mTransitionHelper.addTransition(mHeadersTransition, fadeOut);
- mTransitionHelper.addTransition(mHeadersTransition, changeBounds);
- mTransitionHelper.addTransition(mHeadersTransition, fadeIn);
+ sTransitionHelper.addTransition(mHeadersTransition, fadeOut);
+ sTransitionHelper.addTransition(mHeadersTransition, changeBounds);
+ sTransitionHelper.addTransition(mHeadersTransition, fadeIn);
- mTransitionHelper.setTransitionCompleteListener(mHeadersTransition, new Runnable() {
+ sTransitionHelper.setTransitionCompleteListener(mHeadersTransition, new Runnable() {
@Override
public void run() {
mHeadersTransition = null;
@@ -475,6 +480,13 @@
});
}
+ public void setHeaderPresenterSelector(PresenterSelector headerPresenterSelector) {
+ mHeaderPresenterSelector = headerPresenterSelector;
+ if (mHeadersFragment != null) {
+ mHeadersFragment.setPresenterSelector(mHeaderPresenterSelector);
+ }
+ }
+
private void showTitle(boolean show) {
mBrowseTitle.setVisibility(show ? View.VISIBLE : View.GONE);
}
@@ -502,7 +514,7 @@
}
mShowingHeaders = false;
onHeadersTransitionStart(false);
- mTransitionHelper.runTransition(mSceneWithoutHeaders, mHeadersTransition);
+ sTransitionHelper.runTransition(mSceneWithoutHeaders, mHeadersTransition);
mRowsFragment.getVerticalGridView().requestFocus();
}
};
@@ -535,11 +547,11 @@
if (position == 0) {
if (!mShowingTitle) {
- mTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition);
+ sTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition);
mShowingTitle = true;
}
} else if (mShowingTitle) {
- mTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition);
+ sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition);
mShowingTitle = false;
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
index 7cb5ce1..2027881 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
@@ -23,6 +23,7 @@
import android.support.v17.leanback.widget.OnItemSelectedListener;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowHeaderPresenter;
+import android.support.v17.leanback.widget.SinglePresenterSelector;
import android.support.v17.leanback.widget.VerticalGridView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -44,15 +45,11 @@
private OnHeaderClickedListener mOnHeaderClickedListener;
private boolean mShow = true;
- private static final Presenter sHeaderPresenter = new RowHeaderPresenter();
+ private static final PresenterSelector sHeaderPresenter = new SinglePresenterSelector(
+ new RowHeaderPresenter());
public HeadersFragment() {
- setPresenterSelector(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object item) {
- return sHeaderPresenter;
- }
- });
+ setPresenterSelector(sHeaderPresenter);
}
public void setOnHeaderClickedListener(OnHeaderClickedListener listener) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
index a97c5d8..1a5e625 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
@@ -50,6 +50,7 @@
final TimeAnimator mSelectAnimator = new TimeAnimator();
final ColorOverlayDimmer mColorDimmer;
+
int mSelectAnimatorDurationInUse;
Interpolator mSelectAnimatorInterpolatorInUse;
float mSelectLevelAnimStart;
@@ -69,6 +70,12 @@
@Override
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+ if (mSelectAnimator.isRunning()) {
+ updateSelect(totalTime, deltaTime);
+ }
+ }
+
+ void updateSelect(long totalTime, long deltaTime) {
float fraction;
if (totalTime >= mSelectAnimatorDurationInUse) {
fraction = 1;
@@ -87,7 +94,7 @@
}
void animateSelect(boolean select, boolean immediate) {
- endAnimation();
+ endSelectAnimation();
final float end = select ? 1 : 0;
if (immediate) {
mRowPresenter.setSelectLevel(mRowViewHolder, end);
@@ -103,7 +110,11 @@
}
}
- void endAnimation() {
+ void endAnimations() {
+ endSelectAnimation();
+ }
+
+ void endSelectAnimation() {
mSelectAnimator.end();
}
@@ -124,8 +135,9 @@
private OnItemSelectedListener mOnItemSelectedListener;
private OnItemClickedListener mOnItemClickedListener;
- // Select animation and interpolator are not intended to exposed at this moment.
- // They might be synced with vertical scroll animation later.
+ // Select animation and interpolator are not intended to be
+ // exposed at this moment. They might be synced with vertical scroll
+ // animation later.
int mSelectAnimatorDuration;
Interpolator mSelectAnimatorInterpolator = new DecelerateInterpolator(2);
@@ -157,7 +169,6 @@
mExpand = expand;
VerticalGridView listView = getVerticalGridView();
if (listView != null) {
- listView.setActivated(expand);
final int count = listView.getChildCount();
if (DEBUG) Log.v(TAG, "setExpand " + expand + " count " + count);
for (int i = 0; i < count; i++) {
@@ -289,7 +300,7 @@
@Override
public void onUnbind(ItemBridgeAdapter.ViewHolder vh) {
RowViewHolderExtra extra = (RowViewHolderExtra) vh.getExtraObject();
- extra.endAnimation();
+ extra.endAnimations();
}
};
diff --git a/v17/leanback/src/android/support/v17/leanback/app/TransitionHelper.java b/v17/leanback/src/android/support/v17/leanback/app/TransitionHelper.java
index 78c2766..783386e 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/TransitionHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/TransitionHelper.java
@@ -13,7 +13,6 @@
*/
package android.support.v17.leanback.app;
-import android.content.Context;
import android.os.Build;
import android.util.SparseArray;
import android.view.View;
@@ -27,6 +26,7 @@
public static final int FADE_IN = 0x1;
public static final int FADE_OUT = 0x2;
+ private final static TransitionHelper sHelper = new TransitionHelper();
TransitionHelperVersionImpl mImpl;
/**
@@ -189,8 +189,8 @@
private static final class TransitionHelperKitkatImpl implements TransitionHelperVersionImpl {
private final TransitionHelperKitkat mTransitionHelper;
- TransitionHelperKitkatImpl(Context context) {
- mTransitionHelper = new TransitionHelperKitkat(context);
+ TransitionHelperKitkatImpl() {
+ mTransitionHelper = new TransitionHelperKitkat();
}
@Override
@@ -288,12 +288,14 @@
/**
* Returns the TransitionHelper that can be used to perform Transition
* animations.
- *
- * @param context A context for accessing system resources.
*/
- public TransitionHelper(Context context) {
+ public static TransitionHelper getInstance() {
+ return sHelper;
+ }
+
+ private TransitionHelper() {
if (systemSupportsTransitions()) {
- mImpl = new TransitionHelperKitkatImpl(context);
+ mImpl = new TransitionHelperKitkatImpl();
} else {
mImpl = new TransitionHelperStubImpl();
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index ff4cddf..5e2c4e6 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -14,6 +14,7 @@
package android.support.v17.leanback.app;
import android.support.v17.leanback.R;
+import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.VerticalGridPresenter;
import android.support.v17.leanback.widget.ObjectAdapter;
import android.support.v17.leanback.widget.OnItemClickedListener;
@@ -56,6 +57,13 @@
private TextView mTitleView;
private ViewGroup mBrowseTitle;
private SearchOrbView mSearchOrbView;
+ private boolean mShowingTitle = true;
+
+ // transition related
+ private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
+ private Object mTitleTransition;
+ private Object mSceneWithTitle;
+ private Object mSceneWithoutTitle;
public static class Params {
private String mTitle;
@@ -114,9 +122,7 @@
throw new IllegalArgumentException("Grid presenter may not be null");
}
mGridPresenter = gridPresenter;
- if (mOnItemSelectedListener != null) {
- mGridPresenter.setOnItemSelectedListener(mOnItemSelectedListener);
- }
+ mGridPresenter.setOnItemSelectedListener(mRowSelectedListener);
if (mOnItemClickedListener != null) {
mGridPresenter.setOnItemClickedListener(mOnItemClickedListener);
}
@@ -144,17 +150,40 @@
return mAdapter;
}
+ final private OnItemSelectedListener mRowSelectedListener = new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(Object item, Row row) {
+ int position = mGridViewHolder.getGridView().getSelectedPosition();
+ if (DEBUG) Log.v(TAG, "row selected position " + position);
+ onRowSelected(position);
+ if (mOnItemSelectedListener != null) {
+ mOnItemSelectedListener.onItemSelected(item, row);
+ }
+ }
+ };
+
/**
* Sets an item selection listener.
*/
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
mOnItemSelectedListener = listener;
- if (mGridPresenter != null) {
- mGridPresenter.setOnItemSelectedListener(mOnItemSelectedListener);
- }
}
- // TODO: getitemselectedlistener?
+ private void onRowSelected(int position) {
+ if (position != mSelectedPosition) {
+ if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) {
+ // if has no sibling in front of it, show title
+ if (!mShowingTitle) {
+ sTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition);
+ mShowingTitle = true;
+ }
+ } else if (mShowingTitle) {
+ sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition);
+ mShowingTitle = false;
+ }
+ mSelectedPosition = position;
+ }
+ }
/**
* Sets an item clicked listener.
@@ -211,7 +240,8 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.lb_vertical_grid_fragment, container, false);
+ ViewGroup root = (ViewGroup) inflater.inflate(R.layout.lb_vertical_grid_fragment,
+ container, false);
mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group);
mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge);
@@ -226,6 +256,25 @@
setTitle(mParams.mTitle);
}
+ mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
+ @Override
+ public void run() {
+ mBrowseTitle.setVisibility(View.VISIBLE);
+ }
+ });
+ mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
+ @Override
+ public void run() {
+ mBrowseTitle.setVisibility(View.GONE);
+ }
+ });
+ mTitleTransition = sTransitionHelper.createTransitionSet(false);
+ Object fade = sTransitionHelper.createFadeTransition(
+ TransitionHelper.FADE_IN | TransitionHelper.FADE_OUT);
+ Object changeBounds = sTransitionHelper.createChangeBounds(false);
+ sTransitionHelper.addTransition(mTitleTransition, fade);
+ sTransitionHelper.addTransition(mTitleTransition, changeBounds);
+ sTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_grid_dock, true);
return root;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
index 854f5de..a0dc556 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
@@ -19,8 +19,8 @@
import android.support.v17.leanback.R;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
-import android.view.ViewGroup;
import android.view.animation.Interpolator;
/**
@@ -122,6 +122,9 @@
a.getDimensionPixelSize(R.styleable.lbBaseGridView_verticalMargin, 0));
mLayoutManager.setHorizontalMargin(
a.getDimensionPixelSize(R.styleable.lbBaseGridView_horizontalMargin, 0));
+ if (a.hasValue(R.styleable.lbBaseGridView_android_gravity)) {
+ setGravity(a.getInt(R.styleable.lbBaseGridView_android_gravity, Gravity.NO_GRAVITY));
+ }
a.recycle();
}
@@ -467,4 +470,21 @@
return mLayoutManager.isFocusSearchDisabled();
}
+ /**
+ * Get if view has same row sibling next to it.
+ *
+ * @param position Position in adapter.
+ */
+ public boolean hasNextViewInSameRow(int position) {
+ return mLayoutManager.hasNextViewInSameRow(position);
+ }
+
+ /**
+ * Get if view has same row sibling in front of it.
+ *
+ * @param position Position in adapter.
+ */
+ public boolean hasPreviousViewInSameRow(int position) {
+ return mLayoutManager.hasPreviousViewInSameRow(position);
+ }
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
index 0ad0669..8529968 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -19,6 +19,7 @@
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.Recycler;
+import android.support.v7.widget.RecyclerView.State;
import static android.support.v7.widget.RecyclerView.NO_ID;
import static android.support.v7.widget.RecyclerView.NO_POSITION;
@@ -72,9 +73,16 @@
private boolean mFirstAttached;
// current virtual view position (scrollOffset + left/top) in the GridLayoutManager
private int mViewX, mViewY;
+ private int mSize;
// animation start value of translation x and y
private float mAnimationStartTranslationX, mAnimationStartTranslationY;
+ // The direction this view should be laid out along the primary dimension.
+ private boolean mLayoutForward;
+
+ // Orientation of the grid layout
+ private int mOrientation;
+
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
@@ -167,8 +175,21 @@
float fraction = (float) (totalTime / (double)mDuration);
float fractionToEnd = 1 - mAnimator
.getInterpolator().getInterpolation(fraction);
- mView.setTranslationX(fractionToEnd * mAnimationStartTranslationX);
- mView.setTranslationY(fractionToEnd * mAnimationStartTranslationY);
+ if (mOrientation == HORIZONTAL) {
+ if (mLayoutForward) {
+ mView.setTranslationX(fractionToEnd * mAnimationStartTranslationX);
+ } else {
+ mView.setTranslationX(fractionToEnd * mAnimationStartTranslationX -
+ fractionToEnd * (mView.getMeasuredWidth() - mSize));
+ }
+ } else {
+ if (mLayoutForward) {
+ mView.setTranslationY(fractionToEnd * mAnimationStartTranslationY);
+ } else {
+ mView.setTranslationY(fractionToEnd * mAnimationStartTranslationY -
+ fractionToEnd * (mView.getMeasuredHeight() - mSize));
+ }
+ }
invalidateItemDecoration();
}
}
@@ -184,6 +205,8 @@
// TODO do we need initial animation?
mViewX = layout.getScrollOffsetX() + getOpticalLeft(view);
mViewY = layout.getScrollOffsetY() + getOpticalTop(view);
+ mOrientation = layout.mOrientation;
+ mSize = mOrientation == HORIZONTAL ? view.getMeasuredWidth() : view.getMeasuredHeight();
mFirstAttached = false;
return;
}
@@ -211,6 +234,8 @@
mAnimator.end();
}
if (mView != null) {
+ mSize = mOrientation == HORIZONTAL ?
+ mView.getMeasuredWidth() : mView.getMeasuredHeight();
mView.setTranslationX(0);
mView.setTranslationY(0);
mView = null;
@@ -271,17 +296,32 @@
private int mScrollOffsetSecondary;
/**
- * User-specified fixed size of each grid item in the secondary direction, can be
- * 0 to be determined by parent size and number of rows.
+ * User-specified row height/column width. Can be WRAP_CONTENT.
*/
- private int mItemLengthSecondaryRequested;
+ private int mRowSizeSecondaryRequested;
+
/**
* The fixed size of each grid item in the secondary direction. This corresponds to
* the row height, equal for all rows. Grid items may have variable length
* in the primary direction.
- *
*/
- private int mItemLengthSecondary;
+ private int mFixedRowSizeSecondary;
+
+ /**
+ * Tracks the secondary size of each row.
+ */
+ private int[] mRowSizeSecondary;
+
+ /**
+ * Flag controlling whether the current/next layout should
+ * be updating the secondary size of rows.
+ */
+ private boolean mRowSecondarySizeRefresh;
+
+ /**
+ * The maximum measured size of the view.
+ */
+ private int mMaxSizeSecondary;
/**
* Margin between items.
@@ -467,9 +507,15 @@
mForceFullLayout = true;
}
+ /**
+ * Set the row height. May be WRAP_CONTENT, or a size in pixels.
+ */
public void setRowHeight(int height) {
- if (height < 0) throw new IllegalArgumentException();
- mItemLengthSecondaryRequested = height;
+ if (height >= 0 || height == ViewGroup.LayoutParams.WRAP_CONTENT) {
+ mRowSizeSecondaryRequested = height;
+ } else {
+ throw new IllegalArgumentException("Invalid row height: " + height);
+ }
}
public void setItemMargin(int margin) {
@@ -643,6 +689,15 @@
return p.getOpticalTop(v) + p.getAlignY();
}
+ private void setViewLayoutForward(View v, boolean layoutForward) {
+ LayoutParams p = (LayoutParams) v.getLayoutParams();
+ p.mLayoutForward = layoutForward;
+ }
+
+ private boolean getIsViewLayoutForward(View v) {
+ return ((LayoutParams) v.getLayoutParams()).mLayoutForward;
+ }
+
/**
* Re-initialize data structures for a data change or handling invisible
* selection. The method tries its best to preserve position information so
@@ -733,6 +788,8 @@
} else {
// otherwise recreate data structure
mRows = new StaggeredGrid.Row[mNumRows];
+ mRowSizeSecondary = new int[mNumRows];
+
for (int i = 0; i < mNumRows; i++) {
mRows[i] = new StaggeredGrid.Row();
}
@@ -759,10 +816,110 @@
mFirstVisiblePos = mLastVisiblePos = NO_POSITION;
initScrollController();
+ updateScrollSecondAxis();
return focusPosition;
}
+ private int getRowSizeSecondary(int rowIndex) {
+ if (mFixedRowSizeSecondary != 0) {
+ return mFixedRowSizeSecondary;
+ }
+ if (mRowSizeSecondary == null) {
+ return 0;
+ }
+ return mRowSizeSecondary[rowIndex];
+ }
+
+ private int getRowStartSecondary(int rowIndex) {
+ int start = 0;
+ for (int i = 0; i < rowIndex; i++) {
+ start += getRowSizeSecondary(i) + mMarginSecondary;
+ }
+ return start;
+ }
+
+ private int getSizeSecondary() {
+ return getRowStartSecondary(mNumRows - 1) + getRowSizeSecondary(mNumRows - 1);
+ }
+
+ private boolean processRowSizeSecondary(boolean measure) {
+ if (mFixedRowSizeSecondary != 0) {
+ return false;
+ }
+
+ List<Integer>[] rows = mGrid.getItemPositionsInRows(mFirstVisiblePos, mLastVisiblePos);
+ boolean changed = false;
+
+ for (int rowIndex = 0; rowIndex < mNumRows; rowIndex++) {
+ int rowSize = 0;
+
+ final int rowItemCount = rows[rowIndex].size();
+ if (DEBUG) Log.v(getTag(), "processRowSizeSecondary row " + rowIndex +
+ " rowItemCount " + rowItemCount);
+
+ for (int i = 0; i < rowItemCount; i++) {
+ final int position = rows[rowIndex].get(i);
+ final View view = getViewByPosition(position);
+ if (measure && view.isLayoutRequested()) {
+ measureChild(view, rowIndex);
+ }
+ // If this view isn't visible, we ignore it.
+ if (getOpticalRight(view) < 0 || getOpticalLeft(view) > getWidth() ||
+ getOpticalBottom(view) < 0 || getOpticalTop(view) > getHeight()) {
+ continue;
+ }
+ final int secondarySize = mOrientation == HORIZONTAL ?
+ view.getMeasuredHeight() : view.getMeasuredWidth();
+ if (secondarySize > rowSize) {
+ rowSize = secondarySize;
+ }
+ }
+ if (DEBUG) Log.v(getTag(), "row " + rowIndex + " rowItemCount " + rowItemCount +
+ " rowSize " + rowSize);
+
+ if (mRowSizeSecondary[rowIndex] != rowSize) {
+ if (DEBUG) Log.v(getTag(), "row size secondary changed: " + mRowSizeSecondary[rowIndex] +
+ ", " + rowSize);
+
+ mRowSizeSecondary[rowIndex] = rowSize;
+ changed = true;
+ }
+ }
+
+ return changed;
+ }
+
+ /**
+ * Checks if we need to update row secondary sizes.
+ */
+ private void updateRowSecondarySizeRefresh() {
+ mRowSecondarySizeRefresh = processRowSizeSecondary(false);
+ if (mRowSecondarySizeRefresh) {
+ if (DEBUG) Log.v(getTag(), "mRowSecondarySizeRefresh now set");
+ forceRequestLayout();
+ }
+ }
+
+ private void forceRequestLayout() {
+ if (DEBUG) Log.v(getTag(), "forceRequestLayout");
+ // RecyclerView prevents us from requesting layout in many cases
+ // (during layout, during scroll, etc.)
+ // For secondary row size wrap_content support we currently need a
+ // second layout pass to update the measured size after having measured
+ // and added child views in layoutChildren.
+ // Force the second layout by posting a delayed runnable.
+ // TODO: investigate allowing a second layout pass,
+ // or move child add/measure logic to the measure phase.
+ mBaseGridView.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.v(getTag(), "request Layout from runnable");
+ requestLayout();
+ }
+ });
+ }
+
@Override
public void onMeasure(int widthSpec, int heightSpec) {
int sizePrimary, sizeSecondary, modeSecondary, paddingSecondary;
@@ -778,52 +935,81 @@
modeSecondary = MeasureSpec.getMode(widthSpec);
paddingSecondary = getPaddingLeft() + getPaddingRight();
}
- switch (modeSecondary) {
- case MeasureSpec.UNSPECIFIED:
- if (mItemLengthSecondaryRequested == 0) {
- if (mOrientation == HORIZONTAL) {
- throw new IllegalStateException("Must specify rowHeight or view height");
- } else {
- throw new IllegalStateException("Must specify columnWidth or view width");
+ if (DEBUG) Log.v(getTag(), "onMeasure widthSpec " + Integer.toHexString(widthSpec) +
+ " heightSpec " + Integer.toHexString(heightSpec) +
+ " modeSecondary " + Integer.toHexString(modeSecondary) +
+ " sizeSecondary " + sizeSecondary + " " + this);
+
+ mMaxSizeSecondary = sizeSecondary;
+
+ if (mRowSizeSecondaryRequested == ViewGroup.LayoutParams.WRAP_CONTENT) {
+ mNumRows = mNumRowsRequested == 0 ? 1 : mNumRowsRequested;
+ mFixedRowSizeSecondary = 0;
+
+ // Measure all current children and update cached row heights
+ if (mGrid != null) {
+ processRowSizeSecondary(true);
+ }
+
+ switch (modeSecondary) {
+ case MeasureSpec.UNSPECIFIED:
+ measuredSizeSecondary = getSizeSecondary() + paddingSecondary;
+ break;
+ case MeasureSpec.AT_MOST:
+ measuredSizeSecondary = Math.min(getSizeSecondary() + paddingSecondary,
+ mMaxSizeSecondary);
+ break;
+ case MeasureSpec.EXACTLY:
+ measuredSizeSecondary = mMaxSizeSecondary;
+ break;
+ default:
+ throw new IllegalStateException("wrong spec");
+ }
+
+ } else {
+ switch (modeSecondary) {
+ case MeasureSpec.UNSPECIFIED:
+ if (mRowSizeSecondaryRequested == 0) {
+ if (mOrientation == HORIZONTAL) {
+ throw new IllegalStateException("Must specify rowHeight or view height");
+ } else {
+ throw new IllegalStateException("Must specify columnWidth or view width");
+ }
}
- }
- mItemLengthSecondary = mItemLengthSecondaryRequested;
- if (mNumRowsRequested == 0) {
- mNumRows = 1;
- } else {
- mNumRows = mNumRowsRequested;
- }
- measuredSizeSecondary = mItemLengthSecondary * mNumRows + mMarginSecondary
- * (mNumRows - 1) + paddingSecondary;
- break;
- case MeasureSpec.AT_MOST:
- case MeasureSpec.EXACTLY:
- if (mNumRowsRequested == 0 && mItemLengthSecondaryRequested == 0) {
- mNumRows = 1;
- mItemLengthSecondary = sizeSecondary - paddingSecondary;
- } else if (mNumRowsRequested == 0) {
- mItemLengthSecondary = mItemLengthSecondaryRequested;
- mNumRows = (sizeSecondary + mMarginSecondary)
- / (mItemLengthSecondaryRequested + mMarginSecondary);
- } else if (mItemLengthSecondaryRequested == 0) {
- mNumRows = mNumRowsRequested;
- mItemLengthSecondary = (sizeSecondary - paddingSecondary - mMarginSecondary
- * (mNumRows - 1)) / mNumRows;
- } else {
- mNumRows = mNumRowsRequested;
- mItemLengthSecondary = mItemLengthSecondaryRequested;
- }
- measuredSizeSecondary = sizeSecondary;
- if (modeSecondary == MeasureSpec.AT_MOST) {
- int childrenSize = mItemLengthSecondary * mNumRows + mMarginSecondary
+ mFixedRowSizeSecondary = mRowSizeSecondaryRequested;
+ mNumRows = mNumRowsRequested == 0 ? 1 : mNumRowsRequested;
+ measuredSizeSecondary = mFixedRowSizeSecondary * mNumRows + mMarginSecondary
* (mNumRows - 1) + paddingSecondary;
- if (childrenSize < measuredSizeSecondary) {
- measuredSizeSecondary = childrenSize;
+ break;
+ case MeasureSpec.AT_MOST:
+ case MeasureSpec.EXACTLY:
+ if (mNumRowsRequested == 0 && mRowSizeSecondaryRequested == 0) {
+ mNumRows = 1;
+ mFixedRowSizeSecondary = sizeSecondary - paddingSecondary;
+ } else if (mNumRowsRequested == 0) {
+ mFixedRowSizeSecondary = mRowSizeSecondaryRequested;
+ mNumRows = (sizeSecondary + mMarginSecondary)
+ / (mRowSizeSecondaryRequested + mMarginSecondary);
+ } else if (mRowSizeSecondaryRequested == 0) {
+ mNumRows = mNumRowsRequested;
+ mFixedRowSizeSecondary = (sizeSecondary - paddingSecondary - mMarginSecondary
+ * (mNumRows - 1)) / mNumRows;
+ } else {
+ mNumRows = mNumRowsRequested;
+ mFixedRowSizeSecondary = mRowSizeSecondaryRequested;
}
+ measuredSizeSecondary = sizeSecondary;
+ if (modeSecondary == MeasureSpec.AT_MOST) {
+ int childrenSize = mFixedRowSizeSecondary * mNumRows + mMarginSecondary
+ * (mNumRows - 1) + paddingSecondary;
+ if (childrenSize < measuredSizeSecondary) {
+ measuredSizeSecondary = childrenSize;
+ }
+ }
+ break;
+ default:
+ throw new IllegalStateException("wrong spec");
}
- break;
- default:
- throw new IllegalStateException("wrong spec");
}
if (mOrientation == HORIZONTAL) {
setMeasuredDimension(sizePrimary, measuredSizeSecondary);
@@ -833,28 +1019,38 @@
if (DEBUG) {
Log.v(getTag(), "onMeasure sizePrimary " + sizePrimary +
" measuredSizeSecondary " + measuredSizeSecondary +
- " mItemLengthSecondary " + mItemLengthSecondary +
+ " mFixedRowSizeSecondary " + mFixedRowSizeSecondary +
" mNumRows " + mNumRows);
}
}
- private void measureChild(View child) {
+ private void measureChild(View child, int rowIndex) {
final ViewGroup.LayoutParams lp = child.getLayoutParams();
-
+ final int secondarySpec = (mRowSizeSecondaryRequested == ViewGroup.LayoutParams.WRAP_CONTENT) ?
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) :
+ MeasureSpec.makeMeasureSpec(mFixedRowSizeSecondary, MeasureSpec.EXACTLY);
int widthSpec, heightSpec;
+
if (mOrientation == HORIZONTAL) {
widthSpec = ViewGroup.getChildMeasureSpec(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, lp.width);
- heightSpec = ViewGroup.getChildMeasureSpec(MeasureSpec.makeMeasureSpec(
- mItemLengthSecondary, MeasureSpec.EXACTLY), 0, lp.height);
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ 0, lp.width);
+ heightSpec = ViewGroup.getChildMeasureSpec(secondarySpec, 0, lp.height);
} else {
heightSpec = ViewGroup.getChildMeasureSpec(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, lp.height);
- widthSpec = ViewGroup.getChildMeasureSpec(MeasureSpec.makeMeasureSpec(
- mItemLengthSecondary, MeasureSpec.EXACTLY), 0, lp.width);
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ 0, lp.height);
+ widthSpec = ViewGroup.getChildMeasureSpec(secondarySpec, 0, lp.width);
}
child.measure(widthSpec, heightSpec);
+
+ if (DEBUG) Log.v(getTag(), "measureChild secondarySpec " + Integer.toHexString(secondarySpec) +
+ " widthSpec " + Integer.toHexString(widthSpec) +
+ " heightSpec " + Integer.toHexString(heightSpec) +
+ " measuredWidth " + child.getMeasuredWidth() +
+ " measuredHeight " + child.getMeasuredHeight());
+ if (DEBUG) Log.v(getTag(), "child lp width " + lp.width + " height " + lp.height);
}
private StaggeredGrid.Provider mGridProvider = new StaggeredGrid.Provider() {
@@ -883,7 +1079,7 @@
addView(v, 0);
}
- measureChild(v);
+ measureChild(v, rowIndex);
int length = mOrientation == HORIZONTAL ? v.getMeasuredWidth() : v.getMeasuredHeight();
int start, end;
@@ -923,22 +1119,25 @@
mFirstVisiblePos--;
}
}
- int startSecondary = rowIndex * (mItemLengthSecondary + mMarginSecondary);
- layoutChild(v, start - mScrollOffsetPrimary, end - mScrollOffsetPrimary,
- startSecondary - mScrollOffsetSecondary);
+ if (DEBUG) Log.v(getTag(), "start " + start + " end " + end);
+ int startSecondary = getRowStartSecondary(rowIndex) - mScrollOffsetSecondary;
+ layoutChild(rowIndex, v, start - mScrollOffsetPrimary, end - mScrollOffsetPrimary,
+ startSecondary);
if (DEBUG) {
Log.d(getTag(), "addView " + index + " " + v);
}
updateScrollMin();
updateScrollMax();
+
+ setViewLayoutForward(v, append);
}
};
- private void layoutChild(View v, int start, int end, int startSecondary) {
- int measuredSecondary = mOrientation == HORIZONTAL ? v.getMeasuredHeight()
- : v.getMeasuredWidth();
- if (measuredSecondary > mItemLengthSecondary) {
- measuredSecondary = mItemLengthSecondary;
+ private void layoutChild(int rowIndex, View v, int start, int end, int startSecondary) {
+ int sizeSecondary = mOrientation == HORIZONTAL ? v.getMeasuredHeight()
+ : v.getMeasuredWidth();
+ if (mFixedRowSizeSecondary > 0) {
+ sizeSecondary = Math.min(sizeSecondary, mFixedRowSizeSecondary);
}
final int verticalGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
final int horizontalGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
@@ -947,22 +1146,22 @@
// do nothing
} else if (mOrientation == HORIZONTAL && verticalGravity == Gravity.BOTTOM
|| mOrientation == VERTICAL && horizontalGravity == Gravity.RIGHT) {
- startSecondary += mItemLengthSecondary - measuredSecondary;
+ startSecondary += getRowSizeSecondary(rowIndex) - sizeSecondary;
} else if (mOrientation == HORIZONTAL && verticalGravity == Gravity.CENTER_VERTICAL
|| mOrientation == VERTICAL && horizontalGravity == Gravity.CENTER_HORIZONTAL) {
- startSecondary += (mItemLengthSecondary - measuredSecondary) / 2;
+ startSecondary += (getRowSizeSecondary(rowIndex) - sizeSecondary) / 2;
}
int left, top, right, bottom;
if (mOrientation == HORIZONTAL) {
left = start;
top = startSecondary;
right = end;
- bottom = startSecondary + measuredSecondary;
+ bottom = startSecondary + sizeSecondary;
} else {
top = start;
left = startSecondary;
bottom = end;
- right = startSecondary + measuredSecondary;
+ right = startSecondary + sizeSecondary;
}
v.layout(left, top, right, bottom);
updateChildOpticalInsets(v, left, top, right, bottom);
@@ -1148,35 +1347,6 @@
}
}
- /**
- * Relayout and re-positioning child for a possible new size and/or a new
- * start.
- *
- * @param view View to measure and layout.
- * @param start New start of the view or Integer.MIN_VALUE for not change.
- * @return New start of next view.
- */
- private int updateChildView(View view, int start, int startSecondary) {
- if (start == Integer.MIN_VALUE) {
- start = getViewMin(view);
- }
- int end;
- if (mOrientation == HORIZONTAL) {
- if (view.isLayoutRequested() || view.getMeasuredHeight() != mItemLengthSecondary) {
- measureChild(view);
- }
- end = start + view.getMeasuredWidth();
- } else {
- if (view.isLayoutRequested() || view.getMeasuredWidth() != mItemLengthSecondary) {
- measureChild(view);
- }
- end = start + view.getMeasuredHeight();
- }
-
- layoutChild(view, start, end, startSecondary);
- return end + mMarginPrimary;
- }
-
// Fast layout when there is no structure change, adapter change, etc.
protected void fastRelayout() {
initScrollController();
@@ -1186,12 +1356,63 @@
// relayout and repositioning views on each row
for (int i = 0; i < mNumRows; i++) {
List<Integer> row = rows[i];
- int start = Integer.MIN_VALUE;
- int startSecondary =
- i * (mItemLengthSecondary + mMarginSecondary) - mScrollOffsetSecondary;
+ final int startSecondary = getRowStartSecondary(i) - mScrollOffsetSecondary;
for (int j = 0, size = row.size(); j < size; j++) {
- int position = row.get(j);
- start = updateChildView(getViewByPosition(position), start, startSecondary);
+ final int position = row.get(j);
+ final View view = getViewByPosition(position);
+ final boolean layoutForward = getIsViewLayoutForward(view);
+ int primaryDelta, start, end;
+
+ if (mOrientation == HORIZONTAL) {
+ final int primarySize = view.getMeasuredWidth();
+ if (view.isLayoutRequested()) {
+ measureChild(view, i);
+ }
+ if (layoutForward) {
+ start = getViewMin(view);
+ end = start + view.getMeasuredWidth();
+ primaryDelta = view.getMeasuredWidth() - primarySize;
+ if (primaryDelta != 0) {
+ for (int k = j + 1; k < size; k++) {
+ getViewByPosition(row.get(k)).offsetLeftAndRight(primaryDelta);
+ }
+ }
+ } else {
+ end = getViewMax(view);
+ start = end - view.getMeasuredWidth();
+ primaryDelta = primarySize - view.getMeasuredWidth();
+ if (primaryDelta != 0) {
+ for (int k = 0; k < j; k++) {
+ getViewByPosition(row.get(k)).offsetLeftAndRight(primaryDelta);
+ }
+ }
+ }
+ } else {
+ final int primarySize = view.getMeasuredHeight();
+ if (view.isLayoutRequested()) {
+ measureChild(view, i);
+ }
+ if (layoutForward) {
+ start = getViewMin(view);
+ end = start + view.getMeasuredHeight();
+ primaryDelta = view.getMeasuredHeight() - primarySize;
+ if (primaryDelta != 0) {
+ for (int k = j + 1; k < size; k++) {
+ getViewByPosition(row.get(k)).offsetTopAndBottom(primaryDelta);
+ }
+ }
+ } else {
+ end = getViewMax(view);
+ start = end - view.getMeasuredHeight();
+ primaryDelta = primarySize - view.getMeasuredHeight();
+ if (primaryDelta != 0) {
+ for (int k = 0; k < j; k++) {
+ getViewByPosition(row.get(k)).offsetTopAndBottom(primaryDelta);
+ }
+ }
+ }
+ }
+ layoutChild(i, view, start, end, startSecondary);
}
}
@@ -1201,6 +1422,7 @@
updateRowsMinMax();
updateScrollMin();
updateScrollMax();
+ updateScrollSecondAxis();
if (mFocusScrollStrategy == BaseGridView.FOCUS_SCROLL_ALIGNED) {
View focusView = getViewByPosition(mFocusPosition == NO_POSITION ? 0 : mFocusPosition);
@@ -1324,6 +1546,12 @@
removeAndRecycleScrap(recycler);
attemptAnimateLayoutChild();
+ if (mRowSecondarySizeRefresh) {
+ mRowSecondarySizeRefresh = false;
+ } else {
+ updateRowSecondarySizeRefresh();
+ }
+
if (!hasDoneFirstLayout) {
dispatchChildSelected();
}
@@ -1388,14 +1616,30 @@
if (mInLayout) {
return da;
}
+
+ int childCount = getChildCount();
+ boolean updated;
+
if (da > 0) {
appendVisibleItems();
- removeInvisibleViewsAtFront();
} else if (da < 0) {
prependVisibleItems();
+ }
+ updated = getChildCount() > childCount;
+ childCount = getChildCount();
+
+ if (da > 0) {
+ removeInvisibleViewsAtFront();
+ } else if (da < 0) {
removeInvisibleViewsAtEnd();
}
+ updated |= getChildCount() < childCount;
+
attemptAnimateLayoutChild();
+ if (updated) {
+ updateRowSecondarySizeRefresh();
+ }
+
mBaseGridView.invalidate();
return da;
}
@@ -1433,6 +1677,11 @@
}
}
+ private void updateScrollSecondAxis() {
+ mWindowAlignment.secondAxis().setMinEdge(0);
+ mWindowAlignment.secondAxis().setMaxEdge(getSizeSecondary());
+ }
+
private void initScrollController() {
mWindowAlignment.horizontal.setSize(getWidth());
mWindowAlignment.horizontal.setPadding(getPaddingLeft(), getPaddingRight());
@@ -1442,15 +1691,9 @@
mWindowAlignment.mainAxis().invalidateScrollMin();
mWindowAlignment.mainAxis().invalidateScrollMax();
- // second axis min/max is determined at initialization, the mainAxis
- // min/max is determined later when we scroll to first or last item
- mWindowAlignment.secondAxis().setMinEdge(0);
- mWindowAlignment.secondAxis().setMaxEdge(mItemLengthSecondary * mNumRows + mMarginSecondary
- * (mNumRows - 1));
-
if (DEBUG) {
- Log.v(getTag(), "initScrollController mSizePrimary " + mSizePrimary + " "
- + " mItemLengthSecondary " + mItemLengthSecondary + " " + mWindowAlignment);
+ Log.v(getTag(), "initScrollController mSizePrimary " + mSizePrimary
+ + " mWindowAlignment " + mWindowAlignment);
}
}
@@ -1773,6 +2016,40 @@
return null;
}
+ boolean hasNextViewInSameRow(int pos) {
+ if (mGrid == null || pos == NO_POSITION) {
+ return false;
+ }
+ final int focusedRow = mGrid.getLocation(pos).row;
+ for (int i = 0, count = getChildCount(); i < count; i++) {
+ int position = getPositionByIndex(i);
+ StaggeredGrid.Location loc = mGrid.getLocation(position);
+ if (loc != null && loc.row == focusedRow) {
+ if (position > pos) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean hasPreviousViewInSameRow(int pos) {
+ if (mGrid == null || pos == NO_POSITION) {
+ return false;
+ }
+ final int focusedRow = mGrid.getLocation(pos).row;
+ for (int i = getChildCount() - 1; i >= 0; i--) {
+ int position = getPositionByIndex(i);
+ StaggeredGrid.Location loc = mGrid.getLocation(position);
+ if (loc != null && loc.row == focusedRow) {
+ if (position < pos) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public boolean onAddFocusables(RecyclerView recyclerView,
ArrayList<View> views, int direction, int focusableMode) {
@@ -2011,6 +2288,8 @@
RecyclerView.Adapter newAdapter) {
mGrid = null;
mRows = null;
+ mRowSizeSecondary = null;
+ mRowSecondarySizeRefresh = false;
super.onAdapterChanged(oldAdapter, newAdapter);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/HorizontalGridView.java b/v17/leanback/src/android/support/v17/leanback/widget/HorizontalGridView.java
index 2024425..03641b9 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/HorizontalGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/HorizontalGridView.java
@@ -27,7 +27,9 @@
import android.support.v17.leanback.R;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.View;
+import android.view.ViewGroup;
/**
* A view that shows items in a horizontal scrolling list. The items come from
@@ -66,7 +68,7 @@
protected void initAttributes(Context context, AttributeSet attrs) {
initBaseGridViewAttributes(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbHorizontalGridView);
- setRowHeight(a.getDimensionPixelSize(R.styleable.lbHorizontalGridView_rowHeight, 0));
+ setRowHeight(a);
setNumRows(a.getInt(R.styleable.lbHorizontalGridView_numberOfRows, 1));
a.recycle();
setWillNotDraw(false);
@@ -74,8 +76,19 @@
mTempPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
}
+ void setRowHeight(TypedArray array) {
+ TypedValue typedValue = array.peekValue(R.styleable.lbHorizontalGridView_rowHeight);
+ int size;
+ if (typedValue != null && typedValue.type == TypedValue.TYPE_DIMENSION) {
+ size = array.getDimensionPixelSize(R.styleable.lbHorizontalGridView_rowHeight, 0);
+ } else {
+ size = array.getInt(R.styleable.lbHorizontalGridView_rowHeight, 0);
+ }
+ setRowHeight(size);
+ }
+
/**
- * Set the number of rows.
+ * Set the number of rows. Defaults to one.
*/
public void setNumRows(int numRows) {
mLayoutManager.setNumRows(numRows);
@@ -84,6 +97,9 @@
/**
* Set the row height.
+ *
+ * @param height May be WRAP_CONTENT, or a size in pixels. If zero,
+ * row height will be fixed based on number of rows and view height.
*/
public void setRowHeight(int height) {
mLayoutManager.setRowHeight(height);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
index 0de39ab..92b1288 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
@@ -76,6 +76,8 @@
}
}
+ private int mRowHeight;
+ private int mExpandedRowHeight;
private PresenterSelector mHoverCardPresenterSelector;
private int mZoomFactor;
private boolean mShadowEnabled = true;
@@ -103,6 +105,43 @@
}
/**
+ * Sets the row height for rows created by this Presenter. Rows
+ * created before calling this method will not be updated.
+ *
+ * @param rowHeight Row height in pixels, or WRAP_CONTENT, or 0
+ * to use the default height.
+ */
+ public void setRowHeight(int rowHeight) {
+ mRowHeight = rowHeight;
+ }
+
+ /**
+ * Returns the row height for list rows created by this Presenter.
+ */
+ public int getRowHeight() {
+ return mRowHeight;
+ }
+
+ /**
+ * Sets the expanded row height for rows created by this Presenter.
+ * If not set, expanded rows have the same height as unexpanded
+ * rows.
+ *
+ * @param rowHeight The row height in to use when the row is expanded,
+ * in pixels, or WRAP_CONTENT, or 0 to use the default.
+ */
+ public void setExpandedRowHeight(int rowHeight) {
+ mExpandedRowHeight = rowHeight;
+ }
+
+ /**
+ * Returns the expanded row height for rows created by this Presenter.
+ */
+ public int getExpandedRowHeight() {
+ return mExpandedRowHeight != 0 ? mExpandedRowHeight : mRowHeight;
+ }
+
+ /**
* Returns the zoom factor used for focus highlighting.
*/
public final int getZoomFactor() {
@@ -172,6 +211,7 @@
int dimmedColor = rowViewHolder.mColorDimmer.getPaint().getColor();
((ShadowOverlayContainer) viewHolder.itemView).setOverlayColor(dimmedColor);
}
+ viewHolder.itemView.setActivated(rowViewHolder.mExpanded);
}
});
}
@@ -225,6 +265,9 @@
protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
ListRowView rowView = new ListRowView(parent.getContext());
setupFadingEffect(rowView);
+ if (mRowHeight != 0) {
+ rowView.getGridView().setRowHeight(mRowHeight);
+ }
return new ViewHolder(rowView, rowView.getGridView(), this);
}
@@ -270,6 +313,10 @@
protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) {
super.onRowViewExpanded(holder, expanded);
ViewHolder vh = (ViewHolder) holder;
+ if (getRowHeight() != getExpandedRowHeight()) {
+ int newHeight = expanded ? getExpandedRowHeight() : getRowHeight();
+ vh.getGridView().setRowHeight(newHeight);
+ }
vh.getGridView().setFadingLeftEdge(!expanded);
updateFooterViewSwitcher(vh);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
index 787597f..1d56c87 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
@@ -219,6 +219,7 @@
containerView.removeHeaderView(headerView);
}
}
+ vh.view.setActivated(expanded);
}
/**
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridView.java b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridView.java
index 0b3f453..5b10d41 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridView.java
@@ -18,6 +18,8 @@
import android.support.v17.leanback.R;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.ViewGroup;
/**
* A view that shows items in a vertically scrolling list. The items come from
@@ -42,13 +44,24 @@
protected void initAttributes(Context context, AttributeSet attrs) {
initBaseGridViewAttributes(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbVerticalGridView);
- setColumnWidth(a.getDimensionPixelSize(R.styleable.lbVerticalGridView_columnWidth, 0));
+ setColumnWidth(a);
setNumColumns(a.getInt(R.styleable.lbVerticalGridView_numberOfColumns, 1));
a.recycle();
}
+ void setColumnWidth(TypedArray array) {
+ TypedValue typedValue = array.peekValue(R.styleable.lbVerticalGridView_columnWidth);
+ int size;
+ if (typedValue != null && typedValue.type == TypedValue.TYPE_DIMENSION) {
+ size = array.getDimensionPixelSize(R.styleable.lbVerticalGridView_columnWidth, 0);
+ } else {
+ size = array.getInt(R.styleable.lbVerticalGridView_columnWidth, 0);
+ }
+ setColumnWidth(size);
+ }
+
/**
- * Set the number of columns.
+ * Set the number of columns. Defaults to one.
*/
public void setNumColumns(int numColumns) {
mLayoutManager.setNumRows(numColumns);
@@ -57,6 +70,9 @@
/**
* Set the column width.
+ *
+ * @param width May be WRAP_CONTENT, or a size in pixels. If zero,
+ * column width will be fixed based on number of columns and view width.
*/
public void setColumnWidth(int width) {
mLayoutManager.setRowHeight(width);
diff --git a/v4/api20/android/support/v4/app/NotificationCompatApi20.java b/v4/api20/android/support/v4/app/NotificationCompatApi20.java
index e737695..2e6be70 100644
--- a/v4/api20/android/support/v4/app/NotificationCompatApi20.java
+++ b/v4/api20/android/support/v4/app/NotificationCompatApi20.java
@@ -23,6 +23,8 @@
import android.os.Bundle;
import android.widget.RemoteViews;
+import java.util.ArrayList;
+
class NotificationCompatApi20 {
public static class Builder implements NotificationBuilderWithBuilderAccessor,
NotificationBuilderWithActions {
@@ -34,7 +36,7 @@
PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
int mProgressMax, int mProgress, boolean mProgressIndeterminate,
boolean useChronometer, int priority, CharSequence subText, boolean localOnly,
- Bundle extras) {
+ String category, ArrayList<String> people, Bundle extras) {
b = new Notification.Builder(context)
.setWhen(n.when)
.setSmallIcon(n.icon, n.iconLevel)
@@ -61,7 +63,11 @@
.setPriority(priority)
.setProgress(mProgressMax, mProgress, mProgressIndeterminate)
.setLocalOnly(localOnly)
+ .setCategory(category)
.setExtras(extras);
+ for (String person: people) {
+ b.addPerson(person);
+ }
}
@Override
diff --git a/v4/java/android/support/v4/app/NotificationCompat.java b/v4/java/android/support/v4/app/NotificationCompat.java
index 5ea5db6..71e98f0 100644
--- a/v4/java/android/support/v4/app/NotificationCompat.java
+++ b/v4/java/android/support/v4/app/NotificationCompat.java
@@ -360,7 +360,7 @@
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
b.mProgressMax, b.mProgress, b.mProgressIndeterminate,
- b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras);
+ b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mPeople, b.mExtras);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
return builder.build();
@@ -384,7 +384,8 @@
b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
b.mProgressMax, b.mProgress, b.mProgressIndeterminate,
- b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras);
+ b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mCategory,
+ b.mPeople, b.mExtras);
addActionsToBuilder(builder, b.mActions);
addStyleToBuilderJellybean(builder, b.mStyle);
return builder.build();
@@ -439,8 +440,10 @@
}
static {
- // TODO: Add NotificationCompatApi20 when SDK_INT is incremented.
- if (Build.VERSION.SDK_INT >= 19) {
+ // TODO: Replace this if clause when SDK_INT is incremented to 20.
+ if (Build.VERSION.RELEASE.equals("L")) {
+ IMPL = new NotificationCompatImplApi20();
+ } else if (Build.VERSION.SDK_INT >= 19) {
IMPL = new NotificationCompatImplKitKat();
} else if (Build.VERSION.SDK_INT >= 16) {
IMPL = new NotificationCompatImplJellybean();
@@ -495,9 +498,11 @@
boolean mProgressIndeterminate;
ArrayList<Action> mActions = new ArrayList<Action>();
boolean mLocalOnly = false;
+ String mCategory;
Bundle mExtras;
Notification mNotification = new Notification();
+ public ArrayList<String> mPeople;
/**
* Constructor.
@@ -517,6 +522,7 @@
mNotification.when = System.currentTimeMillis();
mNotification.audioStreamType = Notification.STREAM_DEFAULT;
mPriority = PRIORITY_DEFAULT;
+ mPeople = new ArrayList<String>();
}
/**
@@ -806,6 +812,18 @@
}
/**
+ * Set the notification category.
+ *
+ * <p>Must be one of the predefined notification categories (see the <code>CATEGORY_*</code>
+ * constants in {@link Notification}) that best describes this notification.
+ * May be used by the system for ranking and filtering.
+ */
+ public Builder setCategory(String category) {
+ mCategory = category;
+ return this;
+ }
+
+ /**
* Set the default notification options that will be used.
* <p>
* The value should be one or more of the following fields combined with
@@ -854,6 +872,16 @@
}
/**
+ * Add a person that is relevant to this notification.
+ *
+ * @see Notification#EXTRA_PEOPLE
+ */
+ public Builder addPerson(String handle) {
+ mPeople.add(handle);
+ return this;
+ }
+
+ /**
* Merge additional metadata into this notification.
*
* <p>Values within the Bundle will replace existing extras values in this Builder.
diff --git a/v4/java/android/support/v4/graphics/BitmapCompat.java b/v4/java/android/support/v4/graphics/BitmapCompat.java
new file mode 100644
index 0000000..6c97a0d
--- /dev/null
+++ b/v4/java/android/support/v4/graphics/BitmapCompat.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.graphics;
+
+import android.graphics.Bitmap;
+
+/**
+ * Helper for accessing features in {@link android.graphics.Bitmap}
+ * introduced after API level 4 in a backwards compatible fashion.
+ */
+public class BitmapCompat {
+ /**
+ * Interface for the full API.
+ */
+ interface BitmapImpl {
+ public boolean hasMipMap(Bitmap bitmap);
+ public void setHasMipMap(Bitmap bitmap, boolean hasMipMap);
+ }
+
+ /**
+ * Interface implementation that doesn't use anything about v4 APIs.
+ */
+ static class BaseBitmapImpl implements BitmapImpl {
+ @Override
+ public boolean hasMipMap(Bitmap bitmap) {
+ return false;
+ }
+
+ @Override
+ public void setHasMipMap(Bitmap bitmap, boolean hasMipMap) {
+ }
+ }
+
+ static class JbMr2BitmapCompatImpl extends BaseBitmapImpl {
+ @Override
+ public boolean hasMipMap(Bitmap bitmap){
+ return BitmapCompatJellybeanMR2.hasMipMap(bitmap);
+ }
+
+ @Override
+ public void setHasMipMap(Bitmap bitmap, boolean hasMipMap) {
+ BitmapCompatJellybeanMR2.setHasMipMap(bitmap, hasMipMap);
+ }
+ }
+
+ /**
+ * Select the correct implementation to use for the current platform.
+ */
+ static final BitmapImpl IMPL;
+ static {
+ final int version = android.os.Build.VERSION.SDK_INT;
+ if (version >= 18) {
+ IMPL = new JbMr2BitmapCompatImpl();
+ } else {
+ IMPL = new BaseBitmapImpl();
+ }
+ }
+
+ public static boolean hasMipMap(Bitmap bitmap) {
+ return IMPL.hasMipMap(bitmap);
+ }
+
+ public static void setHasMipMap(Bitmap bitmap, boolean hasMipMap) {
+ IMPL.setHasMipMap(bitmap, hasMipMap);
+ }
+}
\ No newline at end of file
diff --git a/v4/java/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java b/v4/java/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
new file mode 100644
index 0000000..a8174a3
--- /dev/null
+++ b/v4/java/android/support/v4/graphics/drawable/RoundedBitmapDrawable.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.graphics.drawable;
+
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+import android.support.v4.graphics.BitmapCompat;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * A Drawable that wraps a bitmap and can be drawn with rounded corners. You can create a
+ * RoundedBitmapDrawable from a file path, an input stream, or from a
+ * {@link android.graphics.Bitmap} object.
+ * <p>
+ * Also see the {@link android.graphics.Bitmap} class, which handles the management and
+ * transformation of raw bitmap graphics, and should be used when drawing to a
+ * {@link android.graphics.Canvas}.
+ * </p>
+ */
+public class RoundedBitmapDrawable extends Drawable {
+
+ private static final String TAG = "RoundedBitmapDrawable";
+ private static final int DEFAULT_PAINT_FLAGS =
+ Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
+ private Bitmap mBitmap;
+ private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+ private int mGravity = Gravity.FILL;
+ private Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS);
+ private BitmapShader mBitmapShader;
+ private float mCornerRadius;
+
+ private final Rect mDstRect = new Rect(); // Gravity.apply() sets this
+ private final RectF mDstRectF = new RectF();
+
+ private boolean mApplyGravity = true;
+
+ // These are scaled to match the target density.
+ private int mBitmapWidth;
+ private int mBitmapHeight;
+
+
+ /**
+ * Returns a new drawable by creating it from a bitmap, setting initial target density based on
+ * the display metrics of the resources.
+ */
+ public static RoundedBitmapDrawable createRoundedBitmapDrawable(Resources res, Bitmap bitmap) {
+ return new RoundedBitmapDrawable(res, bitmap);
+ }
+
+ /**
+ * Returns a new drawable, creating it by opening a given file path and decoding the bitmap.
+ */
+ public static RoundedBitmapDrawable createRoundedBitmapDrawable(Resources res,
+ String filepath) {
+ final RoundedBitmapDrawable drawable =
+ createRoundedBitmapDrawable(res, BitmapFactory.decodeFile(filepath));
+ if (drawable.mBitmap == null) {
+ Log.w(TAG, "BitmapDrawable cannot decode " + filepath);
+ }
+ return drawable;
+ }
+
+
+ /**
+ * Returns a new drawable, creating it by decoding a bitmap from the given input stream.
+ */
+ public static RoundedBitmapDrawable createRoundedBitmapDrawable(Resources res,
+ java.io.InputStream is) {
+ final RoundedBitmapDrawable drawable =
+ createRoundedBitmapDrawable(res, BitmapFactory.decodeStream(is));
+ if (drawable.mBitmap == null) {
+ Log.w(TAG, "BitmapDrawable cannot decode " + is);
+ }
+ return drawable;
+ }
+
+ /**
+ * Returns the paint used to render this drawable.
+ */
+ public final Paint getPaint() {
+ return mPaint;
+ }
+
+ /**
+ * Returns the bitmap used by this drawable to render. May be null.
+ */
+ public final Bitmap getBitmap() {
+ return mBitmap;
+ }
+
+ private void computeBitmapSize() {
+ mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
+ mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
+ }
+
+ /**
+ * Set the density scale at which this drawable will be rendered. This
+ * method assumes the drawable will be rendered at the same density as the
+ * specified canvas.
+ *
+ * @param canvas The Canvas from which the density scale must be obtained.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(Canvas canvas) {
+ setTargetDensity(canvas.getDensity());
+ }
+
+ /**
+ * Set the density scale at which this drawable will be rendered.
+ *
+ * @param metrics The DisplayMetrics indicating the density scale for this drawable.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(DisplayMetrics metrics) {
+ setTargetDensity(metrics.densityDpi);
+ }
+
+ /**
+ * Set the density at which this drawable will be rendered.
+ *
+ * @param density The density scale for this drawable.
+ *
+ * @see android.graphics.Bitmap#setDensity(int)
+ * @see android.graphics.Bitmap#getDensity()
+ */
+ public void setTargetDensity(int density) {
+ if (mTargetDensity != density) {
+ mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+ if (mBitmap != null) {
+ computeBitmapSize();
+ }
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Get the gravity used to position/stretch the bitmap within its bounds.
+ *
+ * @return the gravity applied to the bitmap
+ *
+ * @see android.view.Gravity
+ */
+ public int getGravity() {
+ return mGravity;
+ }
+
+ /**
+ * Set the gravity used to position/stretch the bitmap within its bounds.
+ *
+ * @param gravity the gravity
+ *
+ * @see android.view.Gravity
+ */
+ public void setGravity(int gravity) {
+ if (mGravity != gravity) {
+ mGravity = gravity;
+ mApplyGravity = true;
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Enables or disables the mipmap hint for this drawable's bitmap.
+ * See {@link Bitmap#setHasMipMap(boolean)} for more information.
+ *
+ * If the bitmap is null, or the current API version does not support setting a mipmap hint,
+ * calling this method has no effect.
+ *
+ * @param mipMap True if the bitmap should use mipmaps, false otherwise.
+ *
+ * @see #hasMipMap()
+ */
+ public void setMipMap(boolean mipMap) {
+ if (mBitmap != null) {
+ BitmapCompat.setHasMipMap(mBitmap, mipMap);
+ invalidateSelf();
+ }
+ }
+
+ /**
+ * Indicates whether the mipmap hint is enabled on this drawable's bitmap.
+ *
+ * @return True if the mipmap hint is set, false otherwise. If the bitmap
+ * is null, this method always returns false.
+ *
+ * @see #setMipMap(boolean)
+ */
+ public boolean hasMipMap() {
+ return mBitmap != null && BitmapCompat.hasMipMap(mBitmap);
+ }
+
+ /**
+ * Enables or disables anti-aliasing for this drawable. Anti-aliasing affects
+ * the edges of the bitmap only so it applies only when the drawable is rotated.
+ *
+ * @param aa True if the bitmap should be anti-aliased, false otherwise.
+ *
+ * @see #hasAntiAlias()
+ */
+ public void setAntiAlias(boolean aa) {
+ mPaint.setAntiAlias(aa);
+ invalidateSelf();
+ }
+
+ /**
+ * Indicates whether anti-aliasing is enabled for this drawable.
+ *
+ * @return True if anti-aliasing is enabled, false otherwise.
+ *
+ * @see #setAntiAlias(boolean)
+ */
+ public boolean hasAntiAlias() {
+ return mPaint.isAntiAlias();
+ }
+
+ @Override
+ public void setFilterBitmap(boolean filter) {
+ mPaint.setFilterBitmap(filter);
+ invalidateSelf();
+ }
+
+ @Override
+ public void setDither(boolean dither) {
+ mPaint.setDither(dither);
+ invalidateSelf();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ final Bitmap bitmap = mBitmap;
+ if (bitmap == null) {
+ return;
+ }
+
+ final Paint paint = mPaint;
+
+ final Shader shader = paint.getShader();
+ if (shader == null) {
+ if (mApplyGravity) {
+ GravityCompat.apply(mGravity, mBitmapWidth, mBitmapHeight,
+ getBounds(), mDstRect, ViewCompat.LAYOUT_DIRECTION_LTR);
+ mDstRectF.set(mDstRect);
+ mApplyGravity = false;
+ }
+
+ canvas.drawBitmap(bitmap, null, mDstRect, paint);
+
+ } else {
+ if (mApplyGravity) {
+ copyBounds(mDstRect);
+ mDstRectF.set(mDstRect);
+ mApplyGravity = false;
+ }
+
+ canvas.drawRoundRect(mDstRectF, mCornerRadius, mCornerRadius, paint);
+ }
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ final int oldAlpha = mPaint.getAlpha();
+ if (alpha != oldAlpha) {
+ mPaint.setAlpha(alpha);
+ invalidateSelf();
+ }
+ }
+
+ public int getAlpha() {
+ return mPaint.getAlpha();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ mPaint.setColorFilter(cf);
+ invalidateSelf();
+ }
+
+ public ColorFilter getColorFilter() {
+ return mPaint.getColorFilter();
+ }
+
+ /**
+ * Sets the corner radius to be applied when drawing the bitmap.
+ */
+ public void setCornerRadius(float cornerRadius) {
+ if (isGreaterThanZero(cornerRadius)) {
+ mPaint.setShader(mBitmapShader);
+ } else {
+ mPaint.setShader(null);
+ }
+ mCornerRadius = cornerRadius;
+ }
+
+ /**
+ * @return The corner radius applied when drawing the bitmap.
+ */
+ public float getCornerRadius() {
+ return mCornerRadius;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mBitmapWidth;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mBitmapHeight;
+ }
+
+ @Override
+ public int getOpacity() {
+ if (mGravity != Gravity.FILL) {
+ return PixelFormat.TRANSLUCENT;
+ }
+ Bitmap bm = mBitmap;
+ return (bm == null
+ || bm.hasAlpha()
+ || mPaint.getAlpha() < 255
+ || isGreaterThanZero(mCornerRadius))
+ ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
+ }
+
+ private RoundedBitmapDrawable(Resources res, Bitmap bitmap) {
+ if (res != null) {
+ mTargetDensity = res.getDisplayMetrics().densityDpi;
+ }
+
+ mBitmap = bitmap;
+ if (mBitmap != null) {
+ computeBitmapSize();
+ mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ } else {
+ mBitmapWidth = mBitmapHeight = -1;
+ }
+ }
+
+ private boolean isGreaterThanZero(float toCompare) {
+ return Float.compare(toCompare, +0.0f) > 0;
+ }
+}
diff --git a/v4/java/android/support/v4/media/TransportMediator.java b/v4/java/android/support/v4/media/TransportMediator.java
index 789ea7b..16bf94b 100644
--- a/v4/java/android/support/v4/media/TransportMediator.java
+++ b/v4/java/android/support/v4/media/TransportMediator.java
@@ -84,28 +84,28 @@
public static final int KEYCODE_MEDIA_RECORD = 130;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS
- * RemoveControlClient.FLAG_KEY_MEDIA_PREVIOUS */
+ * RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS */
public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND
- * RemoveControlClient.FLAG_KEY_MEDIA_REWIND */
+ * RemoteControlClient.FLAG_KEY_MEDIA_REWIND */
public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY
- * RemoveControlClient.FLAG_KEY_MEDIA_PLAY */
+ * RemoteControlClient.FLAG_KEY_MEDIA_PLAY */
public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE
- * RemoveControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE */
+ * RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE */
public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE
- * RemoveControlClient.FLAG_KEY_MEDIA_PAUSE */
+ * RemoteControlClient.FLAG_KEY_MEDIA_PAUSE */
public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP
- * RemoveControlClient.FLAG_KEY_MEDIA_STOP */
+ * RemoteControlClient.FLAG_KEY_MEDIA_STOP */
public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD
- * RemoveControlClient.FLAG_KEY_MEDIA_FAST_FORWARD */
+ * RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD */
public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
/** Synonym for {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT
- * RemoveControlClient.FLAG_KEY_MEDIA_NEXT */
+ * RemoteControlClient.FLAG_KEY_MEDIA_NEXT */
public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
static boolean isMediaKey(int keyCode) {
diff --git a/v4/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/v4/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
index 43aab0a..d9fd9b6 100644
--- a/v4/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/v4/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -22,8 +22,6 @@
import android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat;
import android.support.v4.view.ViewCompat;
import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -34,6 +32,85 @@
*/
public class AccessibilityNodeInfoCompat {
+ public static class CollectionInfoCompat {
+ private final Object mInfo;
+
+ private CollectionInfoCompat(Object info) {
+ mInfo = info;
+ }
+
+ public int getColumnCount() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionInfo.getColumnCount(mInfo);
+ }
+
+ public int getRowCount() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionInfo.getRowCount(mInfo);
+ }
+
+ public boolean isHierarchical() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionInfo.isHierarchical(mInfo);
+ }
+ }
+
+ public static class CollectionItemInfoCompat {
+ private final Object mInfo;
+
+ private CollectionItemInfoCompat(Object info) {
+ mInfo = info;
+ }
+
+ public int getColumnIndex() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getColumnIndex(mInfo);
+ }
+
+ public int getColumnSpan() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getColumnSpan(mInfo);
+ }
+
+ public int getRowIndex() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getRowIndex(mInfo);
+ }
+
+ public int getRowSpan() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.getRowSpan(mInfo);
+ }
+
+ public boolean isHeading() {
+ return AccessibilityNodeInfoCompatKitKat.CollectionItemInfo.isHeading(mInfo);
+ }
+ }
+
+ public static class RangeInfoCompat {
+ /** Range type: integer. */
+ public static final int RANGE_TYPE_INT = 0;
+ /** Range type: float. */
+ public static final int RANGE_TYPE_FLOAT = 1;
+ /** Range type: percent with values from zero to one.*/
+ public static final int RANGE_TYPE_PERCENT = 2;
+
+ private final Object mInfo;
+
+ private RangeInfoCompat(Object info) {
+ mInfo = info;
+ }
+
+ public float getCurrent() {
+ return AccessibilityNodeInfoCompatKitKat.RangeInfo.getCurrent(mInfo);
+ }
+
+ public float getMax() {
+ return AccessibilityNodeInfoCompatKitKat.RangeInfo.getMax(mInfo);
+ }
+
+ public float getMin() {
+ return AccessibilityNodeInfoCompatKitKat.RangeInfo.getMin(mInfo);
+ }
+
+ public int getType() {
+ return AccessibilityNodeInfoCompatKitKat.RangeInfo.getType(mInfo);
+ }
+ }
+
static interface AccessibilityNodeInfoImpl {
public Object obtain();
public Object obtain(View source);
@@ -99,6 +176,9 @@
public void setViewIdResourceName(Object info, String viewId);
public int getLiveRegion(Object info);
public void setLiveRegion(Object info, int mode);
+ public Object getCollectionInfo(Object info);
+ public Object getCollectionItemInfo(Object info);
+ public Object getRangeInfo(Object info);
}
static class AccessibilityNodeInfoStubImpl implements AccessibilityNodeInfoImpl {
@@ -421,6 +501,21 @@
public void setLiveRegion(Object info, int mode) {
// No-op
}
+
+ @Override
+ public Object getCollectionInfo(Object info) {
+ return null;
+ }
+
+ @Override
+ public Object getCollectionItemInfo(Object info) {
+ return null;
+ }
+
+ @Override
+ public Object getRangeInfo(Object info) {
+ return null;
+ }
}
static class AccessibilityNodeInfoIcsImpl extends AccessibilityNodeInfoStubImpl {
@@ -750,6 +845,21 @@
public void setLiveRegion(Object info, int mode) {
AccessibilityNodeInfoCompatKitKat.setLiveRegion(info, mode);
}
+
+ @Override
+ public Object getCollectionInfo(Object info) {
+ return AccessibilityNodeInfoCompatKitKat.getCollectionInfo(info);
+ }
+
+ @Override
+ public Object getCollectionItemInfo(Object info) {
+ return AccessibilityNodeInfoCompatKitKat.getCollectionItemInfo(info);
+ }
+
+ @Override
+ public Object getRangeInfo(Object info) {
+ return AccessibilityNodeInfoCompatKitKat.getRangeInfo(info);
+ }
}
static {
@@ -956,6 +1066,22 @@
*/
public static final int ACTION_SET_SELECTION = 0x00020000;
+ /**
+ * Action that sets the text of the node. Performing the action without argument, using <code>
+ * null</code> or empty {@link CharSequence} will clear the text. This action will also put the
+ * cursor at the end of text.
+ * <p>
+ * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
+ * <strong>Example:</strong>
+ * <code><pre><p>
+ * Bundle arguments = new Bundle();
+ * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
+ * "android");
+ * info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
+ * </code></pre></p>
+ */
+ public static final int ACTION_SET_TEXT = 0x00200000;
+
// Action arguments
/**
@@ -1019,6 +1145,18 @@
public static final String ACTION_ARGUMENT_SELECTION_END_INT =
"ACTION_ARGUMENT_SELECTION_END_INT";
+ /**
+ * Argument for specifying the text content to set
+ * <p>
+ * <strong>Type:</strong> CharSequence<br>
+ * <strong>Actions:</strong> {@link #ACTION_SET_TEXT}
+ * </p>
+ *
+ * @see #ACTION_SET_TEXT
+ */
+ public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
+ "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+
// Focus types
/**
@@ -1943,6 +2081,41 @@
IMPL.setLiveRegion(mInfo, mode);
}
+ /**
+ * Gets the collection info if the node is a collection. A collection
+ * child is always a collection item.
+ *
+ * @return The collection info.
+ */
+ public CollectionInfoCompat getCollectionInfo() {
+ Object info = IMPL.getCollectionInfo(mInfo);
+ if (info == null) return null;
+ return new CollectionInfoCompat(info);
+ }
+
+ /**
+ * Gets the collection item info if the node is a collection item. A collection
+ * item is always a child of a collection.
+ *
+ * @return The collection item info.
+ */
+ public CollectionItemInfoCompat getCollectionItemInfo() {
+ Object info = IMPL.getCollectionItemInfo(mInfo);
+ if (info == null) return null;
+ return new CollectionItemInfoCompat(info);
+ }
+
+ /**
+ * Gets the range info if this node is a range.
+ *
+ * @return The range.
+ */
+ public RangeInfoCompat getRangeInfo() {
+ Object info = IMPL.getRangeInfo(mInfo);
+ if (info == null) return null;
+ return new RangeInfoCompat(info);
+ }
+
@Override
public int hashCode() {
return (mInfo == null) ? 0 : mInfo.hashCode();
diff --git a/v4/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java b/v4/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java
new file mode 100644
index 0000000..21f0d49
--- /dev/null
+++ b/v4/jellybean-mr2/android/support/v4/graphics/BitmapCompatJellybeanMR2.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.v4.graphics;
+
+import android.graphics.Bitmap;
+
+class BitmapCompatJellybeanMR2 {
+ public static boolean hasMipMap(Bitmap bitmap) {
+ return bitmap.hasMipMap();
+ }
+
+ public static void setHasMipMap(Bitmap bitmap, boolean hasMipMap) {
+ bitmap.setHasMipMap(hasMipMap);
+ }
+}
diff --git a/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java b/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
index d6959e3..bff8f5c 100644
--- a/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
+++ b/v4/kitkat/android/support/v4/app/NotificationCompatKitKat.java
@@ -23,6 +23,8 @@
import android.os.Bundle;
import android.widget.RemoteViews;
+import java.util.ArrayList;
+
class NotificationCompatKitKat {
public static class Builder implements NotificationBuilderWithBuilderAccessor,
NotificationBuilderWithActions {
@@ -35,7 +37,7 @@
PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
int mProgressMax, int mProgress, boolean mProgressIndeterminate,
boolean useChronometer, int priority, CharSequence subText, boolean localOnly,
- Bundle extras) {
+ ArrayList<String> people, Bundle extras) {
b = new Notification.Builder(context)
.setWhen(n.when)
.setSmallIcon(n.icon, n.iconLevel)
@@ -62,6 +64,10 @@
.setPriority(priority)
.setProgress(mProgressMax, mProgress, mProgressIndeterminate);
mExtras = extras;
+ if (people != null && !people.isEmpty()) {
+ getExtras().putStringArray(Notification.EXTRA_PEOPLE,
+ people.toArray(new String[people.size()]));
+ }
if (localOnly) {
getExtras().putBoolean(NotificationCompatJellybean.EXTRA_LOCAL_ONLY, localOnly);
}
diff --git a/v4/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java b/v4/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
index 618a02d..4f77b8b 100644
--- a/v4/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
+++ b/v4/kitkat/android/support/v4/view/accessibility/AccessibilityNodeInfoCompatKitKat.java
@@ -22,11 +22,77 @@
* KitKat-specific AccessibilityNodeInfo API implementation.
*/
class AccessibilityNodeInfoCompatKitKat {
- public static int getLiveRegion(Object info) {
+ static int getLiveRegion(Object info) {
return ((AccessibilityNodeInfo) info).getLiveRegion();
}
- public static void setLiveRegion(Object info, int mode) {
+ static void setLiveRegion(Object info, int mode) {
((AccessibilityNodeInfo) info).setLiveRegion(mode);
}
+
+ static Object getCollectionInfo(Object info) {
+ return ((AccessibilityNodeInfo) info).getCollectionInfo();
+ }
+
+ static Object getCollectionItemInfo(Object info) {
+ return ((AccessibilityNodeInfo) info).getCollectionItemInfo();
+ }
+
+ static Object getRangeInfo(Object info) {
+ return ((AccessibilityNodeInfo) info).getRangeInfo();
+ }
+
+ static class CollectionInfo {
+ static int getColumnCount(Object info) {
+ return ((AccessibilityNodeInfo.CollectionInfo) info).getColumnCount();
+ }
+
+ static int getRowCount(Object info) {
+ return ((AccessibilityNodeInfo.CollectionInfo) info).getRowCount();
+ }
+
+ static boolean isHierarchical(Object info) {
+ return ((AccessibilityNodeInfo.CollectionInfo) info).isHierarchical();
+ }
+ }
+
+ static class CollectionItemInfo {
+ static int getColumnIndex(Object info) {
+ return ((AccessibilityNodeInfo.CollectionItemInfo) info).getColumnIndex();
+ }
+
+ static int getColumnSpan(Object info) {
+ return ((AccessibilityNodeInfo.CollectionItemInfo) info).getColumnSpan();
+ }
+
+ static int getRowIndex(Object info) {
+ return ((AccessibilityNodeInfo.CollectionItemInfo) info).getRowIndex();
+ }
+
+ static int getRowSpan(Object info) {
+ return ((AccessibilityNodeInfo.CollectionItemInfo) info).getRowSpan();
+ }
+
+ static boolean isHeading(Object info) {
+ return ((AccessibilityNodeInfo.CollectionItemInfo) info).isHeading();
+ }
+ }
+
+ static class RangeInfo {
+ static float getCurrent(Object info) {
+ return ((AccessibilityNodeInfo.RangeInfo) info).getCurrent();
+ }
+
+ static float getMax(Object info) {
+ return ((AccessibilityNodeInfo.RangeInfo) info).getMax();
+ }
+
+ static float getMin(Object info) {
+ return ((AccessibilityNodeInfo.RangeInfo) info).getMin();
+ }
+
+ static int getType(Object info) {
+ return ((AccessibilityNodeInfo.RangeInfo) info).getType();
+ }
+ }
}
diff --git a/v7/appcompat/res/values-af/strings.xml b/v7/appcompat/res/values-af/strings.xml
new file mode 100644
index 0000000..f7348c4
--- /dev/null
+++ b/v7/appcompat/res/values-af/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Klaar"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeer tuis"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigeer op"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Nog opsies"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Soek"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Soeknavraag"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Vee navraag uit"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Dien navraag in"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Stemsoektog"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Kies \'n program"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Sien alles"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Deel met %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Deel met"</string>
+</resources>
diff --git a/v7/appcompat/res/values-am/strings.xml b/v7/appcompat/res/values-am/strings.xml
new file mode 100644
index 0000000..e849b31
--- /dev/null
+++ b/v7/appcompat/res/values-am/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"ተከናውኗል"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"ወደ መነሻ ይዳስሱ"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ወደ ላይ ይዳስሱ"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ተጨማሪ አማራጮች"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"ፍለጋ"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"የፍለጋ ጥያቄ"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"መጠይቅ አጽዳ"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"መጠይቅ ያስረክቡ"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"የድምፅ ፍለጋ"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"መተግበሪያ ይምረጡ"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ሁሉንም ይመልከቱ"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ከ%s ጋር ያጋሩ"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ከሚከተለው ጋር ያጋሩ"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ar/strings.xml b/v7/appcompat/res/values-ar/strings.xml
new file mode 100644
index 0000000..93dde04
--- /dev/null
+++ b/v7/appcompat/res/values-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"تم"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"التنقل إلى الشاشة الرئيسية"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"التنقل إلى أعلى"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"خيارات إضافية"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"بحث"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"طلب البحث"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"محو طلب البحث"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"إرسال طلب البحث"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"البحث الصوتي"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"اختيار تطبيق"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"عرض الكل"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"مشاركة مع %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"مشاركة مع"</string>
+</resources>
diff --git a/v7/appcompat/res/values-bg/strings.xml b/v7/appcompat/res/values-bg/strings.xml
new file mode 100644
index 0000000..de3bde8
--- /dev/null
+++ b/v7/appcompat/res/values-bg/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Готово"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Придвижване към „Начало“"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Придвижване нагоре"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Още опции"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Търсене"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Заявка за търсене"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Изчистване на заявката"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Изпращане на заявката"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Гласово търсене"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Изберете приложение"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Вижте всички"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Споделяне със: %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Споделяне със:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ca/strings.xml b/v7/appcompat/res/values-ca/strings.xml
new file mode 100644
index 0000000..bfd4cb0
--- /dev/null
+++ b/v7/appcompat/res/values-ca/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Fet"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navega a la pàgina d\'inici"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navega cap a dalt"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Més opcions"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Cerca"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de cerca"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Esborra la consulta"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Envia la consulta"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Cerca per veu"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Selecciona una aplicació"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Mostra\'ls tots"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Comparteix amb %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Comparteix amb"</string>
+</resources>
diff --git a/v7/appcompat/res/values-cs/strings.xml b/v7/appcompat/res/values-cs/strings.xml
new file mode 100644
index 0000000..1465fdc
--- /dev/null
+++ b/v7/appcompat/res/values-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Hotovo"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Přejít na plochu"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Přejít nahoru"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Více možností"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Hledat"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Vyhledávací dotaz"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Smazat dotaz"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Odeslat dotaz"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Hlasové vyhledávání"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Vybrat aplikaci"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobrazit vše"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Sdílet pomocí %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Sdílet pomocí"</string>
+</resources>
diff --git a/v7/appcompat/res/values-da/strings.xml b/v7/appcompat/res/values-da/strings.xml
new file mode 100644
index 0000000..b178513
--- /dev/null
+++ b/v7/appcompat/res/values-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Luk"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Naviger hjem"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Naviger op"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Flere muligheder"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Søg"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Søgeforespørgsel"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ryd forespørgslen"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Indsend forespørgslen"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Stemmesøgning"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Vælg en app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Se alle"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Del med %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Del med"</string>
+</resources>
diff --git a/v7/appcompat/res/values-de/strings.xml b/v7/appcompat/res/values-de/strings.xml
new file mode 100644
index 0000000..6da4b71
--- /dev/null
+++ b/v7/appcompat/res/values-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Fertig"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Zur Startseite"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Nach oben"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Weitere Optionen"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Suchen"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Suchanfrage"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Suchanfrage löschen"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Suchanfrage senden"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Sprachsuche"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"App auswählen"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Alle ansehen"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Freigeben für %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Freigeben für"</string>
+</resources>
diff --git a/v7/appcompat/res/values-el/strings.xml b/v7/appcompat/res/values-el/strings.xml
new file mode 100644
index 0000000..60e6516
--- /dev/null
+++ b/v7/appcompat/res/values-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Τέλος"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Πλοήγηση στην αρχική σελίδα"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Πλοήγηση προς τα επάνω"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Περισσότερες επιλογές"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Αναζήτηση"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Ερώτημα αναζήτησης"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Διαγραφή ερωτήματος"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Υποβολή ερωτήματος"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Φωνητική αναζήτηση"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Επιλέξτε κάποια εφαρμογή"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Προβολή όλων"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Κοινοποίηση με %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Κοινοποίηση με"</string>
+</resources>
diff --git a/v7/appcompat/res/values-en-rGB/strings.xml b/v7/appcompat/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..3ec0b0e
--- /dev/null
+++ b/v7/appcompat/res/values-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Finished"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigate home"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigate up"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"More options"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Search"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Search query"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Clear query"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Submit query"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Voice search"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Choose an app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"See all"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Share with %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Share with"</string>
+</resources>
diff --git a/v7/appcompat/res/values-en-rIN/strings.xml b/v7/appcompat/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..3ec0b0e
--- /dev/null
+++ b/v7/appcompat/res/values-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Finished"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigate home"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigate up"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"More options"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Search"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Search query"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Clear query"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Submit query"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Voice search"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Choose an app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"See all"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Share with %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Share with"</string>
+</resources>
diff --git a/v7/appcompat/res/values-es-rUS/strings.xml b/v7/appcompat/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..6ab7942
--- /dev/null
+++ b/v7/appcompat/res/values-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Listo"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar a la página principal"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar hacia arriba"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Más opciones"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Búsqueda"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de búsqueda"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Eliminar la consulta"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Búsqueda por voz"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Elige una aplicación."</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver todo"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartir con %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartir con"</string>
+</resources>
diff --git a/v7/appcompat/res/values-es/strings.xml b/v7/appcompat/res/values-es/strings.xml
new file mode 100644
index 0000000..ed15b35
--- /dev/null
+++ b/v7/appcompat/res/values-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Listo"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ir a la pantalla de inicio"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Desplazarse hacia arriba"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Más opciones"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Buscar"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Borrar consulta"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Búsqueda por voz"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Seleccionar una aplicación"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver todo"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartir con %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartir con"</string>
+</resources>
diff --git a/v7/appcompat/res/values-et-rEE/strings.xml b/v7/appcompat/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..2ae925d
--- /dev/null
+++ b/v7/appcompat/res/values-et-rEE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Valmis"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeerimine avaekraanile"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigeerimine üles"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Rohkem valikuid"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Otsing"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Otsingupäring"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Päringu tühistamine"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Päringu esitamine"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Häälotsing"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Valige rakendus"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Kuva kõik"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Jagamine kasutajaga %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Jagamine:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-fa/strings.xml b/v7/appcompat/res/values-fa/strings.xml
new file mode 100644
index 0000000..8e10e92
--- /dev/null
+++ b/v7/appcompat/res/values-fa/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"انجام شد"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"پیمایش به صفحه اصلی"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"پیمایش به بالا"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"گزینههای بیشتر"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"جستجو"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"عبارت جستجو"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"پاک کردن عبارت جستجو"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ارسال عبارت جستجو"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"جستجوی شفاهی"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"انتخاب برنامه"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"مشاهده همه"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"اشتراکگذاری با %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"اشتراکگذاری با"</string>
+</resources>
diff --git a/v7/appcompat/res/values-fi/strings.xml b/v7/appcompat/res/values-fi/strings.xml
new file mode 100644
index 0000000..6755cea
--- /dev/null
+++ b/v7/appcompat/res/values-fi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Valmis"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Siirry etusivulle"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Siirry ylös"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Lisää"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Haku"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Hakulauseke"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Tyhjennä kysely"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Lähetä kysely"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Puhehaku"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Valitse sovellus"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Näytä kaikki"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Jakaminen: %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Jakaminen:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-fr-rCA/strings.xml b/v7/appcompat/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..417705a
--- /dev/null
+++ b/v7/appcompat/res/values-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Terminé"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Revenir à l\'accueil"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Revenir en haut de la page"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Plus d\'options"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Rechercher"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Requête de recherche"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Effacer la requête"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Envoyer la requête"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Recherche vocale"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Sélectionnez une application"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Voir toutes les chaînes"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partager avec %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partager avec"</string>
+</resources>
diff --git a/v7/appcompat/res/values-fr/strings.xml b/v7/appcompat/res/values-fr/strings.xml
new file mode 100644
index 0000000..27b8f38
--- /dev/null
+++ b/v7/appcompat/res/values-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"OK"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Revenir à l\'accueil"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Revenir en haut de la page"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Plus d\'options"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Rechercher"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Requête de recherche"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Effacer la requête"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Envoyer la requête"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Recherche vocale"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Sélectionner une application"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tout afficher"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partager avec %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partager avec"</string>
+</resources>
diff --git a/v7/appcompat/res/values-hi/strings.xml b/v7/appcompat/res/values-hi/strings.xml
new file mode 100644
index 0000000..b236ebb
--- /dev/null
+++ b/v7/appcompat/res/values-hi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"पूर्ण"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"मुखपृष्ठ पर नेविगेट करें"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ऊपर नेविगेट करें"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"अधिक विकल्प"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"खोजें"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"खोज क्वेरी"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"क्वेरी साफ़ करें"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"क्वेरी सबमिट करें"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ध्वनि खोज"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"कोई एप्लिकेशन चुनें"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"सभी देखें"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s के साथ साझा करें"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"इसके द्वारा साझा करें"</string>
+</resources>
diff --git a/v7/appcompat/res/values-hr/strings.xml b/v7/appcompat/res/values-hr/strings.xml
new file mode 100644
index 0000000..680e39f
--- /dev/null
+++ b/v7/appcompat/res/values-hr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Gotovo"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Idi na početnu"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Idi gore"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Dodatne opcije"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Pretraživanje"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Upit za pretraživanje"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Izbriši upit"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pošalji upit"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Glasovno pretraživanje"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Odabir aplikacije"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Prikaži sve"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Dijeljenje sa: %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Dijeljenje sa"</string>
+</resources>
diff --git a/v7/appcompat/res/values-hu/strings.xml b/v7/appcompat/res/values-hu/strings.xml
new file mode 100644
index 0000000..52dafb0
--- /dev/null
+++ b/v7/appcompat/res/values-hu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Kész"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ugrás a főoldalra"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Felfelé mozgatás"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"További lehetőségek"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Keresés"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Keresési lekérdezés"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Lekérdezés törlése"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Lekérdezés küldése"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Hangalapú keresés"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Válasszon ki egy alkalmazást"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Összes megtekintése"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Megosztás a következővel: %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Megosztás a következővel:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-hy-rAM/strings.xml b/v7/appcompat/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..6c0ee27
--- /dev/null
+++ b/v7/appcompat/res/values-hy-rAM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Կատարված է"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ուղղվել տուն"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Ուղղվել վերև"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Այլ ընտրանքներ"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Որոնել"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Որոնման հարցում"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Մաքրել հարցումը"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Ուղարկել հարցումը"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Ձայնային որոնում"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Ընտրել ծրագիր"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Տեսնել բոլորը"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Տարածել ըստ %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Տարածել"</string>
+</resources>
diff --git a/v7/appcompat/res/values-in/strings.xml b/v7/appcompat/res/values-in/strings.xml
new file mode 100644
index 0000000..9481e83
--- /dev/null
+++ b/v7/appcompat/res/values-in/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Selesai"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigasi ke beranda"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigasi naik"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Opsi lain"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Telusuri"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Kueri penelusuran"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Hapus kueri"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Kirim kueri"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Penelusuran suara"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Pilih aplikasi"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Lihat semua"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Bagikan dengan %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Bagikan dengan"</string>
+</resources>
diff --git a/v7/appcompat/res/values-it/strings.xml b/v7/appcompat/res/values-it/strings.xml
new file mode 100644
index 0000000..a8b0f2c
--- /dev/null
+++ b/v7/appcompat/res/values-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Fine"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Vai alla home page"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Vai in alto"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Altre opzioni"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Cerca"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Query di ricerca"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Cancella query"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Invia query"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Ricerca vocale"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Scegli un\'applicazione"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Visualizza tutte"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Condividi con %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Condividi con"</string>
+</resources>
diff --git a/v7/appcompat/res/values-iw/strings.xml b/v7/appcompat/res/values-iw/strings.xml
new file mode 100644
index 0000000..1af07df
--- /dev/null
+++ b/v7/appcompat/res/values-iw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"בוצע"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"נווט לדף הבית"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"נווט למעלה"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"עוד אפשרויות"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"חפש"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"שאילתת חיפוש"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"מחק שאילתה"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"שלח שאילתה"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"חיפוש קולי"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"בחר אפליקציה"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ראה הכול"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"שתף עם %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"שתף עם"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ja/strings.xml b/v7/appcompat/res/values-ja/strings.xml
new file mode 100644
index 0000000..659358a
--- /dev/null
+++ b/v7/appcompat/res/values-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"完了"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"ホームへ移動"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"上へ移動"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"その他のオプション"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"検索"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"検索キーワード"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"検索キーワードを削除"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"検索キーワードを送信"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"音声検索"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"アプリの選択"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"すべて表示"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%sと共有"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"共有"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ka-rGE/strings.xml b/v7/appcompat/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..0c430b1
--- /dev/null
+++ b/v7/appcompat/res/values-ka-rGE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"დასრულდა"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"მთავარზე ნავიგაცია"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ზემოთ ნავიგაცია"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"მეტი ვარიანტები"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"ძიება"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ძიების მოთხოვნა"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"მოთხოვნის გასუფთავება"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"მოთხოვნის გადაგზავნა"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ხმოვანი ძიება"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"აპის არჩევა"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ყველას ნახვა"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s-თან გაზიარება"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"გაზიარება:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-km-rKH/strings.xml b/v7/appcompat/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..597aec5
--- /dev/null
+++ b/v7/appcompat/res/values-km-rKH/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"រួចរាល់"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"រកមើលទៅដើម"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"រកមើលឡើងលើ"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ជម្រើសច្រើនទៀត"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"ស្វែងរក"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ស្វែងរកសំណួរ"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"សម្អាតសំណួរ"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ដាក់ស្នើសំណួរ"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ការស្វែងរកសំឡេង"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"ជ្រើសកម្មវិធី"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"មើលទាំងអស់"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ចែករំលែកជាមួយ %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ចែករំលែកជាមួយ"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ko/strings.xml b/v7/appcompat/res/values-ko/strings.xml
new file mode 100644
index 0000000..d331975
--- /dev/null
+++ b/v7/appcompat/res/values-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"완료"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"홈 탐색"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"위로 탐색"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"옵션 더보기"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"검색"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"검색어"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"검색어 삭제"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"검색어 보내기"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"음성 검색"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"앱 선택"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"전체 보기"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s와(과) 공유"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"공유 대상"</string>
+</resources>
diff --git a/v7/appcompat/res/values-lo-rLA/strings.xml b/v7/appcompat/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..7eb42ea
--- /dev/null
+++ b/v7/appcompat/res/values-lo-rLA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"ແລ້ວໆ"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"ກັບໄປໜ້າຫຼັກ"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"ຂຶ້ນເທິງ"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ໂຕເລືອກອື່ນ"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"ຊອກຫາ"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ຊອກຫາ"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"ລຶບຂໍ້ຄວາມຊອກຫາ"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ສົ່ງການຊອກຫາ"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ຊອກຫາດ້ວຍສຽງ"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"ເລືອກແອັບຯ"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ເບິ່ງທັງຫມົດ"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"ແບ່ງປັນກັບ %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"ແບ່ງປັນກັບ"</string>
+</resources>
diff --git a/v7/appcompat/res/values-lt/strings.xml b/v7/appcompat/res/values-lt/strings.xml
new file mode 100644
index 0000000..c4738a7
--- /dev/null
+++ b/v7/appcompat/res/values-lt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Atlikta"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Eiti į pagrindinį puslapį"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Eiti į viršų"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Daugiau parinkčių"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Paieška"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Paieškos užklausa"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Išvalyti užklausą"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pateikti užklausą"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Paieška balsu"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Pasirinkti programą"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Peržiūrėti viską"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Bendrinti naudojant „%s“"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Bendrinti naudojant"</string>
+</resources>
diff --git a/v7/appcompat/res/values-lv/strings.xml b/v7/appcompat/res/values-lv/strings.xml
new file mode 100644
index 0000000..c33858a
--- /dev/null
+++ b/v7/appcompat/res/values-lv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Gatavs"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Pārvietoties uz sākuma ekrānu"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Pārvietoties augšup"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Vairāk opciju"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Meklēt"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Meklēšanas vaicājums"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Notīrīt vaicājumu"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Iesniegt vaicājumu"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Meklēšana ar balsi"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Izvēlieties lietotni"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Skatīt visu"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Kopīgot ar %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Kopīgot ar:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-mn-rMN/strings.xml b/v7/appcompat/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..203e959
--- /dev/null
+++ b/v7/appcompat/res/values-mn-rMN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Дууссан"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Нүүр хуудас руу шилжих"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Дээш шилжих"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Нэмэлт сонголтууд"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Хайх"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Хайх асуулга"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Асуулгыг цэвэрлэх"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Асуулгыг илгээх"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Дуут хайлт"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Апп сонгох"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Бүгдийг харах"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s-тай хуваалцах"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Хуваалцах"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ms-rMY/strings.xml b/v7/appcompat/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..b174068
--- /dev/null
+++ b/v7/appcompat/res/values-ms-rMY/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Selesai"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigasi skrin utama"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigasi ke atas"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Lagi pilihan"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Cari"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Pertanyaan carian"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Kosongkan pertanyaan"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Serah pertanyaan"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Carian suara"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Pilih apl"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Lihat semua"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Kongsi dengan %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Kongsi dengan"</string>
+</resources>
diff --git a/v7/appcompat/res/values-nb/strings.xml b/v7/appcompat/res/values-nb/strings.xml
new file mode 100644
index 0000000..6630acf
--- /dev/null
+++ b/v7/appcompat/res/values-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Ferdig"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Gå til startsiden"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Gå opp"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Flere alternativer"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Søk"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Søkeord"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Slett søket"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Utfør søket"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Talesøk"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Velg en app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Se alle"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Del med %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Del med"</string>
+</resources>
diff --git a/v7/appcompat/res/values-nl/strings.xml b/v7/appcompat/res/values-nl/strings.xml
new file mode 100644
index 0000000..1375f9e
--- /dev/null
+++ b/v7/appcompat/res/values-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Gereed"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigeren naar startpositie"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Omhoog navigeren"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Meer opties"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Zoeken"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Zoekopdracht"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Zoekopdracht wissen"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Zoekopdracht verzenden"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Gesproken zoekopdracht"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Een app selecteren"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Alles weergeven"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Delen met %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Delen met"</string>
+</resources>
diff --git a/v7/appcompat/res/values-pl/strings.xml b/v7/appcompat/res/values-pl/strings.xml
new file mode 100644
index 0000000..aa1ba79
--- /dev/null
+++ b/v7/appcompat/res/values-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Gotowe"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Przejdź do strony głównej"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Przejdź wyżej"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Więcej opcji"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Szukaj"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Wyszukiwane hasło"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Wyczyść zapytanie"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Wyślij zapytanie"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Wyszukiwanie głosowe"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Wybierz aplikację"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobacz wszystkie"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Udostępnij dla %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Udostępnij dla"</string>
+</resources>
diff --git a/v7/appcompat/res/values-pt-rPT/strings.xml b/v7/appcompat/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..0d63f5f
--- /dev/null
+++ b/v7/appcompat/res/values-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Concluído"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar para a página inicial"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar para cima"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mais opções"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Pesquisar"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de pesquisa"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Limpar consulta"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Pesquisa por voz"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Escolher uma aplicação"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver tudo"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Partilhar com %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Partilhar com"</string>
+</resources>
diff --git a/v7/appcompat/res/values-pt/strings.xml b/v7/appcompat/res/values-pt/strings.xml
new file mode 100644
index 0000000..88b09ea
--- /dev/null
+++ b/v7/appcompat/res/values-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Concluído"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navegar para a página inicial"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navegar para cima"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mais opções"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Pesquisar"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Consulta de pesquisa"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Limpar consulta"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Enviar consulta"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Pesquisa por voz"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Selecione um aplicativo"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Ver tudo"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Compartilhar com %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Compartilhar com"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ro/strings.xml b/v7/appcompat/res/values-ro/strings.xml
new file mode 100644
index 0000000..36a7b31
--- /dev/null
+++ b/v7/appcompat/res/values-ro/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Terminat"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Navigați la ecranul de pornire"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigați în sus"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Mai multe opțiuni"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Căutați"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Interogare de căutare"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ștergeți interogarea"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Trimiteți interogarea"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Căutare vocală"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Alegeți o aplicaţie"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Afișați-le pe toate"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Trimiteți la %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Trimiteți la"</string>
+</resources>
diff --git a/v7/appcompat/res/values-ru/strings.xml b/v7/appcompat/res/values-ru/strings.xml
new file mode 100644
index 0000000..5c22e5e
--- /dev/null
+++ b/v7/appcompat/res/values-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Готово"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Перейти на главный экран"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Перейти вверх"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Другие параметры"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Поиск"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Поисковый запрос"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Удалить запрос"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Отправить запрос"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Голосовой поиск"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Выбрать приложение"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Показать все"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Открыть доступ пользователю %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Открыть доступ"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sk/strings.xml b/v7/appcompat/res/values-sk/strings.xml
new file mode 100644
index 0000000..253f3e5
--- /dev/null
+++ b/v7/appcompat/res/values-sk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Hotovo"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Prejsť na plochu"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Prejsť hore"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Ďalšie možnosti"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Hľadať"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Vyhľadávací dopyt"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Vymazať dopyt"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Odoslať dopyt"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Hlasové vyhľadávanie"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Zvoľte aplikáciu"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Zobraziť všetko"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Zdieľať pomocou %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Zdieľať pomocou"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sl/strings.xml b/v7/appcompat/res/values-sl/strings.xml
new file mode 100644
index 0000000..8e3e23e
--- /dev/null
+++ b/v7/appcompat/res/values-sl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Končano"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Krmarjenje domov"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Krmarjenje navzgor"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Več možnosti"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Iskanje"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Iskalna poizvedba"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Izbris poizvedbe"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Pošiljanje poizvedbe"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Glasovno iskanje"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Izbira aplikacije"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Pokaži vse"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Deljenje z:"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Deljenje z"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sr/strings.xml b/v7/appcompat/res/values-sr/strings.xml
new file mode 100644
index 0000000..213c939
--- /dev/null
+++ b/v7/appcompat/res/values-sr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Готово"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Одлазак на Почетну"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Кретање нагоре"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Још опција"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Претрага"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Упит за претрагу"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Брисање упита"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Слање упита"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Гласовна претрага"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Избор апликације"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Прикажи све"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Дели са апликацијом %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Дели са"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sv/strings.xml b/v7/appcompat/res/values-sv/strings.xml
new file mode 100644
index 0000000..49c7a5d
--- /dev/null
+++ b/v7/appcompat/res/values-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Klart"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Visa startsidan"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Navigera uppåt"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Fler alternativ"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Sök"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Sökfråga"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Ta bort frågan"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Skicka fråga"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Röstsökning"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Välj en app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Visa alla"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Dela med %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Dela med"</string>
+</resources>
diff --git a/v7/appcompat/res/values-sw/strings.xml b/v7/appcompat/res/values-sw/strings.xml
new file mode 100644
index 0000000..6455ba5
--- /dev/null
+++ b/v7/appcompat/res/values-sw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Nimemaliza"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Nenda mwanzo"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Nenda juu"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Chaguo zaidi"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Tafuta"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Hoja ya utafutaji"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Futa hoja"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Wasilisha hoja"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Tafuta kwa kutamka"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Chagua programu"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Angalia zote"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Shiriki na %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Shiriki na:"</string>
+</resources>
diff --git a/v7/appcompat/res/values-th/strings.xml b/v7/appcompat/res/values-th/strings.xml
new file mode 100644
index 0000000..275dc57
--- /dev/null
+++ b/v7/appcompat/res/values-th/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"เสร็จสิ้น"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"นำทางไปหน้าแรก"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"นำทางขึ้น"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"ตัวเลือกอื่น"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"ค้นหา"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"ข้อความค้นหา"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"ล้างข้อความค้นหา"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"ส่งข้อความค้นหา"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"ค้นหาด้วยเสียง"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"เลือกแอป"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"ดูทั้งหมด"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"แชร์กับ %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"แชร์กับ"</string>
+</resources>
diff --git a/v7/appcompat/res/values-tl/strings.xml b/v7/appcompat/res/values-tl/strings.xml
new file mode 100644
index 0000000..e0705d6
--- /dev/null
+++ b/v7/appcompat/res/values-tl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Tapos na"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Mag-navigate patungo sa home"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Mag-navigate pataas"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Higit pang mga opsyon"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Maghanap"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Query sa paghahanap"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"I-clear ang query"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Isumite ang query"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Paghahanap gamit ang boses"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Pumili ng isang app"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tingnan lahat"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Ibahagi sa/kay %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Ibahagi sa/kay"</string>
+</resources>
diff --git a/v7/appcompat/res/values-tr/strings.xml b/v7/appcompat/res/values-tr/strings.xml
new file mode 100644
index 0000000..61cb966
--- /dev/null
+++ b/v7/appcompat/res/values-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Tamamlandı"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Ana ekrana git"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Yukarı git"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Diğer seçenekler"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Ara"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Arama sorgusu"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Sorguyu temizle"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Sorguyu gönder"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Sesli arama"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Bir uygulama seçin"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Tümünü göster"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"%s ile paylaş"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Şununla paylaş"</string>
+</resources>
diff --git a/v7/appcompat/res/values-uk/strings.xml b/v7/appcompat/res/values-uk/strings.xml
new file mode 100644
index 0000000..f670140
--- /dev/null
+++ b/v7/appcompat/res/values-uk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Готово"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Перейти на головний"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Перейти вгору"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Інші опції"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Пошук"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Пошуковий запит"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Очистити запит"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Надіслати запит"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Голосовий пошук"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Вибрати програму"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Переглянути всі"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Надіслати через %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Надіслати через"</string>
+</resources>
diff --git a/v7/appcompat/res/values-vi/strings.xml b/v7/appcompat/res/values-vi/strings.xml
new file mode 100644
index 0000000..0840f73
--- /dev/null
+++ b/v7/appcompat/res/values-vi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Xong"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Điều hướng về trang chủ"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Điều hướng lên trên"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Thêm tùy chọn"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Tìm kiếm"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Tìm kiếm truy vấn"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Xóa truy vấn"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Gửi truy vấn"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Tìm kiếm bằng giọng nói"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Chọn một ứng dụng"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Xem tất cả"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Chia sẻ với %s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Chia sẻ với"</string>
+</resources>
diff --git a/v7/appcompat/res/values-zh-rCN/strings.xml b/v7/appcompat/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..87b36b0
--- /dev/null
+++ b/v7/appcompat/res/values-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"完成"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"转到主屏幕"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"转到上一层级"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"更多选项"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"搜索"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"搜索查询"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"清除查询"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查询"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"语音搜索"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"选择应用"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"查看全部"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"通过%s分享"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"分享方式"</string>
+</resources>
diff --git a/v7/appcompat/res/values-zh-rHK/strings.xml b/v7/appcompat/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..f6a367d
--- /dev/null
+++ b/v7/appcompat/res/values-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"完成"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"瀏覽主頁"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"向上瀏覽"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"更多選項"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"搜尋"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"搜尋查詢"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"清除查詢"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查詢"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"語音搜尋"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"選擇應用程式"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"顯示全部"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"與「%s」分享"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"分享對象"</string>
+</resources>
diff --git a/v7/appcompat/res/values-zh-rTW/strings.xml b/v7/appcompat/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..c804ccf
--- /dev/null
+++ b/v7/appcompat/res/values-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"完成"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"瀏覽首頁"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"向上瀏覽"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"更多選項"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"搜尋"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"搜尋查詢"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"清除查詢"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"提交查詢"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"語音搜尋"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"選擇應用程式"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"查看全部"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"與「%s」分享"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"選擇分享對象"</string>
+</resources>
diff --git a/v7/appcompat/res/values-zu/strings.xml b/v7/appcompat/res/values-zu/strings.xml
new file mode 100644
index 0000000..92eac7e
--- /dev/null
+++ b/v7/appcompat/res/values-zu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="abc_action_mode_done" msgid="4076576682505996667">"Kwenziwe"</string>
+ <string name="abc_action_bar_home_description" msgid="4600421777120114993">"Zulazulela ekhaya"</string>
+ <string name="abc_action_bar_up_description" msgid="1594238315039666878">"Zulazulela phezulu"</string>
+ <string name="abc_action_menu_overflow_description" msgid="3588849162933574182">"Izinketho eziningi"</string>
+ <string name="abc_searchview_description_search" msgid="8264924765203268293">"Sesha"</string>
+ <string name="abc_searchview_description_query" msgid="2550479030709304392">"Umbuzo wosesho"</string>
+ <string name="abc_searchview_description_clear" msgid="3691816814315814921">"Sula inkinga"</string>
+ <string name="abc_searchview_description_submit" msgid="8928215447528550784">"Hambisa umbuzo"</string>
+ <string name="abc_searchview_description_voice" msgid="893419373245838918">"Ukusesha ngezwi"</string>
+ <string name="abc_activitychooserview_choose_application" msgid="2031811694353399454">"Khetha uhlelo lokusebenza"</string>
+ <string name="abc_activity_chooser_view_see_all" msgid="7468859129482906941">"Buka konke"</string>
+ <string name="abc_shareactionprovider_share_with_application" msgid="7165123711973476752">"Yabelana no-%s"</string>
+ <string name="abc_shareactionprovider_share_with" msgid="3421042268587513524">"Yabelana no-"</string>
+</resources>
diff --git a/v7/gridlayout/build.gradle b/v7/gridlayout/build.gradle
index 8e6d942..54835b2 100644
--- a/v7/gridlayout/build.gradle
+++ b/v7/gridlayout/build.gradle
@@ -6,9 +6,8 @@
compile project(':support-v4')
}
-
android {
- compileSdkVersion 19
+ compileSdkVersion 7
buildToolsVersion "19.0.1"
sourceSets {
diff --git a/v7/mediarouter/build.gradle b/v7/mediarouter/build.gradle
index 4fee3bf..252e44b 100644
--- a/v7/mediarouter/build.gradle
+++ b/v7/mediarouter/build.gradle
@@ -32,7 +32,7 @@
jellybeanmr1Compile getAndroidPrebuilt('17')
jellybeanmr1Compile sourceSets.jellybean.output
- jellybeanmr2Compile getAndroidPrebuilt('18')
+ jellybeanmr2Compile getAndroidPrebuilt('current')
jellybeanmr2Compile sourceSets.jellybean.output
jellybeanmr2Compile sourceSets.jellybeanmr1.output
diff --git a/v7/mediarouter/res/values-af/strings.xml b/v7/mediarouter/res/values-af/strings.xml
new file mode 100644
index 0000000..885af10
--- /dev/null
+++ b/v7/mediarouter/res/values-af/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Stelsel"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Toestelle"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media-uitvoer"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Koppel aan toestel"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Soek tans vir toestelle…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ontkoppel"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-am/strings.xml b/v7/mediarouter/res/values-am/strings.xml
new file mode 100644
index 0000000..0027737
--- /dev/null
+++ b/v7/mediarouter/res/values-am/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"ስርዓት"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"መሣሪያዎች"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"የሚዲያ ውፅዓት"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ከመሳሪያ ጋር ያገናኙ"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"መሳሪያዎችን በመፈለግ ላይ…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ግንኙነት አቋርጥ"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ar/strings.xml b/v7/mediarouter/res/values-ar/strings.xml
new file mode 100644
index 0000000..9289a35
--- /dev/null
+++ b/v7/mediarouter/res/values-ar/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"النظام"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"الأجهزة"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"المنفذ الإعلامي"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"الاتصال بجهاز"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"جارٍ البحث عن الأجهزة…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"قطع الاتصال"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-bg/strings.xml b/v7/mediarouter/res/values-bg/strings.xml
new file mode 100644
index 0000000..ff1401e
--- /dev/null
+++ b/v7/mediarouter/res/values-bg/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Изходяща мултимедия"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Свързване с устройство"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Търсят се устройства…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Прекратяване на връзката"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ca/strings.xml b/v7/mediarouter/res/values-ca/strings.xml
new file mode 100644
index 0000000..dd485de
--- /dev/null
+++ b/v7/mediarouter/res/values-ca/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositius"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortida de contingut multimèdia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connecta al dispositiu"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"S\'estan cercant dispositius…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconnecta"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-cs/strings.xml b/v7/mediarouter/res/values-cs/strings.xml
new file mode 100644
index 0000000..4687100
--- /dev/null
+++ b/v7/mediarouter/res/values-cs/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Zařízení"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Výstup médií"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Připojení k zařízení"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Vyhledávání zařízení…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Odpojit"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-da/strings.xml b/v7/mediarouter/res/values-da/strings.xml
new file mode 100644
index 0000000..fd3b0fb
--- /dev/null
+++ b/v7/mediarouter/res/values-da/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheder"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieudgang"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Opret forbindelse til enheden"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Søger efter enheder..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Afbryd forbindelsen"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-de/strings.xml b/v7/mediarouter/res/values-de/strings.xml
new file mode 100644
index 0000000..9df0ebf
--- /dev/null
+++ b/v7/mediarouter/res/values-de/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Geräte"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medienausgabe"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Mit Gerät verbinden"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Geräte werden gesucht…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Verbindung aufheben"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-el/strings.xml b/v7/mediarouter/res/values-el/strings.xml
new file mode 100644
index 0000000..5a61395
--- /dev/null
+++ b/v7/mediarouter/res/values-el/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Σύστημα"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Συσκευές"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Έξοδος μέσων"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Σύνδεση με τη συσκευή"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Αναζήτηση συσκευών…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Αποσύνδεση"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-en-rGB/strings.xml b/v7/mediarouter/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..b9af4bf
--- /dev/null
+++ b/v7/mediarouter/res/values-en-rGB/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media output"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connect to device"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Searching for devices…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnect"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-en-rIN/strings.xml b/v7/mediarouter/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..b9af4bf
--- /dev/null
+++ b/v7/mediarouter/res/values-en-rIN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Devices"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media output"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connect to device"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Searching for devices…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnect"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-es-rUS/strings.xml b/v7/mediarouter/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..211b400
--- /dev/null
+++ b/v7/mediarouter/res/values-es-rUS/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Salida multimedia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar al dispositivo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Buscando dispositivos…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-es/strings.xml b/v7/mediarouter/res/values-es/strings.xml
new file mode 100644
index 0000000..d3a1639
--- /dev/null
+++ b/v7/mediarouter/res/values-es/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Salida multimedia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar a dispositivo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Buscando dispositivos…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-et-rEE/strings.xml b/v7/mediarouter/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..7dbdf74
--- /dev/null
+++ b/v7/mediarouter/res/values-et-rEE/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Süsteem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Seadmed"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Meediaväljund"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Seadmega ühendamine"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Seadmete otsimine …"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Katkesta ühendus"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-fa/strings.xml b/v7/mediarouter/res/values-fa/strings.xml
new file mode 100644
index 0000000..2ffed50
--- /dev/null
+++ b/v7/mediarouter/res/values-fa/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"سیستم"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"دستگاهها"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"خروجی رسانه"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"برقراری ارتباط با دستگاه"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"در حال جستجو برای دستگاهها..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"قطع ارتباط"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-fi/strings.xml b/v7/mediarouter/res/values-fi/strings.xml
new file mode 100644
index 0000000..0692c2f
--- /dev/null
+++ b/v7/mediarouter/res/values-fi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Järjestelmä"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Laitteet"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Median äänentoisto"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Yhdistä laitteeseen"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Etsitään laitteita…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Katkaise yhteys"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-fr-rCA/strings.xml b/v7/mediarouter/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..9fa3c9c
--- /dev/null
+++ b/v7/mediarouter/res/values-fr-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortie multimédia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connexion au périphérique"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Recherche d\'appareils en cours…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Déconnecter"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-fr/strings.xml b/v7/mediarouter/res/values-fr/strings.xml
new file mode 100644
index 0000000..5607a1c
--- /dev/null
+++ b/v7/mediarouter/res/values-fr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Système"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Appareils"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Sortie multimédia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connecter à l\'appareil"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Recherche d\'appareils en cours…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Déconnecter"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-hi/strings.xml b/v7/mediarouter/res/values-hi/strings.xml
new file mode 100644
index 0000000..8acc2bb
--- /dev/null
+++ b/v7/mediarouter/res/values-hi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"सिस्टम"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"उपकरण"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"मीडिया आउटपुट"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"उपकरण से कनेक्ट करें"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"उपकरणों की खोज हो रही है…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"डिस्कनेक्ट करें"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-hr/strings.xml b/v7/mediarouter/res/values-hr/strings.xml
new file mode 100644
index 0000000..2946433
--- /dev/null
+++ b/v7/mediarouter/res/values-hr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sustav"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Uređaji"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medijski izlaz"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Povezivanje s uređajem"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Traženje uređaja…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Prekini vezu"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-hu/strings.xml b/v7/mediarouter/res/values-hu/strings.xml
new file mode 100644
index 0000000..b68fe16
--- /dev/null
+++ b/v7/mediarouter/res/values-hu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Rendszer"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Eszközök"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Médiakimenet"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Csatlakozás adott eszközhöz"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Eszközkeresés…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Leválasztás"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-hy-rAM/strings.xml b/v7/mediarouter/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..77f1136
--- /dev/null
+++ b/v7/mediarouter/res/values-hy-rAM/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Համակարգ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Սարքեր"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Մեդիա արտածում"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Միանալ սարքին"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Որոնվում են սարքեր..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Անջատել"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-in/strings.xml b/v7/mediarouter/res/values-in/strings.xml
new file mode 100644
index 0000000..1d3b387
--- /dev/null
+++ b/v7/mediarouter/res/values-in/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Perangkat"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Keluaran media"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Sambungkan ke perangkat"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Menelusuri perangkat…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Putuskan sambungan"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-it/strings.xml b/v7/mediarouter/res/values-it/strings.xml
new file mode 100644
index 0000000..bd58755
--- /dev/null
+++ b/v7/mediarouter/res/values-it/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivi"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Uscita media"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Connetti al dispositivo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Ricerca di dispositivi…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Disconnetti"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-iw/strings.xml b/v7/mediarouter/res/values-iw/strings.xml
new file mode 100644
index 0000000..59753b4
--- /dev/null
+++ b/v7/mediarouter/res/values-iw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"מערכת"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"מכשירים"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"פלט מדיה"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"התחבר למכשיר"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"מחפש מכשירים…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"התנתק"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ja/strings.xml b/v7/mediarouter/res/values-ja/strings.xml
new file mode 100644
index 0000000..1367489
--- /dev/null
+++ b/v7/mediarouter/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"システム"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"端末"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"メディア出力"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"端末に接続"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"端末を検索しています…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"接続を解除"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ka-rGE/strings.xml b/v7/mediarouter/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..413257e
--- /dev/null
+++ b/v7/mediarouter/res/values-ka-rGE/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"სისტემა"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"მოწყობილობები"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"მედია გამოსასვლელი"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"მოწყობილობასთან დაკავშირება"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"მოწყობილობების ძიება…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"კავშირის გაწყვეტა"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-km-rKH/strings.xml b/v7/mediarouter/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..e001dde
--- /dev/null
+++ b/v7/mediarouter/res/values-km-rKH/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"ប្រព័ន្ធ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"ឧបករណ៍"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"លទ្ធផលមេឌៀ"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ភ្ជាប់ឧបករណ៍"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"កំពុងស្វែងរកឧបករណ៍..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ផ្ដាច់"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ko/strings.xml b/v7/mediarouter/res/values-ko/strings.xml
new file mode 100644
index 0000000..21f82a0
--- /dev/null
+++ b/v7/mediarouter/res/values-ko/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"시스템"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"기기"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"미디어 출력"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"기기에 연결"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"기기 검색 중…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"연결 해제"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-lo-rLA/strings.xml b/v7/mediarouter/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..31a03cd
--- /dev/null
+++ b/v7/mediarouter/res/values-lo-rLA/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"ລະບົບ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"ອຸປະກອນ"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"ມີເດຍເອົ້າພຸດ"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"ກຳລັງຊອກຫາອຸປະກອນ..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ຕັດການເຊື່ອມຕໍ່"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-lt/strings.xml b/v7/mediarouter/res/values-lt/strings.xml
new file mode 100644
index 0000000..ead3b73
--- /dev/null
+++ b/v7/mediarouter/res/values-lt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Įrenginiai"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medijos išvestis"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Prijungimas prie įrenginio"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Ieškoma įrenginių…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Atjungti"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-lv/strings.xml b/v7/mediarouter/res/values-lv/strings.xml
new file mode 100644
index 0000000..0914990
--- /dev/null
+++ b/v7/mediarouter/res/values-lv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistēma"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Ierīces"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Multivides izeja"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Savienojuma izveide ar ierīci"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Notiek ierīču meklēšana..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Atvienot"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-mn-rMN/strings.xml b/v7/mediarouter/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..4eecdb4
--- /dev/null
+++ b/v7/mediarouter/res/values-mn-rMN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Төхөөрөмжүүд"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Медиа гаралт"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Төхөөрөмжтэй холбох"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Төхөөрөмжүүдийг хайж байна…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Салгах"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ms-rMY/strings.xml b/v7/mediarouter/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..dadaa30
--- /dev/null
+++ b/v7/mediarouter/res/values-ms-rMY/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Peranti"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Output media"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Sambung kepada peranti"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Mencari peranti..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Putuskan sambungan"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-nb/strings.xml b/v7/mediarouter/res/values-nb/strings.xml
new file mode 100644
index 0000000..fa4d9a4
--- /dev/null
+++ b/v7/mediarouter/res/values-nb/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieutgang"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Koble til enheten"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Søker etter enheter …"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Koble fra"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-nl/strings.xml b/v7/mediarouter/res/values-nl/strings.xml
new file mode 100644
index 0000000..5572449
--- /dev/null
+++ b/v7/mediarouter/res/values-nl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Systeem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Apparaten"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Media-uitvoer"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Verbinding maken met apparaat"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Zoeken naar apparaten…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Verbinding verbreken"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-pl/strings.xml b/v7/mediarouter/res/values-pl/strings.xml
new file mode 100644
index 0000000..95a1d03
--- /dev/null
+++ b/v7/mediarouter/res/values-pl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Urządzenia"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Wyjście multimediów"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Połącz z urządzeniem"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Szukam urządzeń…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Rozłącz"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-pt-rPT/strings.xml b/v7/mediarouter/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..54b1dfc
--- /dev/null
+++ b/v7/mediarouter/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Saída de som multimédia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Ligar ao dispositivo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"A pesquisar dispositivos…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desassociar"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-pt/strings.xml b/v7/mediarouter/res/values-pt/strings.xml
new file mode 100644
index 0000000..3ce1c38
--- /dev/null
+++ b/v7/mediarouter/res/values-pt/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistema"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispositivos"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Saída de mídia"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectar ao dispositivo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Procurando dispositivos…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Desconectar"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ro/strings.xml b/v7/mediarouter/res/values-ro/strings.xml
new file mode 100644
index 0000000..4c9e4b9
--- /dev/null
+++ b/v7/mediarouter/res/values-ro/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Dispozitive"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Rezultate media"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Conectați-vă la dispozitiv"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Se caută dispozitive..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Deconectați-vă"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-ru/strings.xml b/v7/mediarouter/res/values-ru/strings.xml
new file mode 100644
index 0000000..5cc2bba
--- /dev/null
+++ b/v7/mediarouter/res/values-ru/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Устройства"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Перенаправлять поток мультимедиа"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Подключение к устройству"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Поиск устройств…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Отключить"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sk/strings.xml b/v7/mediarouter/res/values-sk/strings.xml
new file mode 100644
index 0000000..668800f
--- /dev/null
+++ b/v7/mediarouter/res/values-sk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Systém"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Zariadenia"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Výstup médií"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Pripojenie k zariadeniu"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Prebieha vyhľadávanie zariadení…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Odpojiť"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sl/strings.xml b/v7/mediarouter/res/values-sl/strings.xml
new file mode 100644
index 0000000..3e3e8bb
--- /dev/null
+++ b/v7/mediarouter/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Naprave"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Izhod za predstavnost"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Povezovanje z napravo"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Iskanje naprav …"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Prekini povezavo"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sr/strings.xml b/v7/mediarouter/res/values-sr/strings.xml
new file mode 100644
index 0000000..320f3e8
--- /dev/null
+++ b/v7/mediarouter/res/values-sr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Систем"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Уређаји"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Излаз медија"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Повежите са уређајем"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Претраживање уређаја…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Прекини везу"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sv/strings.xml b/v7/mediarouter/res/values-sv/strings.xml
new file mode 100644
index 0000000..910c6f1
--- /dev/null
+++ b/v7/mediarouter/res/values-sv/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Enheter"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medieuppspelning"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Anslut till enhet"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Söker efter enheter ..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Koppla från"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-sw/strings.xml b/v7/mediarouter/res/values-sw/strings.xml
new file mode 100644
index 0000000..fcbc590
--- /dev/null
+++ b/v7/mediarouter/res/values-sw/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Mfumo"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Vifaa"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Towe la vyombo vya habari"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Unganisha kwenye kifaa"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Inatafuta vifaa..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Tenganisha"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-th/strings.xml b/v7/mediarouter/res/values-th/strings.xml
new file mode 100644
index 0000000..78e5a73
--- /dev/null
+++ b/v7/mediarouter/res/values-th/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"ระบบ"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"อุปกรณ์"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"เอาต์พุตสื่อ"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"เชื่อมต่อกับอุปกรณ์"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"กำลังค้นหาอุปกรณ์…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"ยกเลิกการเชื่อมต่อ"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-tl/strings.xml b/v7/mediarouter/res/values-tl/strings.xml
new file mode 100644
index 0000000..0953787
--- /dev/null
+++ b/v7/mediarouter/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"System"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Mga Device"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Output ng media"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Kumonekta sa device"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Naghahanap ng mga device…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Idiskonekta"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-tr/strings.xml b/v7/mediarouter/res/values-tr/strings.xml
new file mode 100644
index 0000000..12faaa6
--- /dev/null
+++ b/v7/mediarouter/res/values-tr/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Sistem"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Cihazlar"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Medya çıkışı"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Cihaza bağlanın"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Cihaz arayın…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Bağlantıyı kes"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-uk/strings.xml b/v7/mediarouter/res/values-uk/strings.xml
new file mode 100644
index 0000000..b036dea
--- /dev/null
+++ b/v7/mediarouter/res/values-uk/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Система"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Пристрої"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Вивід медіа-даних"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Під’єднатися до пристрою"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Пошук пристроїв…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Від’єднатися"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-vi/strings.xml b/v7/mediarouter/res/values-vi/strings.xml
new file mode 100644
index 0000000..a58d0e4
--- /dev/null
+++ b/v7/mediarouter/res/values-vi/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Hệ thống"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Thiết bị"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Đầu ra phương tiện"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Kết nối với thiết bị"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Đang tìm kiếm thiết bị…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Ngắt kết nối"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-zh-rCN/strings.xml b/v7/mediarouter/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..71c4407
--- /dev/null
+++ b/v7/mediarouter/res/values-zh-rCN/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"系统"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"设备"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒体输出线路"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"连接到设备"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜索设备…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"断开连接"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-zh-rHK/strings.xml b/v7/mediarouter/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..f499169
--- /dev/null
+++ b/v7/mediarouter/res/values-zh-rHK/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒體輸出"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"連線至裝置"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜尋裝置…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"中斷連線"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-zh-rTW/strings.xml b/v7/mediarouter/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..a847615
--- /dev/null
+++ b/v7/mediarouter/res/values-zh-rTW/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"系統"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"裝置"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"媒體輸出"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"連線至裝置"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"正在搜尋裝置..."</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"中斷連線"</string>
+</resources>
diff --git a/v7/mediarouter/res/values-zu/strings.xml b/v7/mediarouter/res/values-zu/strings.xml
new file mode 100644
index 0000000..be195be
--- /dev/null
+++ b/v7/mediarouter/res/values-zu/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mr_system_route_name" msgid="5441529851481176817">"Isistimu"</string>
+ <string name="mr_user_route_category_name" msgid="7498112907524977311">"Amadivayisi"</string>
+ <string name="mr_media_route_button_content_description" msgid="4271159405637008602">"Okukhiphayo kwabezindaba"</string>
+ <string name="mr_media_route_chooser_title" msgid="7106830097177242655">"Xhumeka kudivayisi"</string>
+ <string name="mr_media_route_chooser_searching" msgid="7553005460920830010">"Iseshela amadivayisi…"</string>
+ <string name="mr_media_route_controller_disconnect" msgid="109793632378378069">"Nqamula"</string>
+</resources>
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/ElementThunker.java b/v8/renderscript/java/src/android/support/v8/renderscript/ElementThunker.java
index fc986b3..9b820e2 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/ElementThunker.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/ElementThunker.java
@@ -57,10 +57,6 @@
return android.renderscript.Element.DataKind.PIXEL_RGB;
case PIXEL_RGBA:
return android.renderscript.Element.DataKind.PIXEL_RGBA;
- case PIXEL_DEPTH:
- return android.renderscript.Element.DataKind.PIXEL_DEPTH;
- case PIXEL_YUV:
- return android.renderscript.Element.DataKind.PIXEL_YUV;
}
return null;
}
diff --git a/v8/tts/Android.mk b/v8/tts/Android.mk
new file mode 100644
index 0000000..0e60af6
--- /dev/null
+++ b/v8/tts/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# -----------------------------------------------------------------------
+
+# A helper sub-library that makes direct use of Ice Cream Sandwich APIs.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-tts-ics
+LOCAL_SDK_VERSION := 14
+LOCAL_SRC_FILES := $(call all-java-files-under, ics)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# A helper sub-library that makes direct use of Ice Cream Sandwich MR1 APIs.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-tts-ics-mr1
+LOCAL_SDK_VERSION := 15
+LOCAL_SRC_FILES := $(call all-java-files-under, ics-mr1)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v8-tts
+#LOCAL_SDK_VERSION := 8
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-tts-ics-mr1 android-support-tts-ics
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(LOCAL_PATH)/tests/Android.mk
diff --git a/v8/tts/AndroidManifest.xml b/v8/tts/AndroidManifest.xml
new file mode 100644
index 0000000..0f52756
--- /dev/null
+++ b/v8/tts/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v8.speech.tts">
+ <uses-sdk android:minSdkVersion="8"/>
+</manifest>
diff --git a/v8/tts/ics-mr1/android/support/v8/speech/tts/TextToSpeechICSMR1.java b/v8/tts/ics-mr1/android/support/v8/speech/tts/TextToSpeechICSMR1.java
new file mode 100644
index 0000000..ef795f2
--- /dev/null
+++ b/v8/tts/ics-mr1/android/support/v8/speech/tts/TextToSpeechICSMR1.java
@@ -0,0 +1,72 @@
+package android.support.v8.speech.tts;
+
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+
+import java.util.Locale;
+import java.util.Set;
+
+/** Helper class for TTS functionality introduced in ICS MR1 */
+class TextToSpeechICSMR1 {
+
+ /**
+ * Call {@link TextToSpeech#getFeatures} if available.
+ *
+ * @return {@link TextToSpeech#getFeatures} or null on older devices.
+ */
+ static Set<String> getFeatures(TextToSpeech tts, Locale locale) {
+ if (android.os.Build.VERSION.SDK_INT >=
+ android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
+ return tts.getFeatures(locale);
+ }
+ return null;
+ }
+
+ static interface UtteranceProgressListenerICSMR1 {
+ void onDone(String utteranceId);
+ void onError(String utteranceId);
+ void onStart(String utteranceId);
+ }
+
+ /**
+ * Call {@link TextToSpeech#setOnUtteranceProgressListener} if ICS-MR1 or newer.
+ *
+ * On pre ICS-MR1 devices,{@link TextToSpeech#setOnUtteranceCompletedListener} is
+ * used to emulate its behavior - at the end of synthesis we call
+ * {@link UtteranceProgressListenerICSMR1#onStart(String)} and
+ * {@link UtteranceProgressListenerICSMR1#onDone(String)} one after the other.
+ * Errors can't be detected.
+ */
+ static void setUtteranceProgressListener(TextToSpeech tts,
+ final UtteranceProgressListenerICSMR1 listener) {
+ if (android.os.Build.VERSION.SDK_INT >=
+ android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
+ tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
+ @Override
+ public void onStart(String utteranceId) {
+ listener.onStart(utteranceId);
+ }
+
+ @Override
+ public void onError(String utteranceId) {
+ listener.onError(utteranceId);
+ }
+
+ @Override
+ public void onDone(String utteranceId) {
+ listener.onDone(utteranceId);
+ }
+ });
+ } else {
+ tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
+ @Override
+ public void onUtteranceCompleted(String utteranceId) {
+ // Emulate onStart. Clients are expecting it will happen.
+ listener.onStart(utteranceId);
+ listener.onDone(utteranceId);
+ }
+ });
+ }
+ }
+}
diff --git a/v8/tts/ics/android/support/v8/speech/tts/TextToSpeechICS.java b/v8/tts/ics/android/support/v8/speech/tts/TextToSpeechICS.java
new file mode 100644
index 0000000..b557c41
--- /dev/null
+++ b/v8/tts/ics/android/support/v8/speech/tts/TextToSpeechICS.java
@@ -0,0 +1,27 @@
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.os.Build;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnInitListener;
+import android.util.Log;
+
+/** Helper class for TTS functionality introduced in ICS */
+class TextToSpeechICS {
+ private static final String TAG = "android.support.v8.speech.tts";
+
+ static TextToSpeech construct(Context context, OnInitListener onInitListener,
+ String engineName) {
+ if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ if (engineName == null) {
+ return new TextToSpeech(context, onInitListener);
+ } else {
+ Log.w(TAG, "Can't specify tts engine on this device");
+ return new TextToSpeech(context, onInitListener);
+ }
+ } else {
+ return new TextToSpeech(context, onInitListener, engineName);
+ }
+ }
+
+}
diff --git a/v8/tts/src/android/support/v8/speech/tts/ITextToSpeechClient.java b/v8/tts/src/android/support/v8/speech/tts/ITextToSpeechClient.java
new file mode 100644
index 0000000..cf6a9c1
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/ITextToSpeechClient.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.v8.speech.tts.TextToSpeechClient.ConnectionCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.EngineStatus;
+import android.support.v8.speech.tts.TextToSpeechClient.RequestCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.UtteranceId;
+
+import java.io.File;
+
+interface ITextToSpeechClient {
+ public void setup(Context context, String engine, boolean fallbackToDefaultEngine,
+ RequestCallbacks defaultRequestCallbacks, ConnectionCallbacks connectionCallbacks);
+ public void connect();
+ public boolean isConnected();
+ public void disconnect();
+ public EngineStatus getEngineStatus();
+ public void stop();
+ public void queueSpeak(final String utterance, final UtteranceId utteranceId,
+ final RequestConfig config, final RequestCallbacks callbacks);
+ public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
+ final File outputFile, final RequestConfig config,
+ final RequestCallbacks callbacks);
+ public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
+ final RequestCallbacks callbacks);
+ public void queueAudio(final Uri audioUrl, final UtteranceId utteranceId,
+ final RequestConfig config, final RequestCallbacks callbacks);
+}
\ No newline at end of file
diff --git a/v8/tts/src/android/support/v8/speech/tts/RequestConfig.java b/v8/tts/src/android/support/v8/speech/tts/RequestConfig.java
new file mode 100644
index 0000000..784abfe
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/RequestConfig.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.media.AudioManager;
+import android.os.Bundle;
+
+/**
+ * Synthesis request configuration.
+ *
+ * This class is immutable, and can only be constructed using
+ * {@link RequestConfig.Builder}.
+ */
+public final class RequestConfig {
+
+ /** Builder for constructing RequestConfig objects. */
+ public static final class Builder {
+ private VoiceInfo mCurrentVoiceInfo;
+ private Bundle mVoiceParams;
+ private Bundle mAudioParams;
+
+ Builder(VoiceInfo currentVoiceInfo, Bundle voiceParams, Bundle audioParams) {
+ mCurrentVoiceInfo = currentVoiceInfo;
+ mVoiceParams = voiceParams;
+ mAudioParams = audioParams;
+ }
+
+ /**
+ * Create new RequestConfig builder.
+ */
+ public static Builder newBuilder() {
+ return new Builder(null, new Bundle(), new Bundle());
+ }
+
+ /**
+ * Create new RequestConfig builder.
+ * @param prototype
+ * Prototype of new RequestConfig. Copies all fields of the
+ * prototype to the constructed object.
+ */
+ public static Builder newBuilder(RequestConfig prototype) {
+ return new Builder(prototype.mCurrentVoiceInfo,
+ (Bundle)prototype.mVoiceParams.clone(),
+ (Bundle)prototype.mAudioParams.clone());
+ }
+
+ /** Set voice for request. Will reset voice parameters to the defaults. */
+ public Builder setVoice(VoiceInfo voice) {
+ mCurrentVoiceInfo = voice;
+ mVoiceParams = (Bundle)voice.getParamsWithDefaults().clone();
+ return this;
+ }
+
+ /**
+ * Set request voice parameter.
+ *
+ * @param paramName
+ * The name of the parameter. It has to be one of the keys
+ * from {@link VoiceInfo#getParamsWithDefaults()}
+ * @param value
+ * Value of the parameter. Its type can be one of: Integer, Float,
+ * Boolean, String, VoiceInfo (will be set as a String, result of a call to
+ * the {@link VoiceInfo#getName()}) or byte[]. It has to be of the same type
+ * as the default value from {@link VoiceInfo#getParamsWithDefaults()}
+ * for that parameter.
+ * @throws IllegalArgumentException
+ * If paramName is not a valid parameter name or its value is of a wrong
+ * type.
+ * @throws IllegalStateException
+ * If no voice is set.
+ */
+ public Builder setVoiceParam(String paramName, Object value){
+ if (mCurrentVoiceInfo == null) {
+ throw new IllegalStateException(
+ "Couldn't set voice parameter, no voice is set");
+ }
+ Object defaultValue = mCurrentVoiceInfo.getParamsWithDefaults().get(paramName);
+ if (defaultValue == null) {
+ throw new IllegalArgumentException(
+ "Parameter \"" + paramName + "\" is not available in set voice with " +
+ "name: " + mCurrentVoiceInfo.getName());
+ }
+
+ // If it's VoiceInfo, get its name
+ if (value instanceof VoiceInfo) {
+ value = ((VoiceInfo)value).getName();
+ }
+
+ // Check type information
+ if (!defaultValue.getClass().equals(value.getClass())) {
+ throw new IllegalArgumentException(
+ "Parameter \"" + paramName +"\" is of different type. Value passed has " +
+ "type " + value.getClass().getSimpleName() + " but should have " +
+ "type " + defaultValue.getClass().getSimpleName());
+ }
+
+ setParam(mVoiceParams, paramName, value);
+ return this;
+ }
+
+ /**
+ * Set request audio parameter.
+ *
+ * Doesn't requires a set voice.
+ *
+ * @param paramName
+ * Name of parameter.
+ * @param value
+ * Value of parameter. Its type can be one of: Integer, Float, Boolean, String
+ * or byte[].
+ */
+ public Builder setAudioParam(String paramName, Object value) {
+ setParam(mAudioParams, paramName, value);
+ return this;
+ }
+
+ /**
+ * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_STREAM} audio parameter.
+ *
+ * @param streamId One of the STREAM_ constants defined in {@link AudioManager}.
+ */
+ public void setAudioParamStream(int streamId) {
+ setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_STREAM, streamId);
+ }
+
+ /**
+ * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_VOLUME} audio parameter.
+ *
+ * @param volume Float in range of 0.0 to 1.0.
+ */
+ public void setAudioParamVolume(float volume) {
+ setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_VOLUME, volume);
+ }
+
+ /**
+ * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_PAN} audio parameter.
+ *
+ * @param pan Float in range of -1.0 to +1.0.
+ */
+ public void setAudioParamPan(float pan) {
+ setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_PAN, pan);
+ }
+
+ private void setParam(Bundle bundle, String featureName, Object value) {
+ if (value instanceof String) {
+ bundle.putString(featureName, (String)value);
+ } else if(value instanceof byte[]) {
+ bundle.putByteArray(featureName, (byte[])value);
+ } else if(value instanceof Integer) {
+ bundle.putInt(featureName, (Integer)value);
+ } else if(value instanceof Float) {
+ bundle.putFloat(featureName, (Float)value);
+ } else if(value instanceof Double) {
+ bundle.putFloat(featureName, (Float)value);
+ } else if(value instanceof Boolean) {
+ bundle.putBoolean(featureName, (Boolean)value);
+ } else {
+ throw new IllegalArgumentException("Illegal type of object");
+ }
+ return;
+ }
+
+ /**
+ * Build new RequestConfig instance.
+ */
+ public RequestConfig build() {
+ RequestConfig config =
+ new RequestConfig(mCurrentVoiceInfo, mVoiceParams, mAudioParams);
+ return config;
+ }
+ }
+
+ RequestConfig(VoiceInfo voiceInfo, Bundle voiceParams, Bundle audioParams) {
+ mCurrentVoiceInfo = voiceInfo;
+ mVoiceParams = voiceParams;
+ mAudioParams = audioParams;
+ }
+
+ /**
+ * Currently set voice.
+ */
+ private final VoiceInfo mCurrentVoiceInfo;
+
+ /**
+ * Voice parameters bundle.
+ */
+ private final Bundle mVoiceParams;
+
+ /**
+ * Audio parameters bundle.
+ */
+ private final Bundle mAudioParams;
+
+ /**
+ * @return Currently set request voice.
+ */
+ public VoiceInfo getVoice() {
+ return mCurrentVoiceInfo;
+ }
+
+ /**
+ * @return Request audio parameters.
+ */
+ public Bundle getAudioParams() {
+ return mAudioParams;
+ }
+
+ /**
+ * @return Request voice parameters.
+ */
+ public Bundle getVoiceParams() {
+ return mVoiceParams;
+ }
+
+}
diff --git a/v8/tts/src/android/support/v8/speech/tts/RequestConfigHelper.java b/v8/tts/src/android/support/v8/speech/tts/RequestConfigHelper.java
new file mode 100644
index 0000000..54c8532
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/RequestConfigHelper.java
@@ -0,0 +1,170 @@
+package android.support.v8.speech.tts;
+
+import android.support.v8.speech.tts.TextToSpeechClient.EngineStatus;
+
+import java.util.Locale;
+
+/**
+ * Set of common heuristics for selecting {@link VoiceInfo} from
+ * {@link TextToSpeechClient#getEngineStatus()} output.
+ */
+public final class RequestConfigHelper {
+ private RequestConfigHelper() {}
+
+ /**
+ * Interface for scoring VoiceInfo object.
+ */
+ public static interface VoiceScorer {
+ /**
+ * Score VoiceInfo. If the score is less than or equal to zero, that voice is discarded.
+ * If two voices have same desired primary characteristics (highest quality, lowest
+ * latency or others), the one with the higher score is selected.
+ */
+ public int scoreVoice(VoiceInfo voiceInfo);
+ }
+
+ /**
+ * Score positively voices that exactly match the locale supplied to the constructor.
+ */
+ public static final class ExactLocaleMatcher implements VoiceScorer {
+ private final Locale mLocale;
+
+ /**
+ * Score positively voices that exactly match the given locale
+ * @param locale Reference locale. If null, the default locale will be used.
+ */
+ public ExactLocaleMatcher(Locale locale) {
+ if (locale == null) {
+ mLocale = Locale.getDefault();
+ } else {
+ mLocale = locale;
+ }
+ }
+ @Override
+ public int scoreVoice(VoiceInfo voiceInfo) {
+ return mLocale.equals(voiceInfo.getLocale()) ? 1 : 0;
+ }
+ }
+
+ /**
+ * Score positively voices that match exactly the given locale (score 3)
+ * or that share same language and country (score 2), or that share just a language (score 1).
+ */
+ public static final class LanguageMatcher implements VoiceScorer {
+ private final Locale mLocale;
+
+ /**
+ * Score positively voices with similar locale.
+ * @param locale Reference locale. If null, default will be used.
+ */
+ public LanguageMatcher(Locale locale) {
+ if (locale == null) {
+ mLocale = Locale.getDefault();
+ } else {
+ mLocale = locale;
+ }
+ }
+
+ @Override
+ public int scoreVoice(VoiceInfo voiceInfo) {
+ final Locale voiceLocale = voiceInfo.getLocale();
+ if (mLocale.equals(voiceLocale)) {
+ return 3;
+ } else {
+ if (mLocale.getLanguage().equals(voiceLocale.getLanguage())) {
+ if (mLocale.getCountry().equals(voiceLocale.getCountry())) {
+ return 2;
+ }
+ return 1;
+ }
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Get the highest quality voice from voices that score more than zero from the passed scorer.
+ * If there is more than one voice with the same highest quality, then this method returns one
+ * with the highest score. If they share same score as well, one with the lower index in the
+ * voices list is returned.
+ *
+ * @param engineStatus
+ * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+ * @param voiceScorer
+ * Used to discard unsuitable voices and help settle cases where more than
+ * one voice has the desired characteristic.
+ * @param hasToBeEmbedded
+ * If true, require the voice to be an embedded voice (no network
+ * access will be required for synthesis).
+ */
+ private static VoiceInfo getHighestQualityVoice(EngineStatus engineStatus,
+ VoiceScorer voiceScorer, boolean hasToBeEmbedded) {
+ VoiceInfo bestVoice = null;
+ int bestScoreMatch = 1;
+ int bestVoiceQuality = 0;
+
+ for (VoiceInfo voice : engineStatus.getVoices()) {
+ int score = voiceScorer.scoreVoice(voice);
+ if (score <= 0 || hasToBeEmbedded && voice.getRequiresNetworkConnection()
+ || voice.getQuality() < bestVoiceQuality) {
+ continue;
+ }
+
+ if (bestVoice == null ||
+ voice.getQuality() > bestVoiceQuality ||
+ score > bestScoreMatch) {
+ bestVoice = voice;
+ bestScoreMatch = score;
+ bestVoiceQuality = voice.getQuality();
+ }
+ }
+ return bestVoice;
+ }
+
+ /**
+ * Get highest quality voice.
+ *
+ * Highest quality voice is selected from voices that score more than zero from the passed
+ * scorer. If there is more than one voice with the same highest quality, then this method
+ * will return one with the highest score. If they share same score as well, one with the lower
+ * index in the voices list is returned.
+
+ * @param engineStatus
+ * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+ * @param hasToBeEmbedded
+ * If true, require the voice to be an embedded voice (no network
+ * access will be required for synthesis).
+ * @param voiceScorer
+ * Scorer is used to discard unsuitable voices and help settle cases where more than
+ * one voice has highest quality.
+ * @return RequestConfig with selected voice or null if suitable voice was not found.
+ */
+ public static RequestConfig highestQuality(EngineStatus engineStatus,
+ boolean hasToBeEmbedded, VoiceScorer voiceScorer) {
+ VoiceInfo voice = getHighestQualityVoice(engineStatus, voiceScorer, hasToBeEmbedded);
+ if (voice == null) {
+ return null;
+ }
+ return RequestConfig.Builder.newBuilder().setVoice(voice).build();
+ }
+
+ /**
+ * Get highest quality voice for the default locale.
+ *
+ * Call {@link #highestQuality(EngineStatus, boolean, VoiceScorer)} with
+ * {@link LanguageMatcher} set to device default locale.
+ *
+ * @param engineStatus
+ * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+ * @param hasToBeEmbedded
+ * If true, require the voice to be an embedded voice (no network
+ * access will be required for synthesis).
+ * @return RequestConfig with selected voice or null if suitable voice was not found.
+ */
+ public static RequestConfig highestQuality(EngineStatus engineStatus,
+ boolean hasToBeEmbedded) {
+ return highestQuality(engineStatus, hasToBeEmbedded,
+ new LanguageMatcher(Locale.getDefault()));
+ }
+
+}
diff --git a/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV1.java b/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV1.java
new file mode 100644
index 0000000..cf03537
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV1.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TtsEngines;
+import android.speech.tts.TextToSpeech.Engine;
+import android.speech.tts.TextToSpeech.OnInitListener;
+import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+import android.support.v8.speech.tts.TextToSpeechClient.ConnectionCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.EngineStatus;
+import android.support.v8.speech.tts.TextToSpeechClient.RequestCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.Status;
+import android.support.v8.speech.tts.TextToSpeechClient.UtteranceId;
+import android.support.v8.speech.tts.TextToSpeechICSMR1.UtteranceProgressListenerICSMR1;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Set;
+
+/**
+ * Implementation of the TTS V2 API using V1 API.
+ */
+class TTSImplementationV1 implements ITextToSpeechClient {
+ private static final String TAG = "android.support.v8.speech.tts";
+ private TextToSpeech mOldClient;
+ private Context mContext;
+ private String mEngine;
+ private RequestCallbacks mDefaultRequestCallbacks;
+ private ConnectionCallbacks mConnectionCallbacks;
+ private EngineStatus mEngineStatus;
+ private Object mLock = new Object();
+
+ private volatile boolean mConnected = false;
+
+ public TTSImplementationV1() {
+ }
+
+ TTSImplementationV1(TextToSpeech client) {
+ mOldClient = client;
+ }
+
+ @Override
+ public void setup(Context context, String engine, boolean fallbackToDefaultEngine,
+ RequestCallbacks defaultRequestCallbacks, ConnectionCallbacks connectionCallbacks) {
+ mContext = context;
+ mEngine = engine;
+ mDefaultRequestCallbacks = defaultRequestCallbacks;
+ mConnectionCallbacks = connectionCallbacks;
+ }
+
+ @Override
+ public EngineStatus getEngineStatus() {
+ return mEngineStatus;
+ }
+
+ OnInitListener mOnInitListener = new OnInitListener() {
+ public void onInit(int status) {
+ mConnected = true;
+ if (status == TextToSpeech.SUCCESS) {
+ TTSImplementationV1.this.onInit();
+ mConnectionCallbacks.onConnectionSuccess();
+ } else {
+ mConnectionCallbacks.onConnectionFailure();
+ }
+ }
+ };
+
+ private void onInit() {
+ mEngineStatus = generateEngineStatus();
+ TextToSpeechICSMR1.setUtteranceProgressListener(mOldClient,
+ new UtteranceProgressListenerICSMR1() {
+ @Override
+ public void onStart(String utteranceId) {
+ RequestInternal requestInternal = getCallback(utteranceId);
+ if (requestInternal == null) {
+ return;
+ }
+ requestInternal.requestCallbacks.onSynthesisStart(
+ requestInternal.utteranceId);
+ }
+
+ @Override
+ public void onError(String utteranceId) {
+ RequestInternal requestInternal =
+ removeCallback(utteranceId);
+ if (requestInternal == null) {
+ return;
+ }
+ requestInternal.requestCallbacks.onSynthesisFailure(
+ requestInternal.utteranceId,
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+
+ @Override
+ public void onDone(String utteranceId) {
+ RequestInternal requestInternal =
+ removeCallback(utteranceId);
+ if (requestInternal == null) {
+ return;
+ }
+ requestInternal.requestCallbacks.onSynthesisSuccess(
+ requestInternal.utteranceId);
+ }
+ });
+ }
+
+ @Override
+ public void connect() {
+ if (mOldClient != null) {
+ Log.w(TAG, "Already connected");
+ return;
+ }
+ mOldClient = TextToSpeechICS.construct(mContext, mOnInitListener, mEngine);
+ }
+
+ /** Internal info about a request. */
+ private static class RequestInternal {
+ UtteranceId utteranceId;
+ RequestCallbacks requestCallbacks;
+
+ public RequestInternal(UtteranceId utteranceId, RequestCallbacks requestCallbacks) {
+ super();
+ this.utteranceId = utteranceId;
+ this.requestCallbacks = requestCallbacks;
+ }
+ }
+
+ /** Map of request, keyed by their utteranceId */
+ private HashMap<String, RequestInternal > mUtteranceIdToRequest =
+ new HashMap<String, RequestInternal>();
+
+ /**
+ * Register callback.
+ *
+ * @param utteranceId Non-null utteranceIf instance.
+ * @param callback Non-null callbacks for the request
+ * @return Status.SUCCESS or error code in case of invalid arguments.
+ */
+ private int addCallback(UtteranceId utteranceId, RequestCallbacks callback) {
+ synchronized (mLock) {
+ if (utteranceId == null || callback == null) {
+ return Status.ERROR_INVALID_REQUEST;
+ }
+ if (mUtteranceIdToRequest.put(utteranceId.toUniqueString(),
+ new RequestInternal(utteranceId, callback)) != null) {
+ return Status.ERROR_NON_UNIQUE_UTTERANCE_ID;
+ }
+ return Status.SUCCESS;
+ }
+ }
+
+ /**
+ * Remove and return callback.
+ *
+ * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+ */
+ private RequestInternal removeCallback(String utteranceIdStr) {
+ synchronized (mLock) {
+ return mUtteranceIdToRequest.remove(utteranceIdStr);
+ }
+ }
+
+ /**
+ * Get callback and utterance id.
+ *
+ * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+ */
+ private RequestInternal getCallback(String utteranceIdStr) {
+ synchronized (mLock) {
+ return mUtteranceIdToRequest.get(utteranceIdStr);
+ }
+ }
+
+ /**
+ * Remove callback and call {@link RequestCallbacks#onSynthesisFailure} with passed
+ * error code.
+ *
+ * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+ * @param errorCode argument to {@link RequestCallbacks#onSynthesisFailure} call.
+ */
+ private void removeCallbackAndErr(String utteranceIdStr, int errorCode) {
+ synchronized (mLock) {
+ RequestInternal c = mUtteranceIdToRequest.remove(utteranceIdStr);
+ c.requestCallbacks.onSynthesisFailure(c.utteranceId, errorCode);
+ }
+ }
+
+ /** Internal private data attached to VoiceInfo */
+ private static class VoiceInfoPrivate {
+ static final int VOICE_TYPE_EMBEDDED = 1;
+ static final int VOICE_TYPE_NETWORK = 2;
+ static final int VOICE_TYPE_UNKNOWN = 3;
+
+ int mVoiceType;
+
+ public VoiceInfoPrivate(int voiceType) {
+ super();
+ this.mVoiceType = voiceType;
+ }
+
+ static int getVoiceType(VoiceInfo voiceInfo) {
+ return ((VoiceInfoPrivate)voiceInfo.getPrivateData()).mVoiceType;
+ }
+ }
+
+ private EngineStatus generateEngineStatus() {
+ Bundle defaultParams = new Bundle();
+ defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_PITCH, 1.0f);
+ defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, -1.0f);
+
+ // Enumerate all locales and check if they are available
+ ArrayList<VoiceInfo> voicesInfo = new ArrayList<VoiceInfo>();
+ for (Locale locale : Locale.getAvailableLocales()) {
+ int expectedStatus = TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
+ if (locale.getVariant().length() == 0) {
+ if (locale.getCountry().length() == 0) {
+ expectedStatus = TextToSpeech.LANG_AVAILABLE;
+ } else {
+ expectedStatus = TextToSpeech.LANG_COUNTRY_AVAILABLE;
+ }
+ }
+ try {
+ // Call those to prevent log spam from isLanguageAvailable.
+ locale.getISO3Language();
+ if (!locale.getCountry().isEmpty()) {
+ locale.getISO3Country();
+ }
+ if (mOldClient.isLanguageAvailable(locale) != expectedStatus) {
+ continue;
+ }
+ } catch (MissingResourceException e) {
+ // Ignore locale without iso 3 codes
+ continue;
+ }
+
+ Set<String> features = TextToSpeechICSMR1.getFeatures(mOldClient, locale);
+
+ VoiceInfo.Builder builder = new VoiceInfo.Builder();
+ builder.setLatency(VoiceInfo.LATENCY_NORMAL);
+ builder.setQuality(VoiceInfo.QUALITY_NORMAL);
+ builder.setLocale(locale);
+ builder.setParamsWithDefaults(defaultParams);
+
+ boolean isUnknown = true;
+ if (features != null && features.contains("embeddedTts")) {
+ isUnknown = false;
+ builder.setName(locale.toString() + "-embedded");
+ builder.setRequiresNetworkConnection(false);
+ builder.setPrivateData(
+ new VoiceInfoPrivate(
+ VoiceInfoPrivate.VOICE_TYPE_EMBEDDED));
+ voicesInfo.add(builder.build());
+ }
+
+ if (features != null && features.contains("networkTts")) {
+ isUnknown = false;
+ builder.setName(locale.toString() + "-network");
+ builder.setRequiresNetworkConnection(true);
+ builder.setPrivateData(
+ new VoiceInfoPrivate(
+ VoiceInfoPrivate.VOICE_TYPE_NETWORK));
+ voicesInfo.add(builder.build());
+ }
+
+ if (isUnknown) {
+ builder.setName(locale.toString());
+ builder.setRequiresNetworkConnection(false);
+ builder.setPrivateData(
+ new VoiceInfoPrivate(
+ VoiceInfoPrivate.VOICE_TYPE_UNKNOWN));
+ voicesInfo.add(builder.build());
+ }
+ }
+
+ return new EngineStatus(mEngine, voicesInfo);
+ }
+
+ @Override
+ public boolean isConnected() {
+ return (mOldClient != null) && mConnected;
+ }
+
+ @Override
+ public void disconnect() {
+ if (mOldClient == null) {
+ Log.w(TAG, "Already disconnected");
+ return;
+ }
+ synchronized (mOldClient) {
+ mOldClient.shutdown();
+ mOldClient = null;
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (mOldClient == null) {
+ Log.e(TAG, "Client is not connected");
+ return;
+ }
+ synchronized (mOldClient) {
+ mOldClient.stop();
+ }
+ }
+
+ private HashMap<String, String> createParameters(final RequestConfig config,
+ final UtteranceId utteranceId) {
+ HashMap<String, String> parameters = new HashMap<String, String>();
+ parameters.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId.toUniqueString());
+
+ int voiceType = VoiceInfoPrivate.getVoiceType(config.getVoice());
+ if (voiceType == VoiceInfoPrivate.VOICE_TYPE_NETWORK) {
+ parameters.put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS,
+ "true");
+ } else if (voiceType == VoiceInfoPrivate.VOICE_TYPE_EMBEDDED) {
+ parameters.put(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS,
+ "true");
+ }
+ return parameters;
+ }
+ @Override
+ public void queueSpeak(final String utterance, final UtteranceId utteranceId,
+ final RequestConfig config, final RequestCallbacks callbacks) {
+ if (mOldClient == null || !mConnected) {
+ Log.e(TAG, "Client is not connected");
+ return;
+ }
+
+ synchronized (mOldClient) {
+ if (callbacks != null) {
+ addCallback(utteranceId, callbacks);
+ } else {
+ addCallback(utteranceId, mDefaultRequestCallbacks);
+ }
+ mOldClient.setLanguage(config.getVoice().getLocale());
+ float speed = config.getVoiceParams().getFloat(
+ TextToSpeechClient.Params.SPEECH_SPEED);
+ // We use getDefaultSpeechRate, because once we set a speed,
+ // there's no mechanism to revert it to the default
+ mOldClient.setSpeechRate((speed > 0) ? speed : getDefaultSpeechRate());
+ mOldClient.setPitch(config.getVoiceParams().getFloat(
+ TextToSpeechClient.Params.SPEECH_PITCH));
+ if (mOldClient.speak(utterance, TextToSpeech.QUEUE_ADD,
+ createParameters(config, utteranceId)) != TextToSpeech.SUCCESS) {
+ removeCallbackAndErr(utteranceId.toUniqueString(),
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+ }
+ }
+
+ @Override
+ public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
+ final File outputFile, final RequestConfig config,
+ final RequestCallbacks callbacks) {
+ if (mOldClient == null || !mConnected) {
+ Log.e(TAG, "Client is not connected");
+ return;
+ }
+
+ synchronized (mOldClient) {
+ if (callbacks != null) {
+ addCallback(utteranceId, callbacks);
+ } else {
+ addCallback(utteranceId, mDefaultRequestCallbacks);
+ }
+ mOldClient.setLanguage(config.getVoice().getLocale());
+ float speed = config.getVoiceParams().getFloat(
+ TextToSpeechClient.Params.SPEECH_SPEED);
+ // We use getDefaultSpeechRate, because once we set a speed,
+ // there's no mechanism to revert it to the default
+ mOldClient.setSpeechRate((speed > 0) ? speed : getDefaultSpeechRate());
+ mOldClient.setPitch(config.getVoiceParams().getFloat(
+ TextToSpeechClient.Params.SPEECH_PITCH));
+ if (mOldClient.synthesizeToFile(utterance, createParameters(config, utteranceId),
+ outputFile.getAbsolutePath()) != TextToSpeech.SUCCESS) {
+ removeCallbackAndErr(utteranceId.toUniqueString(),
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+ }
+ }
+
+ @Override
+ public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
+ final RequestCallbacks callbacks) {
+ if (mOldClient == null || !mConnected) {
+ Log.e(TAG, "Client is not connected");
+ return;
+ }
+
+ synchronized (mOldClient) {
+ if (callbacks != null) {
+ addCallback(utteranceId, callbacks);
+ } else {
+ addCallback(utteranceId, mDefaultRequestCallbacks);
+ }
+ if (mOldClient.playSilence(durationInMs, TextToSpeech.QUEUE_ADD,
+ createParameters(null, utteranceId)) != TextToSpeech.SUCCESS) {
+ removeCallbackAndErr(utteranceId.toUniqueString(),
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+ }
+ }
+
+ @Override
+ public void queueAudio(final Uri audioUri, final UtteranceId utteranceId,
+ final RequestConfig config, final RequestCallbacks callbacks) {
+ if (mOldClient == null || !mConnected) {
+ Log.e(TAG, "Client is not connected");
+ return;
+ }
+
+ synchronized (mOldClient) {
+ if (callbacks != null) {
+ addCallback(utteranceId, callbacks);
+ } else {
+ addCallback(utteranceId, mDefaultRequestCallbacks);
+ }
+ final String earconName = audioUri.toString();
+ mOldClient.setLanguage(config.getVoice().getLocale());
+ mOldClient.addEarcon(earconName, earconName);
+ if (mOldClient.playEarcon(earconName, TextToSpeech.QUEUE_ADD,
+ createParameters(config, utteranceId)) != TextToSpeech.SUCCESS) {
+ removeCallbackAndErr(utteranceId.toUniqueString(),
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+ }
+ }
+
+ /** Read default speech speed rate from settings */
+ float getDefaultSpeechRate() {
+ return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE) / 100.0f;
+ }
+
+ int getSecureSettingInt(String name, int defaultValue) {
+ return Settings.Secure.getInt(mContext.getContentResolver(), name, defaultValue);
+ }
+}
\ No newline at end of file
diff --git a/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV2.java b/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV2.java
new file mode 100644
index 0000000..2608fa6
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/TTSImplementationV2.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.v8.speech.tts.TextToSpeechClient.ConnectionCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.EngineStatus;
+import android.support.v8.speech.tts.TextToSpeechClient.RequestCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.UtteranceId;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/** Simple bridge to the actual TTS V2 implementation. */
+class TTSImplementationV2 implements ITextToSpeechClient {
+ private static final String TAG = "android.support.v8.speech.tts";
+
+ interface TextToSpeechClientConstructor {
+ public android.speech.tts.TextToSpeechClient newClient(
+ Context context, String engine, boolean fallbackToDefaultEngine,
+ android.speech.tts.TextToSpeechClient.RequestCallbacks defaultRequestCallbacks,
+ android.speech.tts.TextToSpeechClient.ConnectionCallbacks connectionCallbacks);
+ }
+
+ private TextToSpeechClientConstructor mClientConstructor;
+
+ private android.speech.tts.TextToSpeechClient mClient;
+
+ TTSImplementationV2() {
+ }
+
+ TTSImplementationV2(TextToSpeechClientConstructor constructor) {
+ mClientConstructor = constructor;
+ }
+
+ @Override
+ public void setup(Context context, String engine, boolean fallbackToDefaultEngine,
+ RequestCallbacks defaultRequestCallbacks, ConnectionCallbacks connectionCallbacks) {
+ if (mClient != null) {
+ Log.e(TAG, "Implementation already set up");
+ return;
+ }
+ if (mClientConstructor != null) {
+ mClient = mClientConstructor.newClient(
+ context, engine, fallbackToDefaultEngine, convert(defaultRequestCallbacks),
+ convert(connectionCallbacks));
+ } else {
+ mClient = new android.speech.tts.TextToSpeechClient(context, engine,
+ fallbackToDefaultEngine, convert(defaultRequestCallbacks),
+ convert(connectionCallbacks));
+ }
+ }
+
+ private static class InternalUtteranceId extends
+ android.speech.tts.TextToSpeechClient.UtteranceId {
+ private UtteranceId mExternalUtteranceId;
+
+ public InternalUtteranceId(UtteranceId externalUtteranceId) {
+ mExternalUtteranceId = externalUtteranceId;
+ }
+
+ public UtteranceId getExternalUtteranceId() {
+ return mExternalUtteranceId;
+ }
+ }
+
+ @Override
+ public void connect() {
+ if (mClient != null) {
+ mClient.connect();
+ } else {
+ Log.e(TAG, "Implementation is not set up");
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ return (mClient != null) && mClient.isConnected();
+ }
+
+ @Override
+ public void disconnect() {
+ if (mClient != null) {
+ mClient.disconnect();
+ } else {
+ Log.e(TAG, "Implementation is not set up");
+ }
+ }
+
+ @Override
+ public EngineStatus getEngineStatus() {
+ return convert(mClient.getEngineStatus());
+ }
+
+ @Override
+ public void stop() {
+ mClient.stop();
+ }
+
+ @Override
+ public void queueSpeak(String utterance, UtteranceId utteranceId, RequestConfig config,
+ RequestCallbacks callbacks) {
+ mClient.queueSpeak(utterance, convert(utteranceId), convert(config), convert(callbacks));
+ }
+
+ @Override
+ public void queueSynthesizeToFile(String utterance, UtteranceId utteranceId, File outputFile,
+ RequestConfig config, RequestCallbacks callbacks) {
+ mClient.queueSynthesizeToFile(utterance, convert(utteranceId), outputFile, convert(config),
+ convert(callbacks));
+ }
+
+ @Override
+ public void queueSilence(long durationInMs, UtteranceId utteranceId,
+ RequestCallbacks callbacks) {
+ mClient.queueSilence(durationInMs, convert(utteranceId), convert(callbacks));
+ }
+
+ @Override
+ public void queueAudio(Uri audioUrl, UtteranceId utteranceId, RequestConfig config,
+ RequestCallbacks callbacks) {
+ mClient.queueAudio(audioUrl, convert(utteranceId), convert(config), convert(callbacks));
+ }
+
+ static android.speech.tts.RequestConfig convert(RequestConfig config) {
+ android.speech.tts.RequestConfig.Builder builder =
+ android.speech.tts.RequestConfig.Builder.newBuilder();
+ builder.setVoice(convert(config.getVoice()));
+ for (String key : config.getAudioParams().keySet()) {
+ builder.setAudioParam(key, config.getAudioParams().get(key));
+ }
+ for (String key : config.getVoiceParams().keySet()) {
+ builder.setVoiceParam(key, config.getVoiceParams().get(key));
+ }
+ return builder.build();
+ }
+
+ static android.speech.tts.VoiceInfo convert(VoiceInfo voice) {
+ return (android.speech.tts.VoiceInfo)voice.getPrivateData();
+ }
+
+
+ static UtteranceId convert(android.speech.tts.TextToSpeechClient.UtteranceId utteranceId) {
+ return ((InternalUtteranceId)utteranceId).getExternalUtteranceId();
+ }
+
+ static android.speech.tts.TextToSpeechClient.UtteranceId convert(UtteranceId utteranceId) {
+ return new InternalUtteranceId(utteranceId);
+ }
+
+ static TextToSpeechClient.EngineStatus convert(
+ android.speech.tts.TextToSpeechClient.EngineStatus engineStatus) {
+ ArrayList<VoiceInfo> voices = new ArrayList<VoiceInfo>();
+ for (android.speech.tts.VoiceInfo coreVoiceInfo : engineStatus.getVoices()) {
+ voices.add(convert(coreVoiceInfo));
+ }
+ return new TextToSpeechClient.EngineStatus(
+ engineStatus.getEnginePackage(), voices);
+ }
+
+ static VoiceInfo convert(android.speech.tts.VoiceInfo voiceInfo) {
+ return new VoiceInfo(voiceInfo.getName(), voiceInfo.getLocale(),
+ voiceInfo.getQuality(), voiceInfo.getLatency(),
+ voiceInfo.getRequiresNetworkConnection(), voiceInfo.getParamsWithDefaults(),
+ voiceInfo.getAdditionalFeatures(), voiceInfo);
+ }
+
+ static android.speech.tts.TextToSpeechClient.RequestCallbacks convert(
+ final TextToSpeechClient.RequestCallbacks callbacks) {
+ return new android.speech.tts.TextToSpeechClient.RequestCallbacks() {
+
+ @Override
+ public void onSynthesisFailure(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId, int errorCode) {
+ callbacks.onSynthesisFailure(convert(utteranceId), errorCode);
+ }
+ @Override
+ public void onSynthesisProgress(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId, int charIndex,
+ int msFromStart) {
+ callbacks.onSynthesisProgress(convert(utteranceId), charIndex, msFromStart);
+ }
+ @Override
+ public void onSynthesisFallback(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId) {
+ callbacks.onSynthesisFallback(convert(utteranceId));
+ }
+ @Override
+ public void onSynthesisStart(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId) {
+ callbacks.onSynthesisStart(convert(utteranceId));
+ }
+ @Override
+ public void onSynthesisStop(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId) {
+ callbacks.onSynthesisStop(convert(utteranceId));
+ }
+ @Override
+ public void onSynthesisSuccess(
+ android.speech.tts.TextToSpeechClient.UtteranceId utteranceId) {
+ callbacks.onSynthesisSuccess(convert(utteranceId));
+ }
+ };
+ }
+
+ static android.speech.tts.TextToSpeechClient.ConnectionCallbacks convert(
+ final TextToSpeechClient.ConnectionCallbacks connectionCallbacks) {
+ return new android.speech.tts.TextToSpeechClient.ConnectionCallbacks() {
+ @Override
+ public void onConnectionSuccess() {
+ connectionCallbacks.onConnectionSuccess();
+ }
+
+ @Override
+ public void onConnectionFailure() {
+ connectionCallbacks.onConnectionFailure();
+ }
+
+ @Override
+ public void onServiceDisconnected() {
+ connectionCallbacks.onServiceDisconnected();
+ }
+
+ @Override
+ public void onEngineStatusChange(
+ android.speech.tts.TextToSpeechClient.EngineStatus newEngineStatus) {
+ connectionCallbacks.onEngineStatusChange(convert(newEngineStatus));
+ }
+ };
+ }
+}
diff --git a/v8/tts/src/android/support/v8/speech/tts/TextToSpeechClient.java b/v8/tts/src/android/support/v8/speech/tts/TextToSpeechClient.java
new file mode 100644
index 0000000..13ac1fa
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/TextToSpeechClient.java
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Build;
+import android.speech.tts.TextToSpeech;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Synthesizes speech from text for immediate playback or to create a sound
+ * file.
+ * <p>
+ * This is an updated version of the speech synthesis client that supersedes
+ * {@link android.speech.tts.TextToSpeech}.
+ * <p>
+ * A TextToSpeechClient instance can only be used to synthesize text once it has
+ * connected to the service. The TextToSpeechClient instance will start establishing
+ * the connection after a call to the {@link #connect()} method. This is usually done in
+ * {@link android.app.Application#onCreate()} or {@link android.app.Activity#onCreate}. When the
+ * connection is established, the instance will call back using the
+ * {@link TextToSpeechClient.ConnectionCallbacks} interface. Only after a
+ * successful callback is the client usable.
+ * <p>
+ * After successful connection, the list of all available voices can be obtained
+ * by calling the {@link TextToSpeechClient#getEngineStatus()} method. The client can
+ * choose a voice using some custom heuristic and build a {@link RequestConfig} object
+ * using {@link RequestConfig.Builder}, or can use one of the common heuristics found
+ * in ({@link RequestConfigHelper}.
+ * <p>
+ * When you are done using the TextToSpeechClient instance, call the
+ * {@link #disconnect()} method to release the connection.
+ * <p>
+ * In the rare case of a change to the set of available voices, the service will call to the
+ * {@link ConnectionCallbacks#onEngineStatusChange} with new set of available voices as argument.
+ * In response, the client HAVE to recreate all {@link RequestConfig} instances in use.
+ */
+public class TextToSpeechClient {
+ private static final String TAG = "TextToSpeechClient";
+
+ /** Common voices parameters */
+ public static final class Params {
+ private Params() {}
+
+ /**
+ * Maximum allowed time for a single request attempt, in milliseconds, before synthesis
+ * fails (or fallback request starts, if requested using
+ * {@link #FALLBACK_VOICE_NAME}).
+ */
+ public static final String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+
+ /**
+ * Number of network request retries that are attempted in case of failure
+ */
+ public static final String NETWORK_RETRIES_COUNT = "networkRetriesCount";
+
+ /**
+ * Should synthesizer report sub-utterance progress on synthesis. Only applicable
+ * for the {@link TextToSpeechClient#queueSpeak} method.
+ */
+ public static final String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
+
+ /**
+ * If a voice exposes this parameter then it supports the fallback request feature.
+ *
+ * If it is set to a valid name of some other voice ({@link VoiceInfo#getName()}) then
+ * in case of request failure (due to network problems or missing data), fallback request
+ * will be attempted. Request will be done using the voice referenced by this parameter.
+ * If it is the case, the client will be informed by a callback to the {@link
+ * RequestCallbacks#onSynthesisFallback(UtteranceId)}.
+ */
+ public static final String FALLBACK_VOICE_NAME = "fallbackVoiceName";
+
+ /**
+ * Audio parameter for specifying a linear multiplier to the speaking speed of the voice.
+ * The value is a float. Values below zero decrease speed of the synthesized speech
+ * values above one increase it. If the value of this parameter is equal to zero,
+ * then it will be replaced by a settings-configurable default before it reaches
+ * TTS service.
+ */
+ public static final String SPEECH_SPEED = "speechSpeed";
+
+ /**
+ * Audio parameter for controlling the pitch of the output. The Value is a positive float,
+ * with default of {@code 1.0}. The value is used to scale the primary frequency linearly.
+ * Lower values lower the tone of the synthesized voice, greater values increase it.
+ */
+ public static final String SPEECH_PITCH = "speechPitch";
+
+ /**
+ * Audio parameter for controlling output volume. Value is a float with scale of 0 to 1
+ */
+ public static final String AUDIO_PARAM_VOLUME = "volume";
+
+ /**
+ * Audio parameter for controlling output pan.
+ * Value is a float ranging from -1 to +1 where -1 maps to a hard-left pan,
+ * 0 to center (the default behavior), and +1 to hard-right.
+ */
+ public static final String AUDIO_PARAM_PAN = "pan";
+
+ /**
+ * Audio parameter for specifying the audio stream type to be used when speaking text
+ * or playing back a file. The value should be one of the STREAM_ constants
+ * defined in {@link android.media.AudioManager}.
+ */
+ public static final String AUDIO_PARAM_STREAM = TextToSpeech.Engine.KEY_PARAM_STREAM;
+ }
+
+ /**
+ * Result codes for TTS operations.
+ */
+ public static final class Status {
+ private Status() {}
+
+ /**
+ * Denotes a successful operation.
+ */
+ public static final int SUCCESS = 0;
+
+ /**
+ * Denotes a stop requested by a client. It's used only on the service side of the API,
+ * client should never expect to see this result code.
+ */
+ public static final int STOPPED = 100;
+
+ /**
+ * Denotes a generic failure.
+ */
+ public static final int ERROR_UNKNOWN = -1;
+
+ /**
+ * Denotes a failure of a TTS engine to synthesize the given input.
+ */
+ public static final int ERROR_SYNTHESIS = 10;
+
+ /**
+ * Denotes a failure of a TTS service.
+ */
+ public static final int ERROR_SERVICE = 11;
+
+ /**
+ * Denotes a failure related to the output (audio device or a file).
+ */
+ public static final int ERROR_OUTPUT = 12;
+
+ /**
+ * Denotes a failure caused by a network connectivity problems.
+ */
+ public static final int ERROR_NETWORK = 13;
+
+ /**
+ * Denotes a failure caused by network timeout.
+ */
+ public static final int ERROR_NETWORK_TIMEOUT = 14;
+
+ /**
+ * Denotes a failure caused by an invalid request.
+ */
+ public static final int ERROR_INVALID_REQUEST = 15;
+
+ /**
+ * Denotes a failure related to passing a non-unique utterance id.
+ */
+ public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16;
+
+ /**
+ * Denotes a failure related to missing data. The TTS implementation may download
+ * the missing data, and if so, request will succeed in future. This error can only happen
+ * for voices with {@link VoiceInfo#FEATURE_MAY_AUTOINSTALL} feature.
+ * Note: the recommended way to avoid this error is to create a request with the fallback
+ * voice.
+ */
+ public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17;
+ }
+
+ /**
+ * Set of callbacks for the events related to the progress of a synthesis request
+ * through the synthesis queue. Each synthesis request is associated with a call to
+ * {@link #queueSpeak} or {@link #queueSynthesizeToFile}.
+ *
+ * The callbacks specified in this method will NOT be called on UI thread.
+ */
+ public static abstract class RequestCallbacks {
+ /**
+ * Called after synthesis of utterance successfully starts.
+ */
+ public void onSynthesisStart(UtteranceId utteranceId) {}
+
+ /**
+ * Called after synthesis successfully finishes.
+ * @param utteranceId
+ * Unique identifier of synthesized utterance.
+ */
+ public void onSynthesisSuccess(UtteranceId utteranceId) {}
+
+ /**
+ * Called after synthesis was stopped in middle of synthesis process.
+ * @param utteranceId
+ * Unique identifier of synthesized utterance.
+ */
+ public void onSynthesisStop(UtteranceId utteranceId) {}
+
+ /**
+ * Called when requested synthesis failed and fallback synthesis is about to be attempted.
+ *
+ * Requires voice with available {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}
+ * parameter, and request with this parameter enabled.
+ *
+ * This callback will be followed by callback to the {@link #onSynthesisStart},
+ * {@link #onSynthesisFailure} or {@link #onSynthesisSuccess} that depends on the
+ * fallback outcome.
+ *
+ * For more fallback feature reference, look at the
+ * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}.
+ *
+ * @param utteranceId
+ * Unique identifier of synthesized utterance.
+ */
+ public void onSynthesisFallback(UtteranceId utteranceId) {}
+
+ /**
+ * Called after synthesis of utterance fails.
+ *
+ * It may be called instead or after a {@link #onSynthesisStart} callback.
+ *
+ * @param utteranceId
+ * Unique identifier of synthesized utterance.
+ * @param errorCode
+ * One of the values from {@link Status}.
+ */
+ public void onSynthesisFailure(UtteranceId utteranceId, int errorCode) {}
+
+ /**
+ * Called during synthesis to mark synthesis progress.
+ *
+ * Requires voice with available
+ * {@link TextToSpeechClient.Params#TRACK_SUBUTTERANCE_PROGRESS} parameter, and
+ * request with this parameter enabled.
+ *
+ * @param utteranceId
+ * Unique identifier of synthesized utterance.
+ * @param charIndex
+ * String index (java char offset) of recently synthesized character.
+ * @param msFromStart
+ * Miliseconds from the start of the synthesis.
+ */
+ public void onSynthesisProgress(UtteranceId utteranceId, int charIndex,
+ int msFromStart) {}
+ }
+
+ /**
+ * Interface definition of callbacks that are called when the client is
+ * connected or disconnected from the TTS service.
+ */
+ public static interface ConnectionCallbacks {
+ /**
+ * After calling {@link TextToSpeechClient#connect()}, this method will be invoked
+ * asynchronously when the connect request has successfully completed.
+ *
+ * Clients are strongly encouraged to call {@link TextToSpeechClient#getEngineStatus()}
+ * and create {@link RequestConfig} objects used in subsequent synthesis requests.
+ */
+ public void onConnectionSuccess();
+
+ /**
+ * After calling {@link TextToSpeechClient#connect()}, this method may be invoked
+ * asynchronously when the connect request has failed to complete.
+ *
+ * It may be also invoked synchronously, from the body of
+ * {@link TextToSpeechClient#connect()} method.
+ */
+ public void onConnectionFailure();
+
+ /**
+ * Called when the connection to the service is lost. This can happen if there is a problem
+ * with the speech service (e.g. a crash or resource problem causes it to be killed by the
+ * system). When called, all requests have been canceled and no outstanding listeners will
+ * be executed. Applications should disable UI components that require the service.
+ */
+ public void onServiceDisconnected();
+
+ /**
+ * After receiving {@link #onConnectionSuccess()} callback, this method may be invoked
+ * if engine status obtained from {@link TextToSpeechClient#getEngineStatus()}) changes.
+ * It usually means that some voices were removed, changed or added.
+ *
+ * Clients are required to recreate {@link RequestConfig} objects used in subsequent
+ * synthesis requests.
+ */
+ public void onEngineStatusChange(EngineStatus newEngineStatus);
+ }
+
+ /** State of voices as provided by engine and user. */
+ public static final class EngineStatus {
+ /** All available voices. */
+ private final List<VoiceInfo> mVoices;
+
+ /** Name of the TTS engine package */
+ private final String mPackageName;
+
+ EngineStatus(String packageName, List<VoiceInfo> voices) {
+ this.mVoices = Collections.unmodifiableList(voices);
+ this.mPackageName = packageName;
+ }
+
+ /**
+ * Get an immutable list of all Voices exposed by the TTS engine.
+ */
+ public List<VoiceInfo> getVoices() {
+ return mVoices;
+ }
+
+ /**
+ * Get name of the TTS engine package currently in use.
+ */
+ public String getEnginePackage() {
+ return mPackageName;
+ }
+ }
+
+ /** Unique synthesis request identifier. */
+ public static class UtteranceId {
+ /** Unique identifier */
+ private final int id;
+
+ /** Unique identifier generator */
+ private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
+
+ /**
+ * Create new, unique UtteranceId instance.
+ */
+ public UtteranceId() {
+ id = ID_GENERATOR.getAndIncrement();
+ }
+
+ /**
+ * Returns a unique string associated with an instance of this object.
+ *
+ * This string will be used to identify the synthesis request/utterance inside the
+ * TTS service.
+ */
+ public final String toUniqueString() {
+ return "UID" + id;
+ }
+ }
+
+ private final ITextToSpeechClient mImplementation;
+
+ /**
+ * Create TextToSpeech service client.
+ *
+ * Will connect to the default TTS service. In order to be usable, {@link #connect()} need
+ * to be called first and successful connection callback need to be received.
+ *
+ * @param context
+ * The context this instance is running in.
+ * @param engine
+ * Package name of requested TTS engine. If it's null, then default engine will
+ * be selected regardless of {@code fallbackToDefaultEngine} parameter value.
+ * @param fallbackToDefaultEngine
+ * If requested engine is not available, should we fallback to the default engine?
+ * @param defaultRequestCallbacks
+ * Default request callbacks, it will be used for all synthesis requests without
+ * supplied RequestCallbacks instance. Can't be null.
+ * @param connectionCallbacks
+ * Callbacks for connecting and disconnecting from the service. Can't be null.
+ */
+ public TextToSpeechClient(Context context,
+ String engine, boolean fallbackToDefaultEngine,
+ RequestCallbacks defaultRequestCallbacks,
+ ConnectionCallbacks connectionCallbacks) {
+ if (Build.VERSION.CODENAME.equals("L")) {
+ mImplementation = new TTSImplementationV2();
+ } else {
+ mImplementation = new TTSImplementationV1();
+ }
+ mImplementation.setup(context, engine, fallbackToDefaultEngine, defaultRequestCallbacks,
+ connectionCallbacks);
+ }
+
+ /**
+ * Create TextToSpeech service client. Will connect to the default TTS
+ * service. In order to be usable, {@link #connect()} need to be called
+ * first and successful connection callback need to be received.
+ *
+ * @param context Context this instance is running in.
+ * @param defaultRequestCallbacks Default request callbacks, it
+ * will be used for all synthesis requests without supplied
+ * RequestCallbacks instance. Can't be null.
+ * @param connectionCallbacks Callbacks for connecting and disconnecting
+ * from the service. Can't be null.
+ */
+ public TextToSpeechClient(Context context, RequestCallbacks defaultRequestCallbacks,
+ ConnectionCallbacks connectionCallbacks) {
+ this(context, null, true, defaultRequestCallbacks, connectionCallbacks);
+ }
+
+ TextToSpeechClient(ITextToSpeechClient implementation,
+ Context context, String engine, boolean fallbackToDefaultEngine,
+ RequestCallbacks defaultRequestCallbacks,
+ ConnectionCallbacks connectionCallbacks) {
+ mImplementation = implementation;
+ mImplementation.setup(context, engine, fallbackToDefaultEngine, defaultRequestCallbacks,
+ connectionCallbacks);
+ }
+
+ /**
+ * Connects the client to TTS service. This method returns immediately, and connects to the
+ * service in the background.
+ *
+ * After connection initializes successfully, {@link ConnectionCallbacks#onConnectionSuccess()}
+ * is called. On a failure {@link ConnectionCallbacks#onConnectionFailure} is called.
+ *
+ * Both of those callback may be called asynchronously on the main thread,
+ * {@link ConnectionCallbacks#onConnectionFailure} may be called synchronously, before
+ * this method returns.
+ */
+ public void connect() {
+ mImplementation.connect();
+ }
+
+ /**
+ * Checks if the client is currently connected to the service, so that
+ * requests to other methods will succeed.
+ */
+ public boolean isConnected() {
+ return mImplementation.isConnected();
+ }
+
+ /**
+ * Closes the connection to TextToSpeech service. No calls can be made on this object after
+ * calling this method.
+ * It is good practice to call this method in the onDestroy() method of an Activity
+ * so the TextToSpeech engine can be cleanly stopped.
+ */
+ public void disconnect() {
+ mImplementation.disconnect();
+ }
+
+ /**
+ * Retrieve TTS engine status {@link EngineStatus}. Requires connected client.
+ */
+ public EngineStatus getEngineStatus() {
+ return mImplementation.getEngineStatus();
+ }
+
+ /**
+ * Interrupts the current utterance spoken (whether played or rendered to file) and discards
+ * other utterances in the queue.
+ */
+ public void stop() {
+ if (mImplementation.isConnected()) {
+ mImplementation.stop();
+ } else {
+ Log.e(TAG, "TTS Client is not connected");
+ }
+ }
+
+ /**
+ * Speaks the string using the specified queuing strategy using current
+ * voice. This method is asynchronous, i.e. the method just adds the request
+ * to the queue of TTS requests and then returns. The synthesis might not
+ * have finished (or even started!) at the time when this method returns.
+ *
+ * @param utterance The string of text to be spoken. No longer than
+ * 1000 characters.
+ * @param utteranceId Unique identificator used to track the synthesis progress
+ * in {@link RequestCallbacks}.
+ * @param config Synthesis request configuration. Can't be null. Has to contain a
+ * voice.
+ * @param callbacks Synthesis request callbacks. If null, default request
+ * callbacks object will be used.
+ */
+ public void queueSpeak(final String utterance, final UtteranceId utteranceId,
+ final RequestConfig config,
+ final RequestCallbacks callbacks) {
+ if (utterance == null) {
+ throw new IllegalArgumentException("utterance can't be null");
+ }
+ if (utteranceId == null) {
+ throw new IllegalArgumentException("utteranceId can't be null");
+ }
+ if (config == null) {
+ throw new IllegalArgumentException("config can't be null");
+ }
+
+ if (mImplementation.isConnected()) {
+ mImplementation.queueSpeak(utterance, utteranceId, config, callbacks);
+ } else {
+ Log.e(TAG, "TTS Client is not connected");
+ }
+ }
+
+ /**
+ * Synthesizes the given text to a file using the specified parameters. This
+ * method is asynchronous, i.e. the method just adds the request to the
+ * queue of TTS requests and then returns. The synthesis might not have
+ * finished (or even started!) at the time when this method returns.
+ *
+ * @param utterance The text that should be synthesized. No longer than
+ * 1000 characters.
+ * @param utteranceId Unique identificator used to track the synthesis progress
+ * in {@link RequestCallbacks}.
+ * @param outputFile File to write the generated audio data to.
+ * @param config Synthesis request configuration. Can't be null. Have to contain a
+ * voice.
+ * @param callbacks Synthesis request callbacks. If null, default request
+ * callbacks object will be used.
+ */
+ public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
+ final File outputFile, final RequestConfig config,
+ final RequestCallbacks callbacks) {
+ if (utterance == null) {
+ throw new IllegalArgumentException("utterance can't be null");
+ }
+ if (utteranceId == null) {
+ throw new IllegalArgumentException("utteranceId can't be null");
+ }
+ if (outputFile == null) {
+ throw new IllegalArgumentException("outputFile can't be null");
+ }
+ if (config == null) {
+ throw new IllegalArgumentException("config can't be null");
+ }
+
+ if (mImplementation.isConnected()) {
+ mImplementation.queueSynthesizeToFile(utterance, utteranceId, outputFile, config,
+ callbacks);
+ } else {
+ Log.e(TAG, "TTS Client is not connected");
+ }
+ }
+
+ /**
+ * Plays silence for the specified amount of time. This method is asynchronous,
+ * i.e. the method just adds the request to the queue of TTS requests and then
+ * returns. The synthesis might not have finished (or even started!) at the time
+ * when this method returns.
+ *
+ * @param durationInMs The duration of the silence in milliseconds.
+ * @param utteranceId Unique identificator used to track the synthesis progress
+ * in {@link RequestCallbacks}.
+ * @param callbacks Synthesis request callbacks. If null, default request
+ * callbacks object will be used.
+ */
+ public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
+ final RequestCallbacks callbacks) {
+ if (utteranceId == null) {
+ throw new IllegalArgumentException("utteranceId can't be null");
+ }
+
+ if (mImplementation.isConnected()) {
+ mImplementation.queueSilence(durationInMs, utteranceId, callbacks);
+ } else {
+ Log.e(TAG, "TTS Client is not connected");
+ }
+ }
+
+ /**
+ * Plays the audio resource using the specified parameters.
+ * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
+ * requests and then returns. The synthesis might not have finished (or even started!) at the
+ * time when this method returns.
+ *
+ * @param audioUrl The audio resource that should be played
+ * @param utteranceId Unique identificator used to track synthesis progress
+ * in {@link RequestCallbacks}.
+ * @param config Synthesis request configuration. Can't be null. Doesn't have to contain a
+ * voice (only system parameters are used).
+ * @param callbacks Synthesis request callbacks. If null, default request
+ * callbacks object will be used.
+ */
+ public void queueAudio(final Uri audioUrl, final UtteranceId utteranceId,
+ final RequestConfig config, final RequestCallbacks callbacks) {
+ if (audioUrl == null) {
+ throw new IllegalArgumentException("audioUrl can't be null");
+ }
+ if (utteranceId == null) {
+ throw new IllegalArgumentException("utteranceId can't be null");
+ }
+ if (config == null) {
+ throw new IllegalArgumentException("config can't be null");
+ }
+
+ if (mImplementation.isConnected()) {
+ mImplementation.queueAudio(audioUrl, utteranceId, config, callbacks);
+ } else {
+ Log.e(TAG, "TTS Client is not connected");
+ }
+ }
+}
diff --git a/v8/tts/src/android/support/v8/speech/tts/VoiceInfo.java b/v8/tts/src/android/support/v8/speech/tts/VoiceInfo.java
new file mode 100644
index 0000000..a7eed1e
--- /dev/null
+++ b/v8/tts/src/android/support/v8/speech/tts/VoiceInfo.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
+ * multiple voices for multiple locales, with different set of features.
+ *
+ * Each VoiceInfo has an unique name. This name can be obtained using the {@link #getName()} method
+ * and will persist until the client is asked to re-evaluate the list of available voices in the
+ * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+ * callback. The name can be used to reference a VoiceInfo in an instance of {@link RequestConfig};
+ * the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter is an example of this.
+ * It is recommended that the voice name never change during the TTS service lifetime.
+ */
+public class VoiceInfo {
+ /** Very low, but still intelligible quality of speech synthesis */
+ public static final int QUALITY_VERY_LOW = 100;
+
+ /** Low, not human-like quality of speech synthesis */
+ public static final int QUALITY_LOW = 200;
+
+ /** Normal quality of speech synthesis */
+ public static final int QUALITY_NORMAL = 300;
+
+ /** High, human-like quality of speech synthesis */
+ public static final int QUALITY_HIGH = 400;
+
+ /** Very high, almost human-indistinguishable quality of speech synthesis */
+ public static final int QUALITY_VERY_HIGH = 500;
+
+ /** Very low expected synthesizer latency (< 20ms) */
+ public static final int LATENCY_VERY_LOW = 100;
+
+ /** Low expected synthesizer latency (~20ms) */
+ public static final int LATENCY_LOW = 200;
+
+ /** Normal expected synthesizer latency (~50ms) */
+ public static final int LATENCY_NORMAL = 300;
+
+ /** Network based expected synthesizer latency (~200ms) */
+ public static final int LATENCY_HIGH = 400;
+
+ /** Very slow network based expected synthesizer latency (> 200ms) */
+ public static final int LATENCY_VERY_HIGH = 500;
+
+ /** Additional feature key, with string value, gender of the speaker */
+ public static final String FEATURE_SPEAKER_GENDER = "speakerGender";
+
+ /** Additional feature key, with integer value, speaking speed in words per minute
+ * when {@link TextToSpeechClient.Params#SPEECH_SPEED} parameter is set to {@code 1.0} */
+ public static final String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
+
+ /**
+ * Additional feature key, with boolean value, that indicates that voice may need to
+ * download additional data if used for synthesis.
+ *
+ * Making a request with a voice that has this feature may result in a
+ * {@link TextToSpeechClient.Status#ERROR_DOWNLOADING_ADDITIONAL_DATA} error. It's recommended
+ * to set the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter to reference
+ * a fully installed voice (or network voice) that can serve as replacement.
+ *
+ * Note: It's a good practice for a TTS engine to provide a sensible fallback voice as the
+ * default value for {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} parameter if this
+ * feature is present.
+ */
+ public static final String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
+
+ private final String mName;
+ private final Locale mLocale;
+ private final int mQuality;
+ private final int mLatency;
+ private final boolean mRequiresNetworkConnection;
+ private final Bundle mParams;
+ private final Bundle mAdditionalFeatures;
+
+ private final Object mPrivateData;
+
+ VoiceInfo(String name,
+ Locale locale,
+ int quality,
+ int latency,
+ boolean requiresNetworkConnection,
+ Bundle params,
+ Bundle additionalFeatures,
+ Object privateData) {
+ this.mName = name;
+ this.mLocale = locale;
+ this.mQuality = quality;
+ this.mLatency = latency;
+ this.mRequiresNetworkConnection = requiresNetworkConnection;
+ this.mParams = params;
+ this.mAdditionalFeatures = additionalFeatures;
+ this.mPrivateData = privateData;
+ }
+
+ /** Builder, allows TTS engines to create VoiceInfo instances. */
+ static final class Builder {
+ private String name;
+ private Locale locale;
+ private int quality = VoiceInfo.QUALITY_NORMAL;
+ private int latency = VoiceInfo.LATENCY_NORMAL;
+ private boolean requiresNetworkConnection;
+ private Bundle params;
+ private Bundle additionalFeatures;
+ private Object privateData;
+
+ public Builder() {
+
+ }
+
+ /**
+ * Copy fields from given VoiceInfo instance.
+ */
+ public Builder(VoiceInfo voiceInfo) {
+ this.name = voiceInfo.mName;
+ this.locale = voiceInfo.mLocale;
+ this.quality = voiceInfo.mQuality;
+ this.latency = voiceInfo.mLatency;
+ this.requiresNetworkConnection = voiceInfo.mRequiresNetworkConnection;
+ this.params = (Bundle)voiceInfo.mParams.clone();
+ this.additionalFeatures = (Bundle) voiceInfo.mAdditionalFeatures.clone();
+ }
+
+ /**
+ * Sets the voice's unique name. It will be used by clients to reference the voice used by a
+ * request.
+ *
+ * It's recommended that each voice use the same consistent name during the TTS service
+ * lifetime.
+ */
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Sets voice locale. This has to be a valid locale, built from ISO 639-1 and ISO 3166-1
+ * two letter codes.
+ */
+ public Builder setLocale(Locale locale) {
+ this.locale = locale;
+ return this;
+ }
+
+ /**
+ * Sets map of all available request parameters with their default values.
+ * Some common parameter names can be found in {@link TextToSpeechClient.Params} static
+ * members.
+ */
+ public Builder setParamsWithDefaults(Bundle params) {
+ this.params = params;
+ return this;
+ }
+
+ /**
+ * Sets map of additional voice features. Some common feature names can be found in
+ * {@link VoiceInfo} static members.
+ */
+ public Builder setAdditionalFeatures(Bundle additionalFeatures) {
+ this.additionalFeatures = additionalFeatures;
+ return this;
+ }
+
+ /**
+ * Sets the voice quality (higher is better).
+ */
+ public Builder setQuality(int quality) {
+ this.quality = quality;
+ return this;
+ }
+
+ /**
+ * Sets the voice latency (lower is better).
+ */
+ public Builder setLatency(int latency) {
+ this.latency = latency;
+ return this;
+ }
+
+ /**
+ * Sets whether the voice requires network connection to work properly.
+ */
+ public Builder setRequiresNetworkConnection(boolean requiresNetworkConnection) {
+ this.requiresNetworkConnection = requiresNetworkConnection;
+ return this;
+ }
+
+ /**
+ * Sets implementation specific private data
+ */
+ public void setPrivateData(Object privateData) {
+ this.privateData = privateData;
+ }
+
+ /**
+ * @return The built VoiceInfo instance.
+ */
+ public VoiceInfo build() {
+ if (name == null || name.length() == 0) {
+ throw new IllegalStateException("Name can't be null or empty");
+ }
+ if (locale == null) {
+ throw new IllegalStateException("Locale can't be null");
+ }
+
+ return new VoiceInfo(name, locale, quality, latency,
+ requiresNetworkConnection,
+ ((params == null) ? new Bundle() :
+ (Bundle)params.clone()),
+ ((additionalFeatures == null) ? new Bundle() :
+ (Bundle)additionalFeatures.clone()), privateData);
+ }
+ }
+
+ /**
+ * @return The voice's locale
+ */
+ public Locale getLocale() {
+ return mLocale;
+ }
+
+ /**
+ * @return The voice's quality (higher is better)
+ */
+ public int getQuality() {
+ return mQuality;
+ }
+
+ /**
+ * @return The voice's latency (lower is better)
+ */
+ public int getLatency() {
+ return mLatency;
+ }
+
+ /**
+ * @return Does the Voice require a network connection to work.
+ */
+ public boolean getRequiresNetworkConnection() {
+ return mRequiresNetworkConnection;
+ }
+
+ /**
+ * @return Bundle of all available parameters with their default values.
+ */
+ public Bundle getParamsWithDefaults() {
+ return mParams;
+ }
+
+ /**
+ * @return Unique voice name.
+ *
+ * Each VoiceInfo has an unique name, that persists until client is asked to re-evaluate the
+ * set of the available languages in the {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+ * callback (Voice may disappear from the set if voice was removed by the user).
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * @return Additional features of the voice.
+ */
+ public Bundle getAdditionalFeatures() {
+ return mAdditionalFeatures;
+ }
+
+ /**
+ * @return Implementation private data.
+ */
+ Object getPrivateData() {
+ return mPrivateData;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(64);
+ return builder.append("VoiceInfo[Name: ").append(mName)
+ .append(", locale: ").append(mLocale)
+ .append(", quality: ").append(mQuality)
+ .append(", latency: ").append(mLatency)
+ .append(", requiresNetwork: ").append(mRequiresNetworkConnection)
+ .append(", paramsWithDefaults: ").append(mParams.toString())
+ .append(", additionalFeatures: ").append(mAdditionalFeatures.toString())
+ .append("]").toString();
+ }
+}
diff --git a/v8/tts/tests/Android.mk b/v8/tts/tests/Android.mk
new file mode 100644
index 0000000..9101d2f
--- /dev/null
+++ b/v8/tts/tests/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java)
+#LOCAL_SDK_VERSION := cur
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target android-support-v8-tts
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := android-support-v8-tts-tests
+
+include $(BUILD_PACKAGE)
diff --git a/v8/tts/tests/AndroidManifest.xml b/v8/tts/tests/AndroidManifest.xml
new file mode 100644
index 0000000..684db70
--- /dev/null
+++ b/v8/tts/tests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.v8.speech.tts">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="android.support.v8.speech.tts" />
+</manifest>
diff --git a/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV1Test.java b/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV1Test.java
new file mode 100644
index 0000000..840ae14
--- /dev/null
+++ b/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV1Test.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.support.v8.speech.tts.TextToSpeechClient.ConnectionCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.EngineStatus;
+import android.support.v8.speech.tts.TextToSpeechClient.RequestCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.UtteranceId;
+import android.test.InstrumentationTestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+
+/**
+ * Tests for {@link TTSImplementationV1} class.
+ */
+public class TTSImplementationV1Test extends InstrumentationTestCase {
+ @Mock TextToSpeech mOldClientMock;
+ @Mock RequestCallbacks mRequestCallbacks;
+ @Mock ConnectionCallbacks mConnectionCallbacks;
+
+ TTSImplementationV1 mImplementationV1;
+ TextToSpeechClient mClient;
+
+ final String mUtterance = "text";
+ final UtteranceId mUtteranceId = new UtteranceId();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().
+ getCacheDir().getPath());
+ MockitoAnnotations.initMocks(this);
+
+ mImplementationV1 = new TTSImplementationV1(mOldClientMock);
+ mClient = new TextToSpeechClient(mImplementationV1,
+ getInstrumentation().getContext(), "test", false, mRequestCallbacks,
+ mConnectionCallbacks);
+ }
+
+ /** Test basic setup success */
+ public void testSetupSuccess() {
+ mClient.connect();
+ mImplementationV1.mOnInitListener.onInit(TextToSpeech.SUCCESS);
+
+ Mockito.verify(mConnectionCallbacks).onConnectionSuccess();
+ }
+
+ /** Test disconnect */
+ public void testDisconnect() {
+ assertTrue(!mClient.isConnected());
+ mClient.connect();
+ mImplementationV1.mOnInitListener.onInit(TextToSpeech.SUCCESS);
+
+ assertTrue(mClient.isConnected());
+
+ mClient.disconnect();
+ Mockito.verify(mOldClientMock).shutdown();
+
+ assertTrue(!mClient.isConnected());
+ }
+
+ /** Test basic setup failure */
+ public void testSetupFailure() {
+ mClient.connect();
+ mImplementationV1.mOnInitListener.onInit(TextToSpeech.ERROR);
+
+ Mockito.verify(mConnectionCallbacks).onConnectionFailure();
+ }
+
+ /** Mock V1 client to support a set of locales
+ *
+ * - en-US embedded and network
+ * - en-GB network
+ * - en-IN embedded
+ * - en embedded
+ * - de embedded
+ */
+ void mockFewVoices() {
+ // Mock the support for set of locales
+ Mockito.when(mOldClientMock.isLanguageAvailable(Mockito.any(Locale.class))).thenReturn(
+ TextToSpeech.LANG_NOT_SUPPORTED);
+ Mockito.when(mOldClientMock.isLanguageAvailable(Locale.US)).thenReturn(
+ TextToSpeech.LANG_COUNTRY_AVAILABLE);
+ Mockito.when(mOldClientMock.isLanguageAvailable(Locale.UK)).thenReturn(
+ TextToSpeech.LANG_COUNTRY_AVAILABLE);
+ Mockito.when(mOldClientMock.isLanguageAvailable(new Locale("en", "IN"))).thenReturn(
+ TextToSpeech.LANG_COUNTRY_AVAILABLE);
+ Mockito.when(mOldClientMock.isLanguageAvailable(Locale.ENGLISH)).thenReturn(
+ TextToSpeech.LANG_AVAILABLE);
+ Mockito.when(mOldClientMock.isLanguageAvailable(Locale.GERMANY)).thenReturn(
+ TextToSpeech.LANG_AVAILABLE); // "de-DE" not supported, only "de".
+ Mockito.when(mOldClientMock.isLanguageAvailable(Locale.GERMAN)).thenReturn(
+ TextToSpeech.LANG_AVAILABLE);
+
+ HashSet<String> featuresEmbedded = new HashSet<String>();
+ featuresEmbedded.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+ HashSet<String> featuresNetwork = new HashSet<String>();
+ featuresNetwork.add(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+ HashSet<String> featuresBoth = new HashSet<String>();
+ featuresBoth.add(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+ featuresBoth.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+
+ Mockito.when(mOldClientMock.getFeatures(Locale.US)).thenReturn(featuresBoth);
+ Mockito.when(mOldClientMock.getFeatures(Locale.UK)).thenReturn(featuresNetwork);
+ Mockito.when(mOldClientMock.getFeatures(new Locale("en", "IN"))).thenReturn(
+ featuresEmbedded);
+ Mockito.when(mOldClientMock.getFeatures(Locale.ENGLISH)).thenReturn(featuresEmbedded);
+ Mockito.when(mOldClientMock.getFeatures(Locale.GERMAN)).thenReturn(null);
+ Mockito.when(mOldClientMock.getFeatures(Locale.GERMANY)).thenReturn(null);
+ }
+
+ /** Connect V2 client and caputure {@link UtteranceProgressListener} instance */
+ UtteranceProgressListener connectSuccessfuly() {
+ // Capture UtteranceProgressListener
+ final ArgumentCaptor<UtteranceProgressListener> listenerCaptor =
+ ArgumentCaptor.forClass(UtteranceProgressListener.class);
+ Mockito.when(mOldClientMock.setOnUtteranceProgressListener(listenerCaptor.capture()))
+ .thenReturn(TextToSpeech.SUCCESS);
+
+ // Connect and get status
+ mClient.connect();
+ mImplementationV1.mOnInitListener.onInit(TextToSpeech.SUCCESS);
+
+ return listenerCaptor.getValue();
+ }
+
+ /** Test generation of a {@link EngineStatus} */
+ public void testGetEngineData() {
+ mockFewVoices();
+
+ // Connect and get status
+ mClient.connect();
+ mImplementationV1.mOnInitListener.onInit(TextToSpeech.SUCCESS);
+
+ EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+
+ // Create hash-map with expected voices
+ final HashMap<Locale, ArrayList<String>> expectedVoices =
+ new HashMap<Locale, ArrayList<String>>();
+
+ ArrayList<String> l = new ArrayList<String>();
+ l.add(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+ l.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+ expectedVoices.put(Locale.US, l);
+
+ l = new ArrayList<String>();
+ l.add(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
+ expectedVoices.put(Locale.UK, l);
+
+ l = new ArrayList<String>();
+ l.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+ expectedVoices.put(new Locale("en", "IN"), l);
+
+ l = new ArrayList<String>();
+ l.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+ expectedVoices.put(Locale.ENGLISH, l);
+
+ l = new ArrayList<String>();
+ l.add(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
+ expectedVoices.put(Locale.GERMAN, l);
+
+ assertEquals(6, engineStatus.getVoices().size());
+ for (VoiceInfo info : engineStatus.getVoices()) {
+ ArrayList<String> features = expectedVoices.get(info.getLocale());
+ assertNotNull(features);
+ if (info.getRequiresNetworkConnection()) {
+ assertTrue(features.remove(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS));
+ } else {
+ assertTrue(info.getName(),
+ features.remove(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS));
+ }
+ if (features.isEmpty()) {
+ assertTrue(expectedVoices.remove(info.getLocale()) != null);
+ }
+ }
+
+ // Make sure all expected voices were found
+ assertTrue(expectedVoices.isEmpty());
+ }
+
+ /** Test successful {@link TextToSpeechClient#queueSpeak} call */
+ public void testQueueSpeakSuccess() {
+ mockFewVoices();
+ UtteranceProgressListener listener = connectSuccessfuly();
+ assertNotNull(listener);
+
+ // Mock the speak call
+ Mockito.when(mOldClientMock.speak(Mockito.anyString(), Mockito.anyInt(),
+ (HashMap<String, String>) Mockito.any()))
+ .thenReturn(TextToSpeech.SUCCESS);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rc = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Call speak
+ mClient.queueSpeak(mUtterance, mUtteranceId, rc, null);
+
+ // Call back to the listener
+ listener.onStart(mUtteranceId.toUniqueString());
+ listener.onDone(mUtteranceId.toUniqueString());
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).setLanguage(Locale.US);
+ Mockito.verify(mOldClientMock).setPitch(1.0f);
+ // We never set speed, so make sure we use value from settings
+ Mockito.verify(mOldClientMock).setSpeechRate(mImplementationV1.getDefaultSpeechRate());
+
+ ArgumentCaptor<HashMap> paramsCaptor =
+ ArgumentCaptor.forClass(HashMap.class);
+ Mockito.verify(mOldClientMock).speak(Mockito.eq(mUtterance),
+ Mockito.eq(TextToSpeech.QUEUE_ADD), paramsCaptor.capture());
+
+ HashMap<String, String> params = paramsCaptor.getValue();
+ assertEquals(mUtteranceId.toUniqueString(), params.get(
+ TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID));
+ assertEquals("true", params.get(
+ TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS));
+
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisStart(mUtteranceId);
+ Mockito.verify(mRequestCallbacks).onSynthesisSuccess(mUtteranceId);
+ }
+
+ /** Test successful {@link TextToSpeechClient#queueSpeak} call, with synthesis failure */
+ public void testQueueSpeakSynthesisFailure() {
+ mockFewVoices();
+ UtteranceProgressListener listener = connectSuccessfuly();
+ assertNotNull(listener);
+
+ // Mock the speak call
+ Mockito.when(mOldClientMock.speak(Mockito.anyString(), Mockito.anyInt(),
+ (HashMap<String, String>) Mockito.any()))
+ .thenReturn(TextToSpeech.SUCCESS);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rcBase = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Set speed and pitch to 0.1f
+ final RequestConfig rc = RequestConfig.Builder.newBuilder(rcBase)
+ .setVoiceParam(TextToSpeechClient.Params.SPEECH_SPEED, 0.1f)
+ .setVoiceParam(TextToSpeechClient.Params.SPEECH_PITCH, 0.1f)
+ .build();
+
+ // Call speak
+ mClient.queueSpeak(mUtterance, mUtteranceId, rc, null);
+
+ // Call back to the listener
+ listener.onStart(mUtteranceId.toUniqueString());
+ listener.onError(mUtteranceId.toUniqueString());
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).setLanguage(Locale.US);
+ Mockito.verify(mOldClientMock).setPitch(0.1f);
+ Mockito.verify(mOldClientMock).setSpeechRate(0.1f);
+ Mockito.verify(mOldClientMock).speak(Mockito.eq(mUtterance),
+ Mockito.eq(TextToSpeech.QUEUE_ADD),
+ (HashMap<String, String>) Mockito.any());
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisStart(mUtteranceId);
+ Mockito.verify(mRequestCallbacks).onSynthesisFailure(mUtteranceId,
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+
+ /** Test failing {@link TextToSpeechClient#queueSpeak} call */
+ public void testQueueSpeakFailure() {
+ mockFewVoices();
+ connectSuccessfuly();
+
+ // Mock the speak call with error
+ Mockito.when(mOldClientMock.speak(Mockito.anyString(), Mockito.anyInt(),
+ (HashMap<String, String>) Mockito.any()))
+ .thenReturn(TextToSpeech.ERROR);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rc = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Call speak
+ mClient.queueSpeak(mUtterance, mUtteranceId, rc, null);
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).speak(Mockito.eq(mUtterance),
+ Mockito.eq(TextToSpeech.QUEUE_ADD),
+ (HashMap<String, String>) Mockito.any());
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisFailure(mUtteranceId,
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+
+ /** Test successful {@link TextToSpeechClient#queueSynthesizeToFile} call */
+ public void testQueueSynthesizeToFileSucces() {
+ mockFewVoices();
+ UtteranceProgressListener listener = connectSuccessfuly();
+ assertNotNull(listener);
+
+ // Mock the speak call
+ Mockito.when(mOldClientMock.synthesizeToFile(Mockito.anyString(),
+ (HashMap<String, String>) Mockito.any(), Mockito.anyString()))
+ .thenReturn(TextToSpeech.SUCCESS);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rc = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Call speak
+ File output = new File("test");
+ mClient.queueSynthesizeToFile(mUtterance, mUtteranceId, output, rc, null);
+
+ // Call back to the listener
+ listener.onStart(mUtteranceId.toUniqueString());
+ listener.onDone(mUtteranceId.toUniqueString());
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).setLanguage(Locale.US);
+ Mockito.verify(mOldClientMock).setPitch(1.0f);
+ // We never set speed, so make sure we use value from settings
+ Mockito.verify(mOldClientMock).setSpeechRate(mImplementationV1.getDefaultSpeechRate());
+
+ ArgumentCaptor<HashMap> paramsCaptor =
+ ArgumentCaptor.forClass(HashMap.class);
+ Mockito.verify(mOldClientMock).synthesizeToFile(Mockito.eq(mUtterance),
+ paramsCaptor.capture(), Mockito.eq(output.getAbsolutePath()));
+
+ HashMap<String, String> params = paramsCaptor.getValue();
+ assertEquals(mUtteranceId.toUniqueString(), params.get(
+ TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID));
+ assertEquals("true", params.get(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS));
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisStart(mUtteranceId);
+ Mockito.verify(mRequestCallbacks).onSynthesisSuccess(mUtteranceId);
+ }
+
+ /** Test successful {@link TextToSpeechClient#queueSynthesizeToFile} call, with synthesis
+ * failure */
+ public void testQueueSynthesizeToFileSynthesisFailure() {
+ mockFewVoices();
+ UtteranceProgressListener listener = connectSuccessfuly();
+ assertNotNull(listener);
+
+ // Mock the speak call
+ Mockito.when(mOldClientMock.synthesizeToFile(Mockito.anyString(),
+ (HashMap<String, String>) Mockito.any(), Mockito.anyString()))
+ .thenReturn(TextToSpeech.SUCCESS);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rcBase = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Set speed and pitch to 0.1f
+ final RequestConfig rc = RequestConfig.Builder.newBuilder(rcBase)
+ .setVoiceParam(TextToSpeechClient.Params.SPEECH_SPEED, 0.1f)
+ .setVoiceParam(TextToSpeechClient.Params.SPEECH_PITCH, 0.1f)
+ .build();
+
+ // Call synthesizeToFile
+ File output = new File("test");
+ mClient.queueSynthesizeToFile(mUtterance, mUtteranceId, output, rc, null);
+
+ // Call back to the listener
+ listener.onStart(mUtteranceId.toUniqueString());
+ listener.onError(mUtteranceId.toUniqueString());
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).setLanguage(Locale.US);
+ Mockito.verify(mOldClientMock).setPitch(0.1f);
+ Mockito.verify(mOldClientMock).setSpeechRate(0.1f);
+ Mockito.verify(mOldClientMock).synthesizeToFile(Mockito.eq(mUtterance),
+ (HashMap<String, String>) Mockito.any(), Mockito.eq(output.getAbsolutePath()));
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisStart(mUtteranceId);
+ Mockito.verify(mRequestCallbacks).onSynthesisFailure(mUtteranceId,
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+
+ /** Test failing {@link TextToSpeechClient#queueSynthesizeToFile} call */
+ public void testQueueSynthesizeToFileFailure() {
+ mockFewVoices();
+ connectSuccessfuly();
+
+ // Mock the synthesizeToFile call with error
+ Mockito.when(mOldClientMock.synthesizeToFile(Mockito.anyString(),
+ (HashMap<String, String>) Mockito.any(), Mockito.anyString()))
+ .thenReturn(TextToSpeech.ERROR);
+
+ final EngineStatus engineStatus = mClient.getEngineStatus();
+ assertNotNull(engineStatus);
+ final RequestConfig rc = RequestConfigHelper.highestQuality(engineStatus, true,
+ new RequestConfigHelper.ExactLocaleMatcher(Locale.US));
+
+ // Call speak
+ File output = new File("test");
+ mClient.queueSynthesizeToFile(mUtterance, mUtteranceId, output, rc, null);
+
+ // Verify V1 client calls
+ Mockito.verify(mOldClientMock).synthesizeToFile(Mockito.eq(mUtterance),
+ (HashMap<String, String>) Mockito.any(), Mockito.eq(output.getAbsolutePath()));
+
+ // Verify callback calls
+ Mockito.verify(mRequestCallbacks).onSynthesisFailure(mUtteranceId,
+ TextToSpeechClient.Status.ERROR_UNKNOWN);
+ }
+
+}
+
diff --git a/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV2Test.java b/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV2Test.java
new file mode 100644
index 0000000..bcb2555
--- /dev/null
+++ b/v8/tts/tests/java/android/support/v8/speech/tts/TTSImplementationV2Test.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.support.v8.speech.tts;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.speech.tts.TextToSpeech;
+import android.support.v8.speech.tts.TextToSpeechClient.ConnectionCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.RequestCallbacks;
+import android.support.v8.speech.tts.TextToSpeechClient.UtteranceId;
+import android.test.InstrumentationTestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * Tests for {@link TTSImplementationV2} class.
+ */
+public class TTSImplementationV2Test extends InstrumentationTestCase {
+ @Mock android.speech.tts.TextToSpeechClient mRealClientMock;
+ @Mock RequestCallbacks mRequestCallbacksMock;
+ @Mock ConnectionCallbacks mConnectionCallbacksMock;
+
+ @Mock TTSImplementationV2.TextToSpeechClientConstructor mClientConstructorMock;
+ TTSImplementationV2 mImplementationV2;
+ TextToSpeechClient mClient;
+
+ final String mUtterance = "text";
+ final UtteranceId mUtteranceId = new UtteranceId();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext().
+ getCacheDir().getPath());
+ MockitoAnnotations.initMocks(this);
+
+ Mockito.when(mClientConstructorMock.newClient(
+ (Context) Mockito.any(),
+ Mockito.anyString(), Mockito.anyBoolean(),
+ (android.speech.tts.TextToSpeechClient.RequestCallbacks)Mockito.any(),
+ (android.speech.tts.TextToSpeechClient.ConnectionCallbacks)Mockito.any()))
+ .thenReturn(mRealClientMock);
+
+ mImplementationV2 = new TTSImplementationV2(mClientConstructorMock);
+ mClient = new TextToSpeechClient(mImplementationV2,
+ getInstrumentation().getContext(), "test", false, mRequestCallbacksMock,
+ mConnectionCallbacksMock);
+ }
+
+ private class Callbacks {
+ android.speech.tts.TextToSpeechClient.RequestCallbacks requestCallback;
+ android.speech.tts.TextToSpeechClient.ConnectionCallbacks connectionCallbacks;
+ }
+
+ public Callbacks connect() {
+ ArgumentCaptor<android.speech.tts.TextToSpeechClient.RequestCallbacks>
+ requestCallbackCaptor =
+ ArgumentCaptor.forClass(
+ android.speech.tts.TextToSpeechClient.RequestCallbacks.class);
+
+ ArgumentCaptor<android.speech.tts.TextToSpeechClient.ConnectionCallbacks>
+ connectionCallbackCaptor =
+ ArgumentCaptor.forClass(
+ android.speech.tts.TextToSpeechClient.ConnectionCallbacks.class);
+
+ Mockito.verify(mClientConstructorMock).newClient(
+ Mockito.eq(getInstrumentation().getContext()),
+ Mockito.eq("test"), Mockito.eq(false),
+ requestCallbackCaptor.capture(),
+ connectionCallbackCaptor.capture());
+
+ mClient.connect();
+
+ Callbacks callbacks = new Callbacks();
+ callbacks.requestCallback = requestCallbackCaptor.getValue();
+ callbacks.connectionCallbacks = connectionCallbackCaptor.getValue();
+ assertNotNull(callbacks.requestCallback);
+ assertNotNull(callbacks.connectionCallbacks);
+ return callbacks;
+ }
+
+ public void testSetupSuccess() {
+ Callbacks callbacks = connect();
+ callbacks.connectionCallbacks.onConnectionSuccess();
+ Mockito.verify(mConnectionCallbacksMock).onConnectionSuccess();
+ }
+
+ public void testSetupFailure() {
+ Callbacks callbacks = connect();
+ callbacks.connectionCallbacks.onConnectionFailure();
+ Mockito.verify(mConnectionCallbacksMock).onConnectionFailure();
+ }
+
+ private static void assertEquals(Bundle expeced, Bundle value) {
+ if (expeced.size() != value.size()) {
+ fail("Received bundle has different number of mappings: " + value.size() +
+ ", expected: " + expeced.size());
+ }
+ for (String key : value.keySet()) {
+ if (!expeced.containsKey(key)) {
+ fail("received bundle is missing key: " + key);
+ }
+ Object e = expeced.get(key);
+ Object v = value.get(key);
+ if (!e.equals(v)) {
+ fail("received bundle has wrong value for key " + key + " value: " + v +
+ ", expected: " + e);
+ }
+ }
+ }
+
+ public android.speech.tts.VoiceInfo createFrameworkVoiceInfo() {
+ Bundle params = new Bundle();
+ params.putInt("foo1", 1);
+ params.putInt("foo2", 1);
+ Bundle features = new Bundle();
+ features.putInt("bar", 2);
+ return (new android.speech.tts.VoiceInfo.Builder())
+ .setName("name")
+ .setQuality(123)
+ .setQuality(321)
+ .setRequiresNetworkConnection(false)
+ .setLocale(Locale.GERMANY)
+ .setParamsWithDefaults(params).setAdditionalFeatures(features).build();
+ }
+
+ public void testVoiceInfoConvert() {
+ android.speech.tts.VoiceInfo frameworkVoiceInfo = createFrameworkVoiceInfo();
+
+ VoiceInfo supportVoiceInfo =
+ TTSImplementationV2.convert(frameworkVoiceInfo);
+
+ assertEquals(frameworkVoiceInfo.getName(), supportVoiceInfo.getName());
+ assertEquals(frameworkVoiceInfo.getLatency(), supportVoiceInfo.getLatency());
+ assertEquals(frameworkVoiceInfo.getQuality(), supportVoiceInfo.getQuality());
+ assertEquals(frameworkVoiceInfo.getLocale(), supportVoiceInfo.getLocale());
+ assertEquals(frameworkVoiceInfo.getRequiresNetworkConnection(),
+ supportVoiceInfo.getRequiresNetworkConnection());
+ assertEquals(frameworkVoiceInfo.getAdditionalFeatures(),
+ supportVoiceInfo.getAdditionalFeatures());
+ assertEquals(frameworkVoiceInfo.getParamsWithDefaults(),
+ supportVoiceInfo.getParamsWithDefaults());
+
+ android.speech.tts.VoiceInfo frameworkVoiceInfo2 =
+ TTSImplementationV2.convert(supportVoiceInfo);
+
+ assertEquals(frameworkVoiceInfo, frameworkVoiceInfo2);
+ }
+
+ public void testRequestInfoConvert() {
+ android.speech.tts.VoiceInfo frameworkVoiceInfo = createFrameworkVoiceInfo();
+ VoiceInfo supportVoiceInfo = TTSImplementationV2.convert(frameworkVoiceInfo);
+
+ RequestConfig.Builder builder = RequestConfig.Builder.newBuilder();
+ builder.setVoice(supportVoiceInfo);
+ builder.setAudioParamVolume(0.5f);
+ builder.setVoiceParam("foo1", 5);
+ RequestConfig supportRequestConfig = builder.build();
+
+ android.speech.tts.RequestConfig frameworkRequestConfig =
+ TTSImplementationV2.convert(supportRequestConfig);
+
+ assertEquals(frameworkRequestConfig.getVoice(), frameworkVoiceInfo);
+ assertEquals(frameworkRequestConfig.getAudioParams(),
+ supportRequestConfig.getAudioParams());
+ assertEquals(frameworkRequestConfig.getVoiceParams(),
+ supportRequestConfig.getVoiceParams());
+ }
+
+ public void testRequestCallbacksConvert() {
+ android.speech.tts.TextToSpeechClient.RequestCallbacks frameworkRequestCallbacks =
+ TTSImplementationV2.convert(mRequestCallbacksMock);
+
+ frameworkRequestCallbacks.onSynthesisFailure(TTSImplementationV2.convert(mUtteranceId), 29);
+ Mockito.verify(mRequestCallbacksMock).onSynthesisFailure(mUtteranceId, 29);
+
+ frameworkRequestCallbacks.onSynthesisSuccess(TTSImplementationV2.convert(mUtteranceId));
+ Mockito.verify(mRequestCallbacksMock).onSynthesisSuccess(mUtteranceId);
+
+ frameworkRequestCallbacks.onSynthesisStop(TTSImplementationV2.convert(mUtteranceId));
+ Mockito.verify(mRequestCallbacksMock).onSynthesisStop(mUtteranceId);
+
+ frameworkRequestCallbacks.onSynthesisStart(TTSImplementationV2.convert(mUtteranceId));
+ Mockito.verify(mRequestCallbacksMock).onSynthesisStart(mUtteranceId);
+
+ frameworkRequestCallbacks.onSynthesisFallback(TTSImplementationV2.convert(mUtteranceId));
+ Mockito.verify(mRequestCallbacksMock).onSynthesisFallback(mUtteranceId);
+
+ frameworkRequestCallbacks.onSynthesisProgress(TTSImplementationV2.convert(mUtteranceId),
+ 1, 2);
+ Mockito.verify(mRequestCallbacksMock).onSynthesisProgress(mUtteranceId, 1, 2);
+ }
+}