Merge "Remove Disco video from builds." into jb-dev
diff --git a/api/16.txt b/api/16.txt
index c95de36..eb09d85 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -23186,6 +23186,7 @@
field public static final int KEYCODE_ALT_RIGHT = 58; // 0x3a
field public static final int KEYCODE_APOSTROPHE = 75; // 0x4b
field public static final int KEYCODE_APP_SWITCH = 187; // 0xbb
+ field public static final int KEYCODE_ASSIST = 219; // 0xdb
field public static final int KEYCODE_AT = 77; // 0x4d
field public static final int KEYCODE_AVR_INPUT = 182; // 0xb6
field public static final int KEYCODE_AVR_POWER = 181; // 0xb5
diff --git a/api/current.txt b/api/current.txt
index f5bc504..a62698e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23197,6 +23197,7 @@
field public static final int KEYCODE_ALT_RIGHT = 58; // 0x3a
field public static final int KEYCODE_APOSTROPHE = 75; // 0x4b
field public static final int KEYCODE_APP_SWITCH = 187; // 0xbb
+ field public static final int KEYCODE_ASSIST = 219; // 0xdb
field public static final int KEYCODE_AT = 77; // 0x4d
field public static final int KEYCODE_AVR_INPUT = 182; // 0xb6
field public static final int KEYCODE_AVR_POWER = 181; // 0xb5
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ec35a3f..bb497c0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1670,6 +1670,9 @@
contentView.setTextViewText(R.id.text, overflowText);
contentView.setViewVisibility(R.id.overflow_divider, View.VISIBLE);
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
+ } else {
+ contentView.setViewVisibility(R.id.overflow_divider, View.GONE);
+ contentView.setViewVisibility(R.id.line3, View.GONE);
}
return contentView;
@@ -1812,6 +1815,7 @@
// Remove the content text so line3 only shows if you have a summary
final boolean hadThreeLines = (mBuilder.mContentText != null && mBuilder.mSubText != null);
mBuilder.mContentText = null;
+
RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
if (hadThreeLines) {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 691ee30..e8bd546 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Rect;
@@ -32,6 +33,7 @@
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
import android.view.KeyEvent;
import java.util.List;
@@ -837,4 +839,32 @@
}
}
+ /**
+ * Returns true if the global assist activity is available.
+ * @return True if the assistant is available.
+ *
+ * @hide
+ */
+ public final boolean isAssistantAvailable() {
+ Intent intent = getAssistIntent();
+ return intent != null
+ && mContext.getPackageManager().queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
+ }
+
+ /**
+ * Gets an intent to launch the global assist activity, or null if not available.
+ * @return The assist intent.
+ *
+ * @hide
+ */
+ public final Intent getAssistIntent() {
+ ComponentName globalSearchActivity = getGlobalSearchActivity();
+ if (globalSearchActivity != null) {
+ Intent intent = new Intent(Intent.ACTION_ASSIST);
+ intent.setPackage(globalSearchActivity.getPackageName());
+ return intent;
+ }
+ return null;
+ }
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 12f16fd..d2bed48 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1696,8 +1696,14 @@
return text.getSpans(start, end, type);
}
+ private char getEllipsisChar(TextUtils.TruncateAt method) {
+ return (method == TextUtils.TruncateAt.END_SMALL) ?
+ ELLIPSIS_TWO_DOTS[0] :
+ ELLIPSIS_NORMAL[0];
+ }
+
private void ellipsize(int start, int end, int line,
- char[] dest, int destoff) {
+ char[] dest, int destoff, TextUtils.TruncateAt method) {
int ellipsisCount = getEllipsisCount(line);
if (ellipsisCount == 0) {
@@ -1711,7 +1717,7 @@
char c;
if (i == ellipsisStart) {
- c = '\u2026'; // ellipsis
+ c = getEllipsisChar(method); // ellipsis
} else {
c = '\uFEFF'; // 0-width space
}
@@ -1785,7 +1791,7 @@
TextUtils.getChars(mText, start, end, dest, destoff);
for (int i = line1; i <= line2; i++) {
- mLayout.ellipsize(start, end, i, dest, destoff);
+ mLayout.ellipsize(start, end, i, dest, destoff, mMethod);
}
}
@@ -1890,4 +1896,6 @@
/* package */ static final Directions DIRS_ALL_RIGHT_TO_LEFT =
new Directions(new int[] { 0, RUN_LENGTH_MASK | RUN_RTL_FLAG });
+ /* package */ static final char[] ELLIPSIS_NORMAL = { '\u2026' }; // this is "..."
+ /* package */ static final char[] ELLIPSIS_TWO_DOTS = { '\u2025' }; // this is ".."
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 299e115..6973b2e 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -745,7 +745,8 @@
}
float ellipsisWidth = paint.measureText(
- (where == TextUtils.TruncateAt.END_SMALL) ? ELLIPSIS_TWO_DOTS : ELLIPSIS_NORMAL);
+ (where == TextUtils.TruncateAt.END_SMALL) ?
+ ELLIPSIS_TWO_DOTS : ELLIPSIS_NORMAL, 0, 1);
int ellipsisStart = 0;
int ellipsisCount = 0;
int len = lineEnd - lineStart;
@@ -985,9 +986,6 @@
private static final double EXTRA_ROUNDING = 0.5;
- private static final String ELLIPSIS_NORMAL = "\u2026"; // this is "..."
- private static final String ELLIPSIS_TWO_DOTS = "\u2025"; // this is ".."
-
private static final int CHAR_FIRST_HIGH_SURROGATE = 0xD800;
private static final int CHAR_LAST_LOW_SURROGATE = 0xDFFF;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 1080229..c2a3e58 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -620,8 +620,11 @@
public static final int KEYCODE_RO = 217;
/** Key code constant: Japanese kana key. */
public static final int KEYCODE_KANA = 218;
+ /** Key code constant: Assist key.
+ * Launches the global assist activity. Not delivered to applications. */
+ public static final int KEYCODE_ASSIST = 219;
- private static final int LAST_KEYCODE = KEYCODE_KANA;
+ private static final int LAST_KEYCODE = KEYCODE_ASSIST;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
@@ -862,6 +865,7 @@
names.append(KEYCODE_YEN, "KEYCODE_YEN");
names.append(KEYCODE_RO, "KEYCODE_RO");
names.append(KEYCODE_KANA, "KEYCODE_KANA");
+ names.append(KEYCODE_ASSIST, "KEYCODE_ASSIST");
};
// Symbolic names of all metakeys in bit order from least significant to most significant.
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index 000eee7..bfcfdfa 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -19,10 +19,12 @@
import com.android.internal.R;
import android.app.Activity;
+import android.app.Dialog;
import android.app.DialogFragment;
import android.app.MediaRouteActionProvider;
import android.app.MediaRouteButton;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteCategory;
import android.media.MediaRouter.RouteGroup;
@@ -34,10 +36,14 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
/**
* This class implements the route chooser dialog for {@link MediaRouter}.
@@ -49,14 +55,30 @@
private static final String TAG = "MediaRouteChooserDialogFragment";
public static final String FRAGMENT_TAG = "android:MediaRouteChooserDialogFragment";
+ private static final int[] ITEM_LAYOUTS = new int[] {
+ R.layout.media_route_list_item_top_header,
+ R.layout.media_route_list_item_section_header,
+ R.layout.media_route_list_item
+ };
+
+ private static final int[] GROUP_ITEM_LAYOUTS = new int[] {
+ R.layout.media_route_list_item_top_header,
+ R.layout.media_route_list_item_checkable,
+ R.layout.media_route_list_item_collapse_group
+ };
+
MediaRouter mRouter;
private int mRouteTypes;
+ private LayoutInflater mInflater;
private LauncherListener mLauncherListener;
private View.OnClickListener mExtendedSettingsListener;
private RouteAdapter mAdapter;
+ private GroupAdapter mGroupAdapter;
private ListView mListView;
+ static final RouteComparator sComparator = new RouteComparator();
+
public MediaRouteChooserDialogFragment() {
setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog);
}
@@ -77,10 +99,15 @@
if (mLauncherListener != null) {
mLauncherListener.onDetached(this);
}
+ if (mGroupAdapter != null) {
+ mRouter.removeCallback(mGroupAdapter);
+ mGroupAdapter = null;
+ }
if (mAdapter != null) {
mRouter.removeCallback(mAdapter);
mAdapter = null;
}
+ mInflater = null;
mRouter = null;
}
@@ -102,6 +129,7 @@
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ mInflater = inflater;
final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false);
final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
@@ -112,7 +140,8 @@
final ListView list = (ListView) layout.findViewById(R.id.list);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- list.setAdapter(mAdapter = new RouteAdapter(inflater));
+ list.setItemsCanFocus(true);
+ list.setAdapter(mAdapter = new RouteAdapter());
list.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
list.setOnItemClickListener(mAdapter);
@@ -122,11 +151,59 @@
return layout;
}
- private static final int[] ITEM_LAYOUTS = new int[] {
- R.layout.media_route_list_item_top_header,
- R.layout.media_route_list_item_section_header,
- R.layout.media_route_list_item
- };
+ void onExpandGroup(RouteGroup info) {
+ mGroupAdapter = new GroupAdapter(info);
+ mRouter.addCallback(mRouteTypes, mGroupAdapter);
+ mListView.setAdapter(mGroupAdapter);
+ mListView.setOnItemClickListener(mGroupAdapter);
+ mListView.setItemsCanFocus(false);
+ mListView.clearChoices();
+ mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+ mGroupAdapter.initCheckedItems();
+
+ getDialog().setCanceledOnTouchOutside(false);
+ }
+
+ void onDoneGrouping() {
+ mListView.setAdapter(mAdapter);
+ mListView.setOnItemClickListener(mAdapter);
+ mListView.setItemsCanFocus(true);
+ mListView.clearChoices();
+ mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ mListView.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
+
+ mRouter.removeCallback(mGroupAdapter);
+ mGroupAdapter = null;
+
+ getDialog().setCanceledOnTouchOutside(true);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new RouteChooserDialog(getActivity(), getTheme());
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (mListView != null) {
+ if (mGroupAdapter != null) {
+ mGroupAdapter.initCheckedItems();
+ } else {
+ mListView.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
+ }
+ }
+ }
+
+ private static class ViewHolder {
+ public TextView text1;
+ public TextView text2;
+ public ImageView icon;
+ public ImageButton expandGroupButton;
+ public RouteAdapter.ExpandGroupListener expandGroupListener;
+ public int position;
+ }
private class RouteAdapter extends BaseAdapter implements MediaRouter.Callback,
ListView.OnItemClickListener {
@@ -136,10 +213,8 @@
private int mSelectedItemPosition;
private final ArrayList<Object> mItems = new ArrayList<Object>();
- private final LayoutInflater mInflater;
- RouteAdapter(LayoutInflater inflater) {
- mInflater = inflater;
+ RouteAdapter() {
update();
}
@@ -222,11 +297,29 @@
if (convertView == null) {
convertView = mInflater.inflate(ITEM_LAYOUTS[viewType], parent, false);
holder = new ViewHolder();
+ holder.position = position;
holder.text1 = (TextView) convertView.findViewById(R.id.text1);
holder.text2 = (TextView) convertView.findViewById(R.id.text2);
+ holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+ holder.expandGroupButton = (ImageButton) convertView.findViewById(
+ R.id.expand_button);
+ if (holder.expandGroupButton != null) {
+ holder.expandGroupListener = new ExpandGroupListener();
+ holder.expandGroupButton.setOnClickListener(holder.expandGroupListener);
+ }
+
+ final View fview = convertView;
+ final ListView list = (ListView) parent;
+ final ViewHolder fholder = holder;
+ convertView.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ list.performItemClick(fview, fholder.position, 0);
+ }
+ });
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
+ holder.position = position;
}
if (viewType == VIEW_ROUTE) {
@@ -248,6 +341,24 @@
holder.text2.setVisibility(View.VISIBLE);
holder.text2.setText(status);
}
+ Drawable icon = info.getIconDrawable();
+ if (icon != null) {
+ // Make sure we have a fresh drawable where it doesn't matter if we mutate it
+ icon = icon.getConstantState().newDrawable(getResources());
+ }
+ holder.icon.setImageDrawable(icon);
+ holder.icon.setVisibility(icon != null ? View.VISIBLE : View.GONE);
+
+ RouteCategory cat = info.getCategory();
+ boolean canGroup = false;
+ if (cat.isGroupable()) {
+ final RouteGroup group = (RouteGroup) info;
+ canGroup = group.getRouteCount() > 1 ||
+ getItemViewType(position - 1) == VIEW_ROUTE ||
+ (position < getCount() - 1 && getItemViewType(position + 1) == VIEW_ROUTE);
+ }
+ holder.expandGroupButton.setVisibility(canGroup ? View.VISIBLE : View.GONE);
+ holder.expandGroupListener.position = position;
}
void bindHeaderView(int position, ViewHolder holder) {
@@ -306,36 +417,274 @@
mRouter.selectRoute(mRouteTypes, (RouteInfo) item);
dismiss();
}
+
+ class ExpandGroupListener implements View.OnClickListener {
+ int position;
+
+ @Override
+ public void onClick(View v) {
+ // Assumption: this is only available for the user to click if we're presenting
+ // a groupable category, where every top-level route in the category is a group.
+ onExpandGroup((RouteGroup) getItem(position));
+ }
+ }
}
- private static class ViewHolder {
- public TextView text1;
- public TextView text2;
- }
+ private class GroupAdapter extends BaseAdapter implements MediaRouter.Callback,
+ ListView.OnItemClickListener {
+ private static final int VIEW_HEADER = 0;
+ private static final int VIEW_ROUTE = 1;
+ private static final int VIEW_DONE = 2;
- private class GroupAdapter extends BaseAdapter {
+ private RouteGroup mPrimary;
+ private RouteCategory mCategory;
+ private final ArrayList<RouteInfo> mTempList = new ArrayList<RouteInfo>();
+ private final ArrayList<RouteInfo> mFlatRoutes = new ArrayList<RouteInfo>();
+ private boolean mIgnoreUpdates;
+
+ public GroupAdapter(RouteGroup primary) {
+ mPrimary = primary;
+ mCategory = primary.getCategory();
+ update();
+ }
+
@Override
public int getCount() {
- // TODO Auto-generated method stub
- return 0;
+ return mFlatRoutes.size() + 2;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 3;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position == 0) {
+ return VIEW_HEADER;
+ } else if (position == getCount() - 1) {
+ return VIEW_DONE;
+ }
+ return VIEW_ROUTE;
+ }
+
+ void update() {
+ if (mIgnoreUpdates) return;
+ mFlatRoutes.clear();
+ mCategory.getRoutes(mTempList);
+
+ // Unpack groups and flatten for presentation
+ final int topCount = mTempList.size();
+ for (int i = 0; i < topCount; i++) {
+ final RouteInfo route = mTempList.get(i);
+ final RouteGroup group = route.getGroup();
+ if (group == route) {
+ // This is a group, unpack it.
+ final int groupCount = group.getRouteCount();
+ for (int j = 0; j < groupCount; j++) {
+ final RouteInfo innerRoute = group.getRouteAt(j);
+ mFlatRoutes.add(innerRoute);
+ }
+ } else {
+ mFlatRoutes.add(route);
+ }
+ }
+ mTempList.clear();
+
+ // Sort by name. This will keep the route positions relatively stable even though they
+ // will be repeatedly added and removed.
+ Collections.sort(mFlatRoutes, sComparator);
+ notifyDataSetChanged();
+ }
+
+ void initCheckedItems() {
+ if (mIgnoreUpdates) return;
+ mListView.clearChoices();
+ int count = mFlatRoutes.size();
+ for (int i = 0; i < count; i++){
+ final RouteInfo route = mFlatRoutes.get(i);
+ if (route.getGroup() == mPrimary) {
+ mListView.setItemChecked(i + 1, true);
+ }
+ }
}
@Override
public Object getItem(int position) {
- // TODO Auto-generated method stub
- return null;
+ if (position == 0) {
+ return mCategory;
+ } else if (position == getCount() - 1) {
+ return null; // Done
+ }
+ return mFlatRoutes.get(position - 1);
}
@Override
public long getItemId(int position) {
- // TODO Auto-generated method stub
- return 0;
+ return position;
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position > 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- return null;
+ final int viewType = getItemViewType(position);
+
+ ViewHolder holder;
+ if (convertView == null) {
+ convertView = mInflater.inflate(GROUP_ITEM_LAYOUTS[viewType], parent, false);
+ holder = new ViewHolder();
+ holder.position = position;
+ holder.text1 = (TextView) convertView.findViewById(R.id.text1);
+ holder.text2 = (TextView) convertView.findViewById(R.id.text2);
+ holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ holder.position = position;
+ }
+
+ if (viewType == VIEW_ROUTE) {
+ bindItemView(position, holder);
+ } else if (viewType == VIEW_HEADER) {
+ bindHeaderView(position, holder);
+ }
+
+ return convertView;
+ }
+
+ void bindItemView(int position, ViewHolder holder) {
+ RouteInfo info = (RouteInfo) getItem(position);
+ holder.text1.setText(info.getName());
+ final CharSequence status = info.getStatus();
+ if (TextUtils.isEmpty(status)) {
+ holder.text2.setVisibility(View.GONE);
+ } else {
+ holder.text2.setVisibility(View.VISIBLE);
+ holder.text2.setText(status);
+ }
+ }
+
+ void bindHeaderView(int position, ViewHolder holder) {
+ holder.text1.setText(mCategory.getName());
+ }
+
+ @Override
+ public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+ }
+
+ @Override
+ public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+ }
+
+ @Override
+ public void onRouteAdded(MediaRouter router, RouteInfo info) {
+ update();
+ initCheckedItems();
+ }
+
+ @Override
+ public void onRouteRemoved(MediaRouter router, RouteInfo info) {
+ if (info == mPrimary) {
+ // Can't keep grouping, clean it up.
+ onDoneGrouping();
+ } else {
+ update();
+ initCheckedItems();
+ }
+ }
+
+ @Override
+ public void onRouteChanged(MediaRouter router, RouteInfo info) {
+ update();
+ }
+
+ @Override
+ public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, int index) {
+ update();
+ initCheckedItems();
+ }
+
+ @Override
+ public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
+ update();
+ initCheckedItems();
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (getItemViewType(position) == VIEW_DONE) {
+ onDoneGrouping();
+ return;
+ }
+
+ final ListView lv = (ListView) parent;
+ final RouteInfo route = mFlatRoutes.get(position - 1);
+ final boolean checked = lv.isItemChecked(position);
+
+ mIgnoreUpdates = true;
+ RouteGroup oldGroup = route.getGroup();
+ if (checked && oldGroup != mPrimary) {
+ // Assumption: in a groupable category oldGroup will never be null.
+ oldGroup.removeRoute(route);
+
+ // If the group is now empty, remove the group too.
+ if (oldGroup.getRouteCount() == 0) {
+ if (mRouter.getSelectedRoute(mRouteTypes) == oldGroup) {
+ // Old group was selected but is now empty. Select the group
+ // we're manipulating since that's where the last route went.
+ mRouter.selectRoute(mRouteTypes, mPrimary);
+ }
+ mRouter.removeRouteInt(oldGroup);
+ }
+
+ mPrimary.addRoute(route);
+ } else if (!checked) {
+ if (mPrimary.getRouteCount() > 1) {
+ mPrimary.removeRoute(route);
+
+ // In a groupable category this will add the route into its own new group.
+ mRouter.addRouteInt(route);
+ } else {
+ // We're about to remove the last route.
+ // Don't let this happen, as it would be silly.
+ // Turn the checkmark back on again. Silly user!
+ lv.setItemChecked(position, true);
+ }
+ }
+ mIgnoreUpdates = false;
+ update();
+ initCheckedItems();
+ }
+ }
+
+ static class RouteComparator implements Comparator<RouteInfo> {
+ @Override
+ public int compare(RouteInfo lhs, RouteInfo rhs) {
+ return lhs.getName().toString().compareTo(rhs.getName().toString());
+ }
+ }
+
+ class RouteChooserDialog extends Dialog {
+ public RouteChooserDialog(Context context, int theme) {
+ super(context, theme);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mGroupAdapter != null) {
+ onDoneGrouping();
+ } else {
+ super.onBackPressed();
+ }
}
}
}
diff --git a/core/java/com/android/internal/view/CheckableLinearLayout.java b/core/java/com/android/internal/view/CheckableLinearLayout.java
new file mode 100644
index 0000000..3fb7cec
--- /dev/null
+++ b/core/java/com/android/internal/view/CheckableLinearLayout.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.view;
+
+import com.android.internal.R;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Checkable;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+
+public class CheckableLinearLayout extends LinearLayout implements Checkable {
+ private CheckBox mCheckBox;
+
+ public CheckableLinearLayout(Context context) {
+ super(context);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CheckableLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ // TODO Auto-generated constructor stub
+ }
+
+ public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mCheckBox = (CheckBox) findViewById(R.id.check);
+ }
+
+ @Override
+ public void setChecked(boolean checked) {
+ mCheckBox.setChecked(checked);
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mCheckBox.isChecked();
+ }
+
+ @Override
+ public void toggle() {
+ mCheckBox.toggle();
+ }
+}
diff --git a/core/java/com/android/internal/view/ImageButtonNoParentPress.java b/core/java/com/android/internal/view/ImageButtonNoParentPress.java
new file mode 100644
index 0000000..a6cfd86
--- /dev/null
+++ b/core/java/com/android/internal/view/ImageButtonNoParentPress.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+
+public class ImageButtonNoParentPress extends ImageButton {
+
+ public ImageButtonNoParentPress(Context context) {
+ super(context);
+ }
+
+ public ImageButtonNoParentPress(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ImageButtonNoParentPress(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void setPressed(boolean pressed) {
+ // Normally parents propagate pressed state to their children.
+ // We don't want that to happen here; only press if our parent isn't.
+ super.setPressed(((ViewGroup) getParent()).isPressed() ? false : pressed);
+ }
+}
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index 5096be6..837b7b8 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -115,7 +115,6 @@
private int mMaxTargetWidth;
private float mOuterRadius = 0.0f;
- private float mHitRadius = 0.0f;
private float mSnapMargin = 0.0f;
private boolean mDragging;
private int mNewTargetResources;
@@ -211,7 +210,6 @@
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GlowPadView);
mInnerRadius = a.getDimension(R.styleable.GlowPadView_innerRadius, mInnerRadius);
mOuterRadius = a.getDimension(R.styleable.GlowPadView_outerRadius, mOuterRadius);
- mHitRadius = a.getDimension(R.styleable.GlowPadView_hitRadius, mHitRadius);
mSnapMargin = a.getDimension(R.styleable.GlowPadView_snapMargin, mSnapMargin);
mVibrationDuration = a.getInt(R.styleable.GlowPadView_vibrationDuration,
mVibrationDuration);
@@ -280,7 +278,6 @@
private void dump() {
Log.v(TAG, "Outer Radius = " + mOuterRadius);
- Log.v(TAG, "HitRadius = " + mHitRadius);
Log.v(TAG, "SnapMargin = " + mSnapMargin);
Log.v(TAG, "FeedbackCount = " + mFeedbackCount);
Log.v(TAG, "VibrationDuration = " + mVibrationDuration);
@@ -799,7 +796,6 @@
final int historySize = event.getHistorySize();
ArrayList<TargetDrawable> targets = mTargetDrawables;
int ntargets = targets.size();
- final boolean singleTarget = ntargets == 1;
float x = 0.0f;
float y = 0.0f;
for (int k = 0; k < historySize + 1; k++) {
@@ -812,31 +808,29 @@
final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;
float limitX = tx * scale;
float limitY = ty * scale;
+ double angleRad = Math.atan2(-ty, tx);
if (!mDragging) {
trySwitchToFirstTouchState(eventX, eventY);
}
if (mDragging) {
- if (singleTarget) {
- // Snap to outer ring if there's only one target
- float snapRadius = mOuterRadius - mSnapMargin;
- if (touchRadius > snapRadius) {
- activeTarget = 0;
- }
- } else {
- // For more than one target, snap to the closest one less than hitRadius away.
- float best = Float.MAX_VALUE;
- final float hitRadius2 = mHitRadius * mHitRadius;
- // Find first target in range
- for (int i = 0; i < ntargets; i++) {
- TargetDrawable target = targets.get(i);
- float dx = limitX - target.getX();
- float dy = limitY - target.getY();
- float dist2 = dx*dx + dy*dy;
- if (target.isEnabled() && dist2 < hitRadius2 && dist2 < best) {
+ // For multiple targets, snap to the one that matches
+ final float snapRadius = mOuterRadius - mSnapMargin;
+ final float snapDistance2 = snapRadius * snapRadius;
+ // Find first target in range
+ for (int i = 0; i < ntargets; i++) {
+ TargetDrawable target = targets.get(i);
+
+ double targetMinRad = (i - 0.5) * 2 * Math.PI / ntargets;
+ double targetMaxRad = (i + 0.5) * 2 * Math.PI / ntargets;
+ if (target.isEnabled()) {
+ boolean angleMatches =
+ (angleRad > targetMinRad && angleRad <= targetMaxRad) ||
+ (angleRad + 2 * Math.PI > targetMinRad &&
+ angleRad + 2 * Math.PI <= targetMaxRad);
+ if (angleMatches && (dist2(tx, ty) > snapDistance2)) {
activeTarget = i;
- best = dist2;
}
}
}
@@ -851,10 +845,7 @@
if (activeTarget != -1) {
switchToState(STATE_SNAP, x,y);
- TargetDrawable target = targets.get(activeTarget);
- final float newX = singleTarget ? x : target.getX();
- final float newY = singleTarget ? y : target.getY();
- updateGlowPosition(newX, newY);
+ updateGlowPosition(x, y);
} else {
switchToState(STATE_TRACKING, x, y);
updateGlowPosition(x, y);
@@ -942,10 +933,6 @@
if (mOuterRadius == 0.0f) {
mOuterRadius = Math.max(mOuterRing.getWidth(), mOuterRing.getHeight())/2.0f;
}
- if (mHitRadius == 0.0f) {
- // Use the radius of inscribed circle of the first target.
- mHitRadius = mTargetDrawables.get(0).getWidth() / 2.0f;
- }
if (mSnapMargin == 0.0f) {
mSnapMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
SNAP_MARGIN_DEFAULT, getContext().getResources().getDisplayMetrics());
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index afeac00..10804c0 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -119,7 +119,6 @@
private int mMaxTargetWidth;
private float mOuterRadius = 0.0f;
- private float mHitRadius = 0.0f;
private float mSnapMargin = 0.0f;
private boolean mDragging;
private int mNewTargetResources;
@@ -213,7 +212,6 @@
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiWaveView);
mOuterRadius = a.getDimension(R.styleable.MultiWaveView_outerRadius, mOuterRadius);
- mHitRadius = a.getDimension(R.styleable.MultiWaveView_hitRadius, mHitRadius);
mSnapMargin = a.getDimension(R.styleable.MultiWaveView_snapMargin, mSnapMargin);
mVibrationDuration = a.getInt(R.styleable.MultiWaveView_vibrationDuration,
mVibrationDuration);
@@ -277,7 +275,6 @@
private void dump() {
Log.v(TAG, "Outer Radius = " + mOuterRadius);
- Log.v(TAG, "HitRadius = " + mHitRadius);
Log.v(TAG, "SnapMargin = " + mSnapMargin);
Log.v(TAG, "FeedbackCount = " + mFeedbackCount);
Log.v(TAG, "VibrationDuration = " + mVibrationDuration);
@@ -823,7 +820,6 @@
final int historySize = event.getHistorySize();
ArrayList<TargetDrawable> targets = mTargetDrawables;
int ntargets = targets.size();
- final boolean singleTarget = ntargets == 1;
float x = 0.0f;
float y = 0.0f;
for (int k = 0; k < historySize + 1; k++) {
@@ -836,31 +832,29 @@
final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;
float limitX = tx * scale;
float limitY = ty * scale;
+ double angleRad = Math.atan2(-ty, tx);
if (!mDragging) {
trySwitchToFirstTouchState(eventX, eventY);
}
if (mDragging) {
- if (singleTarget) {
- // Snap to outer ring if there's only one target
- float snapRadius = mOuterRadius - mSnapMargin;
- if (touchRadius > snapRadius) {
- activeTarget = 0;
- }
- } else {
- // For more than one target, snap to the closest one less than hitRadius away.
- float best = Float.MAX_VALUE;
- final float hitRadius2 = mHitRadius * mHitRadius;
- // Find first target in range
- for (int i = 0; i < ntargets; i++) {
- TargetDrawable target = targets.get(i);
- float dx = limitX - target.getX();
- float dy = limitY - target.getY();
- float dist2 = dx*dx + dy*dy;
- if (target.isEnabled() && dist2 < hitRadius2 && dist2 < best) {
+ // For multiple targets, snap to the one that matches
+ final float snapRadius = mOuterRadius - mSnapMargin;
+ final float snapDistance2 = snapRadius * snapRadius;
+ // Find first target in range
+ for (int i = 0; i < ntargets; i++) {
+ TargetDrawable target = targets.get(i);
+
+ double targetMinRad = (i - 0.5) * 2 * Math.PI / ntargets;
+ double targetMaxRad = (i + 0.5) * 2 * Math.PI / ntargets;
+ if (target.isEnabled()) {
+ boolean angleMatches =
+ (angleRad > targetMinRad && angleRad <= targetMaxRad) ||
+ (angleRad + 2 * Math.PI > targetMinRad &&
+ angleRad + 2 * Math.PI <= targetMaxRad);
+ if (angleMatches && (dist2(tx, ty) > snapDistance2)) {
activeTarget = i;
- best = dist2;
}
}
}
@@ -875,10 +869,7 @@
if (activeTarget != -1) {
switchToState(STATE_SNAP, x,y);
- TargetDrawable target = targets.get(activeTarget);
- final float newX = singleTarget ? x : target.getX();
- final float newY = singleTarget ? y : target.getY();
- moveHandleTo(newX, newY, false);
+ moveHandleTo(x, y, false);
} else {
switchToState(STATE_TRACKING, x, y);
moveHandleTo(x, y, false);
@@ -972,10 +963,6 @@
if (mOuterRadius == 0.0f) {
mOuterRadius = Math.max(mOuterRing.getWidth(), mOuterRing.getHeight())/2.0f;
}
- if (mHitRadius == 0.0f) {
- // Use the radius of inscribed circle of the first target.
- mHitRadius = mTargetDrawables.get(0).getWidth() / 2.0f;
- }
if (mSnapMargin == 0.0f) {
mSnapMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
SNAP_MARGIN_DEFAULT, getContext().getResources().getDisplayMetrics());
diff --git a/core/res/res/drawable-hdpi/ic_media_group_collapse.png b/core/res/res/drawable-hdpi/ic_media_group_collapse.png
new file mode 100644
index 0000000..89abf2c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_group_collapse.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_group_expand.png b/core/res/res/drawable-hdpi/ic_media_group_expand.png
new file mode 100644
index 0000000..d9470b2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_group_expand.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_group_collapse.png b/core/res/res/drawable-mdpi/ic_media_group_collapse.png
new file mode 100644
index 0000000..34454ac
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_group_collapse.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_group_expand.png b/core/res/res/drawable-mdpi/ic_media_group_expand.png
new file mode 100644
index 0000000..8ce5a44
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_group_expand.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_group_collapse.png b/core/res/res/drawable-xhdpi/ic_media_group_collapse.png
new file mode 100644
index 0000000..2fb7428
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_group_collapse.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_group_expand.png b/core/res/res/drawable-xhdpi/ic_media_group_expand.png
new file mode 100644
index 0000000..5755b9d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_group_expand.png
Binary files differ
diff --git a/core/res/res/drawable/item_background_activated_holo_dark.xml b/core/res/res/drawable/item_background_activated_holo_dark.xml
new file mode 100644
index 0000000..9cbf6ab
--- /dev/null
+++ b/core/res/res/drawable/item_background_activated_holo_dark.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+ <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_light" />
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" />
+ <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
+ <item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" />
+ <item android:drawable="@color/transparent" />
+</selector>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
index cd9c913..356e7cf 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
@@ -98,7 +98,6 @@
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
- android:hitRadius="@dimen/glowpadview_hit_radius"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index 32ca602..cb1cb21 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -98,7 +98,6 @@
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
- android:hitRadius="@dimen/glowpadview_hit_radius"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 4e646a6..91f65e9 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -139,7 +139,6 @@
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
- android:hitRadius="@dimen/glowpadview_hit_radius"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 5a357fb..8b9d8e4 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -144,7 +144,6 @@
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
- android:hitRadius="@dimen/glowpadview_hit_radius"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
diff --git a/core/res/res/layout/media_route_chooser_layout.xml b/core/res/res/layout/media_route_chooser_layout.xml
index 320d6de..731c0d0 100644
--- a/core/res/res/layout/media_route_chooser_layout.xml
+++ b/core/res/res/layout/media_route_chooser_layout.xml
@@ -45,10 +45,4 @@
<ListView android:id="@id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <Button android:id="@+id/done"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/borderlessButtonStyle"
- android:text="@string/media_route_chooser_grouping_done"
- android:visibility="gone" />
</LinearLayout>
diff --git a/core/res/res/layout/media_route_list_item.xml b/core/res/res/layout/media_route_list_item.xml
index d457c6c..ba1aaf2 100644
--- a/core/res/res/layout/media_route_list_item.xml
+++ b/core/res/res/layout/media_route_list_item.xml
@@ -17,7 +17,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
- android:background="?android:attr/activatedBackgroundIndicator"
+ android:background="@drawable/item_background_activated_holo_dark"
android:gravity="center_vertical">
<ImageView android:layout_width="56dp"
@@ -37,20 +37,25 @@
<TextView android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
- <!-- TODO Make this not glow when pressed from above, and give it a divider. -->
- <ImageButton android:layout_width="56dp"
- android:layout_height="56dp"
- android:id="@+id/group_button"
- android:background="?android:attr/selectableItemBackground"
- android:scaleType="center"
- android:visibility="gone" />
+ <com.android.internal.view.ImageButtonNoParentPress
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:id="@+id/expand_button"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="@drawable/ic_media_group_expand"
+ android:scaleType="center"
+ android:visibility="gone" />
</LinearLayout>
diff --git a/core/res/res/layout/media_route_list_item_checkable.xml b/core/res/res/layout/media_route_list_item_checkable.xml
new file mode 100644
index 0000000..f6ba09e
--- /dev/null
+++ b/core/res/res/layout/media_route_list_item_checkable.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<com.android.internal.view.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical">
+
+ <ImageView android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:scaleType="center"
+ android:id="@+id/icon"
+ android:visibility="gone" />
+
+ <LinearLayout android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="left|center_vertical"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight">
+
+ <TextView android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView android:id="@android:id/text2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="16dp"
+ android:id="@+id/check"
+ android:focusable="false"
+ android:clickable="false" />
+
+</com.android.internal.view.CheckableLinearLayout>
diff --git a/core/res/res/layout/media_route_list_item_collapse_group.xml b/core/res/res/layout/media_route_list_item_collapse_group.xml
new file mode 100644
index 0000000..3f4b1c0
--- /dev/null
+++ b/core/res/res/layout/media_route_list_item_collapse_group.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:background="#19ffffff"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:gravity="center_vertical">
+
+ <TextView android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:text="@string/media_route_chooser_grouping_done"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_media_group_collapse"
+ android:scaleType="center" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index d377882..0b3386b 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -108,9 +108,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginBottom="10dp"
android:layout_marginRight="8dp"
- android:layout_marginTop="2dp"
android:singleLine="false"
android:visibility="gone"
android:maxLines="8"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index aaa6778..a19bc2b 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokluidsprekers"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-klank"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Stelsel"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 510222d..d2cb8bc 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"የትከል ድምፅ ማጉያዎች"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ድምጽ"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"ስርዓት"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1e8b309..aea32a8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"مكبرات صوت للإرساء"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صوت HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"النظام"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 23631a8..bfe0e27 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Дынамікі станцыi"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аўдыёвыхад"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Сістэма"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 32911f9..a972258 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Докинг станц.: Високогов."</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index bc8a9c1..8f8fb1d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -361,15 +361,15 @@
<string name="permlab_writeProfile" msgid="907793628777397643">"modificació targeta contacte"</string>
<string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet que l\'aplicació pugui canviar o afegir informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que l\'aplicació et pot identificar i enviar la informació del teu perfil a altres persones."</string>
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"llegeix el teu tauler d\'activitat social"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet que l\'aplicació accedeixi i sincronitzi actualitzacions socials teves i dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació llegeix comunicacions entre tu i els teus amics a les xarxes socials, independentment de la confidencialitat. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet que l\'aplicació accedeixi i sincronitzi actualitzacions socials teves i dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació llegeixi comunicacions entre tu i els teus amics a les xarxes socials, independentment de la confidencialitat. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escriu al tauler d\'activitat social"</string>
<string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permet que l\'aplicació mostri actualitzacions socials dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació produeixi missatges que pot semblar que provinguin d\'un amic. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"llegeix els esdeveniments del calendari més informació confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permet que l\'aplicació llegeixi tots els esdeveniments del calendari emmagatzemats a la tauleta, inclosos els dels amics o dels companys de feina. Aquesta acció pot permetre que l\'aplicació comparteixi o desi les dades del teu calendari, sense tenir en compte la confidencialitat."</string>
<string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Permet que l\'aplicació llegeixi tots els esdeveniments del calendari emmagatzemats al telèfon, inclosos els dels amics o dels companys de feina. Aquesta acció pot permetre que l\'aplicació comparteixi o desi les dades del teu calendari, sense tenir en compte la confidencialitat."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"afegeix o modifica els esdeveniments del calendari i envia correus electrònics als clients sense el coneixement dels propietaris"</string>
- <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar a la tauleta, inclosos d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar al telèfon, inclosos d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
+ <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar a la tauleta, inclosos els d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar al telèfon, inclosos els d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"crear orígens d\'ubicacions fictícies per fer proves"</string>
<string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Crea fonts d\'ubicació fictícies per provar o per instal·lar un proveïdor d\'ubicació nou. Aquesta acció permet que l\'aplicació substitueixi la ubicació o l\'estat que retornen altres fonts d\'ubicació, com ara el GPS o altres proveïdors d\'ubicació."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accedir a ordres del proveïdor d\'ubicació addicionals"</string>
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altaveus del connector"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Àudio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index bb87fa6..35f0480 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index dc040e2..6bc5f9f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockstationens højttalere"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1556180..2bd623b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock-Lautsprecher"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-Audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1d4f378..9f50ca3 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Ηχεία βάσης σύνδεσης"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ήχος HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Σύστημα"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 553928b..1386ad5 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock speakers"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8e1582a..c58b08e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b6cb694..127abb5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 6ab1665..6266353 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doki kõlarid"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI heli"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Süsteem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index a22dd19..fcfbc0f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"بلندگوهای جایگاه اتصال"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صدای HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"سیستم"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c0fe3d5..5888acf 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"poista"</string>
<string name="inputMethod" msgid="1653630062304567879">"Syöttötapa"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoiminnot"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Tallennustila loppumassa"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kaikki järjestelmätoiminnot eivät välttämättä toimi"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,4 +1288,5 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Telineen kaiuttimet"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ääni"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Järjestelmä"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f8bc9aa..99c7627 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Haut-parleurs de la station d\'accueil"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Système"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 0551773..dbb3878 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"डॉक स्पीकर"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ऑडियो"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्टम"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index fddc295..dbe54ea 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvučnici postolja"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sustav"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index bdec648..79e3119 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkolóegység hangszórója"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audió"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Rendszer"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 5b5280f..28cc099 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pengeras suara dok"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 54b8b39..bf7a168 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -934,10 +934,8 @@
<string name="deleteText" msgid="7070985395199629156">"elimina"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metodo inserimento"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Azioni testo"</string>
- <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
- <skip />
- <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
- <skip />
+ <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spazio di archiviazione in esaurimento"</string>
+ <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Alcune funzioni di sistema potrebbero non funzionare"</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Annulla"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,4 +1288,5 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altoparlanti dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fine"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 83ad2c2..880cc9d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של מעגן"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"אודיו HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"מערכת"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 68166c3..eb3d96f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ホルダーのスピーカー"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMIオーディオ"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"システム"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index db56251..d345c91 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"도크 스피커"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 오디오"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"시스템"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 90f8c40..319aca7 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doko garsiakalbiai"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI garsas"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 54bd957..8839657 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doka skaļruņi"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistēma"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1f8a2ac..41f8521 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pembesar suara dok"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 6da4257..24d8497 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkhøyttalere"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e94a5fb..fb5e365 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockluidsprekers"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systeem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8c60669..8bd9b91 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Głośniki stacji dokującej"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Dźwięk przez HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 8c86fc6..1e2687d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altif. estação ancoragem"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 525719f..75840cc 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes do dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index ad15a00..d5a4250 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -2024,4 +2024,6 @@
<skip />
<!-- no translation found for default_audio_route_category_name (3722811174003886946) -->
<skip />
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 4e90357..ef732f8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Difuz. dispozit. andocare"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ieşire audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e4b2962..8c280cc 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динамики док-станции"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 49c50bc..0ddf9ef 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 11a0f34..102e6f2 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvočniki stojala"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvok HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 08bbd34..7dd17fc 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Звучници базне станице"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Систем"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index fa4297c..c673628 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockningsstationens högtalare"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ljud"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ac53b00..ef9d19d 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Vipasa sauti vya gati"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Sauti ya HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Mfumo"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9b19913..c4b31d5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ลำโพงแท่นชาร์จ"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"เสียง HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"ระบบ"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ae51a44..4ea1dbc 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Mga speaker ng dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 26b5108..182e2cd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Yuva hoparlörleri"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ses"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 164766c..d861415 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динаміки док-станції"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Аудіовихід HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 271e952..e80ac6a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Loa đế"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Âm thanh HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Hệ thống"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 82c5bf1..6b1bfa6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"基座扬声器"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音频"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系统"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a79cead..9decfa9 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"座架喇叭"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音訊"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系統"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 812fc7c..48a7a8a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1290,4 +1290,6 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Izipika ze-Dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Umsindo we-HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Isistimu"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 00077512..3a7253b 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5405,9 +5405,6 @@
<!-- Outer radius of glow area. Target icons will be drawn on this circle. -->
<attr name="outerRadius"/>
- <!-- Size of target radius. Points within this distance of target center is a "hit". -->
- <attr name="hitRadius"/>
-
<!-- Radius of glow under finger. -->
<attr name="glowRadius" format="dimension" />
@@ -5450,9 +5447,6 @@
<!-- Outer radius of target circle. Icons will be drawn on this circle. -->
<attr name="outerRadius" format="dimension" />
- <!-- Size of target radius. Points within this distance of target center is a "hit". -->
- <attr name="hitRadius" format="dimension" />
-
<!-- Tactile feedback duration for actions. Set to '0' for no vibration. -->
<attr name="vibrationDuration" format="integer"/>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ffbcb95..f30943a 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -79,11 +79,8 @@
<!-- Default glow radius for GlowPadView -->
<dimen name="glowpadview_glow_radius">75dip</dimen>
- <!-- Default distance beyond which GlowPadView snaps to the target radius -->
- <dimen name="glowpadview_snap_margin">20dip</dimen>
-
- <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
- <dimen name="glowpadview_hit_radius">60dip</dimen>
+ <!-- Default distance beyond which GlowPadView snaps to the matching target -->
+ <dimen name="glowpadview_snap_margin">40dip</dimen>
<!-- Default distance from each snap target that GlowPadView considers a "hit" -->
<dimen name="glowpadview_inner_radius">15dip</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0af8534..a6f2f49 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1166,13 +1166,15 @@
<java-symbol type="attr" name="mediaRouteButtonStyle" />
<java-symbol type="attr" name="externalRouteEnabledDrawable" />
- <java-symbol type="layout" name="media_route_chooser_layout" />
<java-symbol type="id" name="extended_settings" />
- <java-symbol type="id" name="done" />
+ <java-symbol type="id" name="check" />
+ <java-symbol type="layout" name="media_route_chooser_layout" />
<java-symbol type="layout" name="media_route_list_item_top_header" />
<java-symbol type="layout" name="media_route_list_item_section_header" />
<java-symbol type="layout" name="media_route_list_item" />
- <java-symbol type="id" name="group_button" />
+ <java-symbol type="layout" name="media_route_list_item_checkable" />
+ <java-symbol type="layout" name="media_route_list_item_collapse_group" />
+ <java-symbol type="string" name="bluetooth_a2dp_audio_route_name" />
<!-- From android.policy -->
<java-symbol type="anim" name="app_starting_exit" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 967d700..da4d37a 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3571,6 +3571,9 @@
<!-- Name of the default audio route category. [CHAR LIMIT=50] -->
<string name="default_audio_route_category_name">System</string>
+ <!-- Default name of the bluetooth a2dp audio route. [CHAR LIMIT=50] -->
+ <string name="bluetooth_a2dp_audio_route_name">Bluetooth audio</string>
+
<!-- "Done" button for MediaRouter chooser dialog when grouping routes. [CHAR LIMIT=NONE] -->
<string name="media_route_chooser_grouping_done">Done</string>
</resources>
diff --git a/include/androidfw/KeycodeLabels.h b/include/androidfw/KeycodeLabels.h
index 1828062..538949d 100755
--- a/include/androidfw/KeycodeLabels.h
+++ b/include/androidfw/KeycodeLabels.h
@@ -243,6 +243,7 @@
{ "YEN", 216 },
{ "RO", 217 },
{ "KANA", 218 },
+ { "ASSIST", 219 },
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index b0657ff..8488cd2 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -237,6 +237,13 @@
addRoute(info);
}
+ /**
+ * @hide Framework use only
+ */
+ public void addRouteInt(RouteInfo info) {
+ addRoute(info);
+ }
+
static void addRoute(RouteInfo info) {
final RouteCategory cat = info.getCategory();
if (!sStatic.mCategories.contains(cat)) {
@@ -246,13 +253,10 @@
if (cat.isGroupable() && !(info instanceof RouteGroup)) {
// Enforce that any added route in a groupable category must be in a group.
final RouteGroup group = new RouteGroup(info.getCategory());
+ group.addRoute(info);
sStatic.mRoutes.add(group);
dispatchRouteAdded(group);
- final int at = group.getRouteCount();
- group.addRoute(info);
- dispatchRouteGrouped(info, group, at);
-
info = group;
} else {
sStatic.mRoutes.add(info);
@@ -282,13 +286,22 @@
public void clearUserRoutes() {
for (int i = 0; i < sStatic.mRoutes.size(); i++) {
final RouteInfo info = sStatic.mRoutes.get(i);
- if (info instanceof UserRouteInfo) {
+ // TODO Right now, RouteGroups only ever contain user routes.
+ // The code below will need to change if this assumption does.
+ if (info instanceof UserRouteInfo || info instanceof RouteGroup) {
removeRouteAt(i);
i--;
}
}
}
+ /**
+ * @hide internal use only
+ */
+ public void removeRouteInt(RouteInfo info) {
+ removeRoute(info);
+ }
+
static void removeRoute(RouteInfo info) {
if (sStatic.mRoutes.remove(info)) {
final RouteCategory removingCat = info.getCategory();
@@ -301,6 +314,11 @@
break;
}
}
+ if (info == sStatic.mSelectedRoute) {
+ // Removing the currently selected route? Select the default before we remove it.
+ // TODO: Be smarter about the route types here; this selects for all valid.
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio);
+ }
if (!found) {
sStatic.mCategories.remove(removingCat);
}
@@ -321,6 +339,11 @@
break;
}
}
+ if (info == sStatic.mSelectedRoute) {
+ // Removing the currently selected route? Select the default before we remove it.
+ // TODO: Be smarter about the route types here; this selects for all valid.
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio);
+ }
if (!found) {
sStatic.mCategories.remove(removingCat);
}
@@ -478,7 +501,8 @@
static void onA2dpDeviceConnected() {
final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
- info.mName = "Bluetooth"; // TODO Fetch the real name of the device
+ info.mName = sStatic.mResources.getString(
+ com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
sStatic.mBluetoothA2dpRoute = info;
addRoute(sStatic.mBluetoothA2dpRoute);
}
@@ -567,9 +591,9 @@
@Override
public String toString() {
- String supportedTypes = typesToString(mSupportedTypes);
- return "RouteInfo{ name=" + mName + ", status=" + mStatus +
- " category=" + mCategory +
+ String supportedTypes = typesToString(getSupportedTypes());
+ return getClass().getSimpleName() + "{ name=" + getName() + ", status=" + getStatus() +
+ " category=" + getCategory() +
" supportedTypes=" + supportedTypes + "}";
}
}
@@ -698,6 +722,7 @@
}
final int at = mRoutes.size();
mRoutes.add(route);
+ route.mGroup = this;
mUpdateName = true;
dispatchRouteGrouped(route, this, at);
routeUpdated();
@@ -720,6 +745,7 @@
" group category=" + mCategory + ")");
}
mRoutes.add(insertAt, route);
+ route.mGroup = this;
mUpdateName = true;
dispatchRouteGrouped(route, this, insertAt);
routeUpdated();
@@ -736,6 +762,7 @@
" is not a member of this group.");
}
mRoutes.remove(route);
+ route.mGroup = null;
mUpdateName = true;
dispatchRouteUngrouped(route, this);
routeUpdated();
@@ -748,6 +775,7 @@
*/
public void removeRoute(int index) {
RouteInfo route = mRoutes.remove(index);
+ route.mGroup = null;
mUpdateName = true;
dispatchRouteUngrouped(route, this);
routeUpdated();
@@ -799,6 +827,18 @@
setStatusInt(status);
}
+ @Override
+ void routeUpdated() {
+ int types = 0;
+ final int count = mRoutes.size();
+ for (int i = 0; i < count; i++) {
+ types |= mRoutes.get(i).mSupportedTypes;
+ }
+ mSupportedTypes = types;
+ mIcon = count == 1 ? mRoutes.get(0).getIconDrawable() : null;
+ super.routeUpdated();
+ }
+
void updateName() {
final StringBuilder sb = new StringBuilder();
final int count = mRoutes.size();
@@ -810,6 +850,19 @@
mName = sb.toString();
mUpdateName = false;
}
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append('[');
+ final int count = mRoutes.size();
+ for (int i = 0; i < count; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(mRoutes.get(i));
+ }
+ sb.append(']');
+ return sb.toString();
+ }
}
/**
@@ -884,7 +937,7 @@
public String toString() {
return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) +
- " groupable=" + mGroupable + " routes=" + sStatic.mRoutes.size() + " }";
+ " groupable=" + mGroupable + " }";
}
}
diff --git a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
index 52c9fda..78f7f3e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
@@ -29,6 +29,7 @@
import android.filterfw.format.ImageFormat;
import android.opengl.GLES20;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.Log;
import java.lang.ArrayIndexOutOfBoundsException;
@@ -510,6 +511,20 @@
super(name);
mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE);
+
+ String adjStr = SystemProperties.get("ro.media.effect.bgdropper.adj");
+ if (adjStr.length() > 0) {
+ try {
+ mAcceptStddev += Float.parseFloat(adjStr);
+ if (mLogVerbose) {
+ Log.v(TAG, "Adjusting accept threshold by " + adjStr +
+ ", now " + mAcceptStddev);
+ }
+ } catch (NumberFormatException e) {
+ Log.e(TAG,
+ "Badly formatted property ro.media.effect.bgdropper.adj: " + adjStr);
+ }
+ }
}
@Override
@@ -695,7 +710,6 @@
mBgUpdateVarianceProgram.setHostValue("bg_adapt_rate", mAdaptRateLearning);
mBgUpdateVarianceProgram.setHostValue("fg_adapt_rate", mAdaptRateLearning);
mFrameCount = 0;
- mStartLearning = false;
}
// Select correct pingpong buffers
@@ -720,6 +734,11 @@
mBgInput.setTextureParameter(GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR_MIPMAP_NEAREST);
+ if (mStartLearning) {
+ copyShaderProgram.process(mVideoInput, mBgMean[inputIndex]);
+ mStartLearning = false;
+ }
+
// Process shaders
Frame[] distInputs = { mVideoInput, mBgMean[inputIndex], mBgVariance[inputIndex] };
mBgDistProgram.process(distInputs, mDistance);
@@ -765,7 +784,12 @@
ByteBuffer mMaskAverageByteBuffer = mMaskAverage.getData();
byte[] mask_average = mMaskAverageByteBuffer.array();
int bi = (int)(mask_average[3] & 0xFF);
- if (mLogVerbose) Log.v(TAG, String.format("Mask_average is %d", bi));
+
+ if (mLogVerbose) {
+ Log.v(TAG,
+ String.format("Mask_average is %d, threshold is %d",
+ bi, DEFAULT_LEARNING_DONE_THRESHOLD));
+ }
if (bi >= DEFAULT_LEARNING_DONE_THRESHOLD) {
mStartLearning = true; // Restart learning
diff --git a/packages/SystemUI/res/drawable/system_bar_notification_header_bg.xml b/packages/SystemUI/res/drawable/system_bar_notification_header_bg.xml
new file mode 100644
index 0000000..85f1ea2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/system_bar_notification_header_bg.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@*android:drawable/list_selector_pressed_holo_dark" />
+ <item android:drawable="@*android:drawable/list_selector_disabled_holo_dark" />
+</selector>
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
index e6c0087..c8a120d 100644
--- a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
@@ -54,7 +54,6 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
prvandroid:feedbackCount="0"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
diff --git a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
index 3828136..1e4bb57 100644
--- a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
@@ -54,7 +54,6 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
prvandroid:feedbackCount="0"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
index c17f858..3b6c52e 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
@@ -40,7 +40,6 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
prvandroid:feedbackCount="0"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
diff --git a/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
index 100f81d..8c2360e 100644
--- a/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
@@ -41,7 +41,6 @@
prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
prvandroid:feedbackCount="0"
prvandroid:vibrationDuration="@integer/config_vibration_duration"
prvandroid:alwaysTrackFinger="true"
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
index afe3b49..480d979 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
@@ -18,7 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/title_area"
- android:background="@color/notification_panel_solid_background"
+ android:background="@drawable/system_bar_notification_header_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c88ae2a..6a96c6b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -110,11 +110,8 @@
<!-- The width of the view containing the menu status bar icon -->
<dimen name="navigation_menu_key_width">40dip</dimen>
- <!-- Default distance beyond which snaps to the target radius -->
- <dimen name="navbar_search_snap_margin">20dip</dimen>
-
- <!-- Default distance from each snap target considers a "hit" -->
- <dimen name="navbar_search_hit_radius">60dip</dimen>
+ <!-- Default distance beyond which snaps to the matching target -->
+ <dimen name="navbar_search_snap_margin">40dip</dimen>
<!-- Diameter of outer shape drawable shown in navbar search-->
<dimen name="navbar_search_outerring_diameter">340dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index df41d25..48efbc7 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -23,11 +23,14 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.Log;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
+import android.widget.ScrollView;
+import android.widget.FrameLayout;
public class ExpandHelper implements Gefingerpoken, OnClickListener {
public interface Callback {
@@ -38,7 +41,7 @@
}
private static final String TAG = "ExpandHelper";
- protected static final boolean DEBUG = false;
+ protected static final boolean DEBUG = true;
private static final long EXPAND_DURATION = 250;
private static final long GLOW_DURATION = 150;
@@ -82,8 +85,11 @@
private int mLargeSize;
private float mMaximumStretch;
+ private int mGravity;
+
private class ViewScaler {
View mView;
+
public ViewScaler() {}
public void setView(View v) {
mView = v;
@@ -119,6 +125,15 @@
}
}
+ /**
+ * Handle expansion gestures to expand and contract children of the callback.
+ *
+ * @param context application context
+ * @param callback the container that holds the items to be manipulated
+ * @param small the smallest allowable size for the manuipulated items.
+ * @param large the largest allowable size for the manuipulated items.
+ * @param scoller if non-null also manipulate the scroll position to obey the gravity.
+ */
public ExpandHelper(Context context, Callback callback, int small, int large) {
mSmallSize = small;
mMaximumStretch = mSmallSize * STRETCH_INTERVAL;
@@ -126,7 +141,7 @@
mContext = context;
mCallback = callback;
mScaler = new ViewScaler();
-
+ mGravity = Gravity.TOP;
mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
mScaleAnimation.setDuration(EXPAND_DURATION);
@@ -194,6 +209,7 @@
span *= USE_SPAN ? 1f : 0f;
float drag = detector.getFocusY() - mInitialTouchFocusY;
drag *= USE_DRAG ? 1f : 0f;
+ drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
float pull = Math.abs(drag) + Math.abs(span) + 1f;
float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
if (DEBUG) Log.d(TAG, "current span handle is: " + hand);
@@ -227,6 +243,10 @@
mEventSource = eventSource;
}
+ public void setGravity(int gravity) {
+ mGravity = gravity;
+ }
+
public void setGlow(float glow) {
if (!mGlowAnimationSet.isRunning() || glow == 0f) {
if (mGlowAnimationSet.isRunning()) {
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 923bcba..c082c97 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -23,7 +23,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Vibrator;
import android.provider.Settings;
@@ -35,6 +34,7 @@
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.FrameLayout;
+
import com.android.internal.widget.multiwaveview.GlowPadView;
import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
import com.android.systemui.R;
@@ -53,6 +53,7 @@
private static final String ASSIST_ICON_METADATA_NAME =
"com.android.systemui.action_assist_icon";
private final Context mContext;
+ private final SearchManager mSearchManager;
private BaseStatusBar mBar;
private StatusBarTouchProxy mStatusBarTouchProxy;
@@ -73,38 +74,12 @@
}
}
- private SearchManager mSearchManager;
-
- // This code should be the same as that used in LockScreen.java
public boolean isAssistantAvailable() {
- Intent intent = getAssistIntent();
- return intent == null ? false
- : mContext.getPackageManager().queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
+ return mSearchManager != null && mSearchManager.isAssistantAvailable();
}
private Intent getAssistIntent() {
- Intent intent = null;
- SearchManager searchManager = getSearchManager();
- if (searchManager != null) {
- ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
- if (globalSearchActivity != null) {
- intent = new Intent(Intent.ACTION_ASSIST);
- intent.setPackage(globalSearchActivity.getPackageName());
- } else {
- Slog.w(TAG, "No global search activity");
- }
- } else {
- Slog.w(TAG, "No SearchManager");
- }
- return intent;
- }
-
- private SearchManager getSearchManager() {
- if (mSearchManager == null) {
- mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
- }
- return mSearchManager;
+ return mSearchManager != null ? mSearchManager.getAssistIntent() : null;
}
private void startAssistActivity() {
@@ -175,9 +150,8 @@
// TODO: fetch views
mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
mGlowPadView.setOnTriggerListener(mGlowPadViewListener);
- SearchManager searchManager = getSearchManager();
- if (searchManager != null) {
- ComponentName component = searchManager.getGlobalSearchActivity();
+ if (mSearchManager != null) {
+ ComponentName component = mSearchManager.getGlobalSearchActivity();
if (component != null) {
if (!mGlowPadView.replaceTargetDrawablesIfPresent(component,
ASSIST_ICON_METADATA_NAME,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 9c773a5..00d6d6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -225,11 +225,28 @@
final boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
+ setSlippery(disableHome && disableRecent && disableBack);
+
getBackButton() .setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
}
+ public void setSlippery(boolean newSlippery) {
+ WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
+ if (lp != null) {
+ boolean oldSlippery = (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0;
+ if (!oldSlippery && newSlippery) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
+ } else if (oldSlippery && !newSlippery) {
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
+ } else {
+ return;
+ }
+ WindowManagerImpl.getDefault().updateViewLayout(this, lp);
+ }
+ }
+
public void setMenuVisibility(final boolean show) {
setMenuVisibility(show, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 56de506..baf86f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -171,6 +171,7 @@
final Rect mNotificationPanelBackgroundPadding = new Rect();
int mNotificationPanelGravity;
int mNotificationPanelMinHeight;
+ boolean mNotificationPanelIsFullScreenWidth;
// top bar
View mClearButton;
@@ -361,9 +362,11 @@
return true;
}
});
+ mNotificationPanelIsFullScreenWidth =
+ (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
mNotificationPanel.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
- | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
+ | (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO));
if (!ActivityManager.isHighEndGfx(mDisplay)) {
mStatusBarWindow.setBackground(null);
@@ -376,6 +379,8 @@
mIntruderAlertView.setBar(this);
}
+ updateShowSearchHoldoff();
+
mStatusBarView.mService = this;
mChoreographer = Choreographer.getInstance();
@@ -663,7 +668,6 @@
lp.setTitle("NavigationBar");
lp.windowAnimations = 0;
-
return lp;
}
@@ -808,8 +812,12 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
updateRecentsPanel();
- mShowSearchHoldoff = mContext.getResources().getInteger(
- R.integer.config_show_search_delay);
+ updateShowSearchHoldoff();
+ }
+
+ private void updateShowSearchHoldoff() {
+ mShowSearchHoldoff = mContext.getResources().getInteger(
+ R.integer.config_show_search_delay);
}
private void loadNotificationShade() {
@@ -1174,7 +1182,8 @@
mExpandedVisible = true;
mPile.setLayoutTransitionsEnabled(true);
- makeSlippery(mNavigationBarView, true);
+ if (mNavigationBarView != null)
+ mNavigationBarView.setSlippery(true);
updateCarrierLabelVisibility(true);
@@ -1198,19 +1207,6 @@
visibilityChanged(true);
}
- private static void makeSlippery(View view, boolean slippery) {
- if (view == null) {
- return;
- }
- WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();
- if (slippery) {
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
- } else {
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
- }
- WindowManagerImpl.getDefault().updateViewLayout(view, lp);
- }
-
public void animateExpand() {
if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
@@ -1295,8 +1291,9 @@
}
mExpandedVisible = false;
mPile.setLayoutTransitionsEnabled(false);
+ if (mNavigationBarView != null)
+ mNavigationBarView.setSlippery(false);
visibilityChanged(false);
- makeSlippery(mNavigationBarView, false);
// Shrink the window to the size of the status bar only
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index ed1b2f5..9317561 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -22,6 +22,7 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.FrameLayout;
+import android.widget.ScrollView;
import android.widget.TextSwitcher;
import com.android.systemui.ExpandHelper;
@@ -47,6 +48,7 @@
protected void onAttachedToWindow () {
super.onAttachedToWindow();
latestItems = (NotificationRowLayout) findViewById(R.id.latestItems);
+ ScrollView scroller = (ScrollView) findViewById(R.id.scroll);
int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index d8166f1..af0f9d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -24,6 +24,7 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Slog;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -33,6 +34,7 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.RelativeLayout;
+import android.widget.ScrollView;
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
@@ -114,6 +116,7 @@
int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
mExpandHelper.setEventSource(this);
+ mExpandHelper.setGravity(Gravity.BOTTOM);
}
private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 18b8042..87ec16b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -81,7 +81,7 @@
private int mFailedAttempts = 0;
private int mFailedBiometricUnlockAttempts = 0;
- private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 5;
+ private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
private boolean mClockVisible;
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index d7fb19a..58d14ed 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -58,7 +58,6 @@
final IccCard.State simState = mUpdateMonitor.getSimState();
return (simState == IccCard.State.PIN_REQUIRED
|| simState == IccCard.State.PUK_REQUIRED
- || simState == IccCard.State.ABSENT
|| simState == IccCard.State.PERM_DISABLED);
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index c9388cb..4af66ce 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -32,7 +32,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Vibrator;
@@ -254,29 +253,14 @@
}
}
- // This code should be the same as that in SearchPanelView
- public boolean isAssistantAvailable() {
- Intent intent = getAssistIntent();
- return intent == null ? false
- : mContext.getPackageManager().queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
+ private boolean isAssistantAvailable() {
+ SearchManager searchManager = getSearchManager();
+ return searchManager != null && searchManager.isAssistantAvailable();
}
private Intent getAssistIntent() {
- Intent intent = null;
SearchManager searchManager = getSearchManager();
- if (searchManager != null) {
- ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
- if (globalSearchActivity != null) {
- intent = new Intent(Intent.ACTION_ASSIST);
- intent.setPackage(globalSearchActivity.getPackageName());
- } else {
- Slog.w(TAG, "No global search activity");
- }
- } else {
- Slog.w(TAG, "No SearchManager");
- }
- return intent;
+ return searchManager != null ? searchManager.getAssistIntent() : null;
}
private SearchManager getSearchManager() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 9ef8d6b..a5190f1 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -19,6 +19,7 @@
import android.app.ActivityManagerNative;
import android.app.IUiModeManager;
import android.app.ProgressDialog;
+import android.app.SearchManager;
import android.app.UiModeManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -235,6 +236,7 @@
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
+ static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
/**
* These are the system UI flags that, when changing, can cause the layout
@@ -279,6 +281,7 @@
LocalPowerManager mPowerManager;
IStatusBarService mStatusBarService;
Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
+ SearchManager mSearchManager;
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -462,6 +465,7 @@
Intent mDeskDockIntent;
boolean mSearchKeyShortcutPending;
boolean mConsumeSearchKeyUp;
+ boolean mAssistKeyLongPressed;
// support for activating the lock screen while the screen is on
boolean mAllowLockscreenWhenOn;
@@ -1860,6 +1864,26 @@
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
}
return -1;
+ } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
+ if (down) {
+ if (repeatCount == 0) {
+ mAssistKeyLongPressed = false;
+ } else if (repeatCount == 1) {
+ mAssistKeyLongPressed = true;
+ if (!keyguardOn) {
+ launchAssistLongPressAction();
+ }
+ }
+ } else {
+ if (mAssistKeyLongPressed) {
+ mAssistKeyLongPressed = false;
+ } else {
+ if (!keyguardOn) {
+ launchAssistAction();
+ }
+ }
+ }
+ return -1;
}
// Shortcuts are invoked through Search+key, so intercept those here
@@ -2050,6 +2074,50 @@
return false;
}
+ private void launchAssistLongPressAction() {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
+
+ // launch the search activity
+ Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ SearchManager searchManager = getSearchManager();
+ if (searchManager != null) {
+ searchManager.stopSearch();
+ }
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist long press action.", e);
+ }
+ }
+
+ private void launchAssistAction() {
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
+
+ SearchManager searchManager = getSearchManager();
+ if (searchManager != null) {
+ Intent intent = searchManager.getAssistIntent();
+ if (intent != null) {
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist action.", e);
+ }
+ }
+ }
+ }
+
+ private SearchManager getSearchManager() {
+ if (mSearchManager == null) {
+ mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+ }
+ return mSearchManager;
+ }
+
/**
* A home key -> launch home action was detected. Take the appropriate action
* given the situation with the keyguard.
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 985249d..2918dbc 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1702,7 +1702,9 @@
mProximityAlerts.remove(intent);
if (mProximityAlerts.size() == 0) {
- removeUpdatesLocked(mProximityReceiver);
+ if (mProximityReceiver != null) {
+ removeUpdatesLocked(mProximityReceiver);
+ }
mProximityReceiver = null;
mProximityListener = null;
}
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index a36c673..152e1889 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -98,6 +98,9 @@
// the two dragging pointers as opposed to use the location of the primary one.
private static final int MIN_POINTER_DISTANCE_TO_USE_MIDDLE_LOCATION_DIP = 200;
+ // The timeout after which we are no longer trying to detect a gesture.
+ private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000;
+
// Temporary array for storing pointer IDs.
private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT];
@@ -138,6 +141,9 @@
// Command for delayed sending of a long press.
private final PerformLongPressDelayed mPerformLongPressDelayed;
+ // Command for exiting gesture detection mode after a timeout.
+ private final ExitGestureDetectionModeDelayed mExitGestureDetectionModeDelayed;
+
// Helper to detect and react to double tap in touch explore mode.
private final DoubleTapDetector mDoubleTapDetector;
@@ -212,6 +218,7 @@
mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
mHandler = new Handler(context.getMainLooper());
mPerformLongPressDelayed = new PerformLongPressDelayed();
+ mExitGestureDetectionModeDelayed = new ExitGestureDetectionModeDelayed();
mGestureLibrary = GestureLibraries.fromRawResource(context, R.raw.accessibility_gestures);
mGestureLibrary.setOrientationStyle(4);
mGestureLibrary.load();
@@ -257,6 +264,7 @@
mSendHoverEnterDelayed.remove();
mSendHoverExitDelayed.remove();
mPerformLongPressDelayed.remove();
+ mExitGestureDetectionModeDelayed.remove();
// Reset the pointer trackers.
mReceivedPointerTracker.clear();
mInjectedPointerTracker.clear();
@@ -304,9 +312,9 @@
switch (eventType) {
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
- if (mInjectedPointerTracker.mLastInjectedHoverEvent != null) {
- mInjectedPointerTracker.mLastInjectedHoverEvent.recycle();
- mInjectedPointerTracker.mLastInjectedHoverEvent = null;
+ if (mInjectedPointerTracker.mLastInjectedHoverEventForClick != null) {
+ mInjectedPointerTracker.mLastInjectedHoverEventForClick.recycle();
+ mInjectedPointerTracker.mLastInjectedHoverEventForClick = null;
}
mLastTouchedWindowId = -1;
} break;
@@ -420,6 +428,7 @@
mSendHoverEnterDelayed.remove();
mSendHoverExitDelayed.remove();
mPerformLongPressDelayed.remove();
+ mExitGestureDetectionModeDelayed.post();
} else {
// We have just decided that the user is touch,
// exploring so start sending events.
@@ -727,6 +736,7 @@
}
mStrokeBuffer.clear();
+ mExitGestureDetectionModeDelayed.remove();
mCurrentState = STATE_TOUCH_EXPLORING;
} break;
case MotionEvent.ACTION_CANCEL: {
@@ -1067,7 +1077,8 @@
final int pointerId = secondTapUp.getPointerId(secondTapUp.getActionIndex());
final int pointerIndex = secondTapUp.findPointerIndex(pointerId);
- MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
+ MotionEvent lastExploreEvent =
+ mInjectedPointerTracker.getLastInjectedHoverEventForClick();
if (lastExploreEvent == null) {
// No last touch explored event but there is accessibility focus in
// the active window. We click in the middle of the focus bounds.
@@ -1263,6 +1274,25 @@
}
/**
+ * Class for delayed exiting from gesture detecting mode.
+ */
+ private final class ExitGestureDetectionModeDelayed implements Runnable {
+
+ public void post() {
+ mHandler.postDelayed(this, EXIT_GESTURE_DETECTION_TIMEOUT);
+ }
+
+ public void remove() {
+ mHandler.removeCallbacks(this);
+ }
+
+ @Override
+ public void run() {
+ clear();
+ }
+ }
+
+ /**
* Class for delayed sending of long press.
*/
private final class PerformLongPressDelayed implements Runnable {
@@ -1299,7 +1329,8 @@
final int pointerId = mEvent.getPointerId(mEvent.getActionIndex());
final int pointerIndex = mEvent.findPointerIndex(pointerId);
- MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEvent();
+ MotionEvent lastExploreEvent =
+ mInjectedPointerTracker.getLastInjectedHoverEventForClick();
if (lastExploreEvent == null) {
// No last touch explored event but there is accessibility focus in
// the active window. We click in the middle of the focus bounds.
@@ -1453,6 +1484,9 @@
// The last injected hover event.
private MotionEvent mLastInjectedHoverEvent;
+ // The last injected hover event used for performing clicks.
+ private MotionEvent mLastInjectedHoverEventForClick;
+
/**
* Processes an injected {@link MotionEvent} event.
*
@@ -1484,6 +1518,10 @@
mLastInjectedHoverEvent.recycle();
}
mLastInjectedHoverEvent = MotionEvent.obtain(event);
+ if (mLastInjectedHoverEventForClick != null) {
+ mLastInjectedHoverEventForClick.recycle();
+ }
+ mLastInjectedHoverEventForClick = MotionEvent.obtain(event);
} break;
}
if (DEBUG) {
@@ -1537,6 +1575,13 @@
return mLastInjectedHoverEvent;
}
+ /**
+ * @return The the last injected hover event.
+ */
+ public MotionEvent getLastInjectedHoverEventForClick() {
+ return mLastInjectedHoverEventForClick;
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();