Merge "When SIM absent, keyguard should be considered non-secure." into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 55c9e28..f5bc504 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3690,6 +3690,7 @@
method public int getRouteTypes();
method public void setExtendedSettingsClickListener(android.view.View.OnClickListener);
method public void setRouteTypes(int);
+ method public void showDialog();
}
public class NativeActivity extends android.app.Activity implements android.view.InputQueue.Callback android.view.SurfaceHolder.Callback2 android.view.ViewTreeObserver.OnGlobalLayoutListener {
@@ -11575,11 +11576,13 @@
}
public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
+ method public java.lang.Object getTag();
method public void setIconDrawable(android.graphics.drawable.Drawable);
method public void setIconResource(int);
method public void setName(java.lang.CharSequence);
method public void setRemoteControlClient(android.media.RemoteControlClient);
method public void setStatus(java.lang.CharSequence);
+ method public void setTag(java.lang.Object);
}
public class MediaScannerConnection implements android.content.ServiceConnection {
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java
index 5fe08ec..4860182 100644
--- a/core/java/android/app/MediaRouteActionProvider.java
+++ b/core/java/android/app/MediaRouteActionProvider.java
@@ -16,7 +16,10 @@
package android.app;
+import com.android.internal.app.MediaRouteChooserDialogFragment;
+
import android.content.Context;
+import android.content.ContextWrapper;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
import android.util.Log;
@@ -83,10 +86,37 @@
@Override
public boolean onPerformDefaultAction() {
- // Show routing dialog
+ final FragmentManager fm = getActivity().getFragmentManager();
+ // See if one is already attached to this activity.
+ MediaRouteChooserDialogFragment dialogFragment =
+ (MediaRouteChooserDialogFragment) fm.findFragmentByTag(
+ MediaRouteChooserDialogFragment.FRAGMENT_TAG);
+ if (dialogFragment != null) {
+ Log.w(TAG, "onPerformDefaultAction(): Chooser dialog already showing!");
+ return false;
+ }
+
+ dialogFragment = new MediaRouteChooserDialogFragment();
+ dialogFragment.setExtendedSettingsClickListener(mExtendedSettingsListener);
+ dialogFragment.setRouteTypes(mRouteTypes);
+ dialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG);
return true;
}
+ private Activity getActivity() {
+ // Gross way of unwrapping the Activity so we can get the FragmentManager
+ Context context = mContext;
+ while (context instanceof ContextWrapper && !(context instanceof Activity)) {
+ context = ((ContextWrapper) context).getBaseContext();
+ }
+ if (!(context instanceof Activity)) {
+ throw new IllegalStateException("The MediaRouteActionProvider's Context " +
+ "is not an Activity.");
+ }
+
+ return (Activity) context;
+ }
+
public void setExtendedSettingsClickListener(View.OnClickListener listener) {
mExtendedSettingsListener = listener;
if (mView != null) {
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index 385241c..a4eebda 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -17,8 +17,10 @@
package android.app;
import com.android.internal.R;
+import com.android.internal.app.MediaRouteChooserDialogFragment;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
@@ -44,6 +46,7 @@
private int mMinHeight;
private OnClickListener mExtendedSettingsClickListener;
+ private MediaRouteChooserDialogFragment mDialogFragment;
private static final int[] ACTIVATED_STATE_SET = {
R.attr.state_activated
@@ -112,7 +115,7 @@
}
}
} else {
- Log.d(TAG, "TODO: Implement the dialog!");
+ showDialog();
}
return handled;
@@ -263,8 +266,51 @@
}
public void setExtendedSettingsClickListener(OnClickListener listener) {
- // TODO: if dialog is already open, propagate so that it updates live.
mExtendedSettingsClickListener = listener;
+ if (mDialogFragment != null) {
+ mDialogFragment.setExtendedSettingsClickListener(listener);
+ }
+ }
+
+ /**
+ * Asynchronously show the route chooser dialog.
+ * This will attach a {@link DialogFragment} to the containing Activity.
+ */
+ public void showDialog() {
+ final FragmentManager fm = getActivity().getFragmentManager();
+ if (mDialogFragment == null) {
+ // See if one is already attached to this activity.
+ mDialogFragment = (MediaRouteChooserDialogFragment) fm.findFragmentByTag(
+ MediaRouteChooserDialogFragment.FRAGMENT_TAG);
+ }
+ if (mDialogFragment != null) {
+ Log.w(TAG, "showDialog(): Already showing!");
+ return;
+ }
+
+ mDialogFragment = new MediaRouteChooserDialogFragment();
+ mDialogFragment.setExtendedSettingsClickListener(mExtendedSettingsClickListener);
+ mDialogFragment.setLauncherListener(new MediaRouteChooserDialogFragment.LauncherListener() {
+ @Override
+ public void onDetached(MediaRouteChooserDialogFragment detachedFragment) {
+ mDialogFragment = null;
+ }
+ });
+ mDialogFragment.setRouteTypes(mRouteTypes);
+ mDialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG);
+ }
+
+ private Activity getActivity() {
+ // Gross way of unwrapping the Activity so we can get the FragmentManager
+ Context context = getContext();
+ while (context instanceof ContextWrapper && !(context instanceof Activity)) {
+ context = ((ContextWrapper) context).getBaseContext();
+ }
+ if (!(context instanceof Activity)) {
+ throw new IllegalStateException("The MediaRouteButton's Context is not an Activity.");
+ }
+
+ return (Activity) context;
}
private class MediaRouteCallback extends MediaRouter.SimpleCallback {
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/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 611742b..da61e74 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1316,7 +1316,7 @@
case WebViewInputDispatcher.EVENT_TYPE_LONG_PRESS:
HitTestResult hitTest = getHitTestResult();
if (hitTest != null) {
- performLongClick();
+ mWebView.performLongClick();
}
break;
case WebViewInputDispatcher.EVENT_TYPE_DOUBLE_TAP:
@@ -7265,7 +7265,7 @@
// the states
mGotCenterDown = false;
mTrackballDown = false;
- performLongClick();
+ mWebView.performLongClick();
break;
case WEBCORE_NEED_TOUCH_EVENTS:
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
new file mode 100644
index 0000000..000eee7
--- /dev/null
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -0,0 +1,341 @@
+/*
+ * 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.app;
+
+import com.android.internal.R;
+
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.app.MediaRouteActionProvider;
+import android.app.MediaRouteButton;
+import android.content.Context;
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteCategory;
+import android.media.MediaRouter.RouteGroup;
+import android.media.MediaRouter.RouteInfo;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * This class implements the route chooser dialog for {@link MediaRouter}.
+ *
+ * @see MediaRouteButton
+ * @see MediaRouteActionProvider
+ */
+public class MediaRouteChooserDialogFragment extends DialogFragment {
+ private static final String TAG = "MediaRouteChooserDialogFragment";
+ public static final String FRAGMENT_TAG = "android:MediaRouteChooserDialogFragment";
+
+ MediaRouter mRouter;
+ private int mRouteTypes;
+
+ private LauncherListener mLauncherListener;
+ private View.OnClickListener mExtendedSettingsListener;
+ private RouteAdapter mAdapter;
+ private ListView mListView;
+
+ public MediaRouteChooserDialogFragment() {
+ setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog);
+ }
+
+ public void setLauncherListener(LauncherListener listener) {
+ mLauncherListener = listener;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ if (mLauncherListener != null) {
+ mLauncherListener.onDetached(this);
+ }
+ if (mAdapter != null) {
+ mRouter.removeCallback(mAdapter);
+ mAdapter = null;
+ }
+ mRouter = null;
+ }
+
+ /**
+ * Implemented by the MediaRouteButton that launched this dialog
+ */
+ public interface LauncherListener {
+ public void onDetached(MediaRouteChooserDialogFragment detachedFragment);
+ }
+
+ public void setExtendedSettingsClickListener(View.OnClickListener listener) {
+ mExtendedSettingsListener = listener;
+ }
+
+ public void setRouteTypes(int types) {
+ mRouteTypes = types;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false);
+ final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
+
+ if (mExtendedSettingsListener != null) {
+ extendedSettingsButton.setVisibility(View.VISIBLE);
+ extendedSettingsButton.setOnClickListener(mExtendedSettingsListener);
+ }
+
+ final ListView list = (ListView) layout.findViewById(R.id.list);
+ list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ list.setAdapter(mAdapter = new RouteAdapter(inflater));
+ list.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
+ list.setOnItemClickListener(mAdapter);
+
+ mListView = list;
+ mRouter.addCallback(mRouteTypes, mAdapter);
+
+ 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
+ };
+
+ private class RouteAdapter extends BaseAdapter implements MediaRouter.Callback,
+ ListView.OnItemClickListener {
+ private static final int VIEW_TOP_HEADER = 0;
+ private static final int VIEW_SECTION_HEADER = 1;
+ private static final int VIEW_ROUTE = 2;
+
+ private int mSelectedItemPosition;
+ private final ArrayList<Object> mItems = new ArrayList<Object>();
+ private final LayoutInflater mInflater;
+
+ RouteAdapter(LayoutInflater inflater) {
+ mInflater = inflater;
+ update();
+ }
+
+ void update() {
+ // TODO this is kind of naive, but our data sets are going to be
+ // fairly small on average.
+ mItems.clear();
+
+ final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes);
+
+ final ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
+ final int catCount = mRouter.getCategoryCount();
+ for (int i = 0; i < catCount; i++) {
+ final RouteCategory cat = mRouter.getCategoryAt(i);
+ cat.getRoutes(routes);
+
+ mItems.add(cat);
+
+ final int routeCount = routes.size();
+ for (int j = 0; j < routeCount; j++) {
+ final RouteInfo info = routes.get(j);
+ if (info == selectedRoute) {
+ mSelectedItemPosition = mItems.size();
+ }
+ mItems.add(info);
+ }
+ }
+
+ notifyDataSetChanged();
+ if (mListView != null) {
+ mListView.setItemChecked(mSelectedItemPosition, true);
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 3;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ final Object item = getItem(position);
+ if (item instanceof RouteCategory) {
+ return position == 0 ? VIEW_TOP_HEADER : VIEW_SECTION_HEADER;
+ } else {
+ return VIEW_ROUTE;
+ }
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return getItemViewType(position) == VIEW_ROUTE;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final int viewType = getItemViewType(position);
+
+ ViewHolder holder;
+ if (convertView == null) {
+ convertView = mInflater.inflate(ITEM_LAYOUTS[viewType], parent, false);
+ holder = new ViewHolder();
+ holder.text1 = (TextView) convertView.findViewById(R.id.text1);
+ holder.text2 = (TextView) convertView.findViewById(R.id.text2);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ if (viewType == VIEW_ROUTE) {
+ bindItemView(position, holder);
+ } else {
+ bindHeaderView(position, holder);
+ }
+
+ return convertView;
+ }
+
+ void bindItemView(int position, ViewHolder holder) {
+ RouteInfo info = (RouteInfo) mItems.get(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) {
+ RouteCategory cat = (RouteCategory) mItems.get(position);
+ holder.text1.setText(cat.getName());
+ }
+
+ public int getSelectedRoutePosition() {
+ return mSelectedItemPosition;
+ }
+
+ @Override
+ public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+ update();
+ }
+
+ @Override
+ public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+ update();
+ }
+
+ @Override
+ public void onRouteAdded(MediaRouter router, RouteInfo info) {
+ update();
+ }
+
+ @Override
+ public void onRouteRemoved(MediaRouter router, RouteInfo info) {
+ update();
+ }
+
+ @Override
+ public void onRouteChanged(MediaRouter router, RouteInfo info) {
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onRouteGrouped(MediaRouter router, RouteInfo info,
+ RouteGroup group, int index) {
+ update();
+ }
+
+ @Override
+ public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
+ update();
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ ListView lv = (ListView) parent;
+ final Object item = getItem(lv.getCheckedItemPosition());
+ if (!(item instanceof RouteInfo)) {
+ // Oops. Stale event running around? Skip it.
+ return;
+ }
+ mRouter.selectRoute(mRouteTypes, (RouteInfo) item);
+ dismiss();
+ }
+ }
+
+ private static class ViewHolder {
+ public TextView text1;
+ public TextView text2;
+ }
+
+ private class GroupAdapter extends BaseAdapter {
+ @Override
+ public int getCount() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+}
diff --git a/core/res/res/layout/media_route_chooser_layout.xml b/core/res/res/layout/media_route_chooser_layout.xml
new file mode 100644
index 0000000..320d6de
--- /dev/null
+++ b/core/res/res/layout/media_route_chooser_layout.xml
@@ -0,0 +1,54 @@
+<?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="wrap_content"
+ android:orientation="vertical"
+ android:showDividers="middle"
+ android:divider="?android:attr/dividerHorizontal">
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical"
+ android:padding="8dp">
+ <ImageView android:id="@+id/volume_icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:src="@android:drawable/ic_audio_vol"
+ android:gravity="center"
+ android:scaleType="center" />
+ <SeekBar android:id="@+id/volume_slider"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp" />
+ <ImageButton android:id="@+id/extended_settings"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="@android:drawable/ic_sysbar_quicksettings"
+ android:visibility="gone" />
+ </LinearLayout>
+ <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
new file mode 100644
index 0000000..d457c6c
--- /dev/null
+++ b/core/res/res/layout/media_route_list_item.xml
@@ -0,0 +1,56 @@
+<?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/listPreferredItemHeight"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ 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:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView android:id="@android:id/text2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ 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" />
+
+</LinearLayout>
diff --git a/core/res/res/layout/media_route_list_item_section_header.xml b/core/res/res/layout/media_route_list_item_section_header.xml
new file mode 100644
index 0000000..04bd0ea
--- /dev/null
+++ b/core/res/res/layout/media_route_list_item_section_header.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp">
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:background="#19ffffff"
+ android:textStyle="bold"
+ android:textAllCaps="true"
+ android:gravity="center_vertical"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="24dp"
+ />
+</FrameLayout>
diff --git a/core/res/res/layout/media_route_list_item_top_header.xml b/core/res/res/layout/media_route_list_item_top_header.xml
new file mode 100644
index 0000000..75decd3
--- /dev/null
+++ b/core/res/res/layout/media_route_list_item_top_header.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:background="#19ffffff"
+ android:textStyle="bold"
+ android:textAllCaps="true"
+ android:gravity="center_vertical"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="24dp"
+/>
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/public.xml b/core/res/res/values/public.xml
index e1f15cf..0af8534 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1166,6 +1166,13 @@
<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="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" />
<!-- 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 53914a8..967d700 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3551,24 +3551,26 @@
<string name="activity_resolver_use_once">Just once</string>
<!-- Name of the default audio route for tablets when nothing
- is connected to a headphone or other wired audio output jack. [CHAR LIMIT=25] -->
+ is connected to a headphone or other wired audio output jack. [CHAR LIMIT=50] -->
<string name="default_audio_route_name" product="tablet">Tablet speakers</string>
<!-- Name of the default audio route when nothing is connected to
- a headphone or other wired audio output jack. [CHAR LIMIT=25] -->
+ a headphone or other wired audio output jack. [CHAR LIMIT=50] -->
<string name="default_audio_route_name" product="default">Phone speaker</string>
<!-- Name of the default audio route when wired headphones are
- connected. [CHAR LIMIT=25] -->
+ connected. [CHAR LIMIT=50] -->
<string name="default_audio_route_name_headphones">Headphones</string>
- <!-- Name of the default audio route when an audio dock is connected. [CHAR LIMIT=25] -->
+ <!-- Name of the default audio route when an audio dock is connected. [CHAR LIMIT=50] -->
<string name="default_audio_route_name_dock_speakers">Dock speakers</string>
- <!-- Name of the default audio route when HDMI is connected. [CHAR LIMIT=25] -->
+ <!-- Name of the default audio route when HDMI is connected. [CHAR LIMIT=50] -->
<string name="default_audio_route_name_hdmi">HDMI audio</string>
- <!-- Name of the default audio route category. [CHAR LIMIT=25] -->
+ <!-- Name of the default audio route category. [CHAR LIMIT=50] -->
<string name="default_audio_route_category_name">System</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/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 38fe363..b0657ff 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -581,6 +581,7 @@
*/
public static class UserRouteInfo extends RouteInfo {
RemoteControlClient mRcc;
+ private Object mTag;
UserRouteInfo(RouteCategory category) {
super(category);
@@ -638,6 +639,29 @@
public void setIconResource(int resId) {
setIconDrawable(sStatic.mResources.getDrawable(resId));
}
+
+ /**
+ * Set an application-specific tag object for this route.
+ * The application may use this to store arbitrary data associated with the
+ * route for internal tracking.
+ *
+ * <p>Note that the lifespan of a route may be well past the lifespan of
+ * an Activity or other Context; take care that objects you store here
+ * will not keep more data in memory alive than you intend.</p>
+ *
+ * @param tag Arbitrary, app-specific data for this route to hold for later use
+ */
+ public void setTag(Object tag) {
+ mTag = tag;
+ }
+
+ /**
+ * @return The tag object previously set by the application
+ * @see #setTag(Object)
+ */
+ public Object getTag() {
+ return mTag;
+ }
}
/**
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/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/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index efed0a4..267bf82 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -93,6 +93,7 @@
final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
if (!winAnimator.mLastHidden) {
winAnimator.hide();
+ mService.dispatchWallpaperVisibility(wallpaper, false);
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
}
@@ -292,7 +293,7 @@
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
final boolean changed;
- if (mForceHiding) {
+ if (mForceHiding && !winAnimator.isAnimating()) {
changed = win.hideLw(false, false);
if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
"Now policy hidden: " + win);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b85573f..6d5ae71 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1870,16 +1870,7 @@
// First, make sure the client has the current visibility
// state.
- if (wallpaper.mWallpaperVisible != visible) {
- wallpaper.mWallpaperVisible = visible;
- try {
- if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
- "Setting visibility of wallpaper " + wallpaper
- + ": " + visible);
- wallpaper.mClient.dispatchAppVisibility(visible);
- } catch (RemoteException e) {
- }
- }
+ dispatchWallpaperVisibility(wallpaper, visible);
wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustWallpaper win "
@@ -2089,6 +2080,24 @@
}
}
+ /**
+ * Check wallpaper for visiblity change and notify window if so.
+ * @param wallpaper The wallpaper to test and notify.
+ * @param visible Current visibility.
+ */
+ void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
+ if (wallpaper.mWallpaperVisible != visible) {
+ wallpaper.mWallpaperVisible = visible;
+ try {
+ if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
+ "Updating visibility of wallpaper " + wallpaper
+ + ": " + visible + " Callers=" + Debug.getCallers(2));
+ wallpaper.mClient.dispatchAppVisibility(visible);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
void updateWallpaperVisibilityLocked() {
final boolean visible = isWallpaperVisible(mWallpaperTarget);
final int dw = mAppDisplayWidth;
@@ -2113,16 +2122,7 @@
updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
}
- if (wallpaper.mWallpaperVisible != visible) {
- wallpaper.mWallpaperVisible = visible;
- try {
- if (DEBUG_VISIBILITY || DEBUG_WALLPAPER) Slog.v(TAG,
- "Updating visibility of wallpaper " + wallpaper
- + ": " + visible);
- wallpaper.mClient.dispatchAppVisibility(visible);
- } catch (RemoteException e) {
- }
- }
+ dispatchWallpaperVisibility(wallpaper, visible);
}
}
}
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index bdacb6e..579cbb7 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -1122,6 +1122,9 @@
+ " during relayout");
if (showSurfaceRobustlyLocked()) {
mLastHidden = false;
+ if (w.mIsWallpaper) {
+ mService.dispatchWallpaperVisibility(w, true);
+ }
} else {
w.mOrientationChanging = false;
}