Merge "Run doc-comment-check only for checkbuild."
diff --git a/Android.mk b/Android.mk
index c98373f..0df900d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -429,6 +429,7 @@
-since ./frameworks/base/api/14.txt 14 \
-since ./frameworks/base/api/15.txt 15 \
-since ./frameworks/base/api/16.txt 16 \
+ -since ./frameworks/base/api/17.txt 17 \
-werror -hide 113 \
-overview $(LOCAL_PATH)/core/java/overview.html
@@ -539,7 +540,7 @@
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=4.1
+framework_docs_SDK_VERSION:=4.2
# release version (ie "Release x") (full releases only)
framework_docs_SDK_REL_ID:=1
diff --git a/api/current.txt b/api/current.txt
index 690500b..bdf89e3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11750,6 +11750,7 @@
method public void removeUserRoute(android.media.MediaRouter.UserRouteInfo);
method public void selectRoute(int, android.media.MediaRouter.RouteInfo);
field public static final int ROUTE_TYPE_LIVE_AUDIO = 1; // 0x1
+ field public static final int ROUTE_TYPE_LIVE_VIDEO = 2; // 0x2
field public static final int ROUTE_TYPE_USER = 8388608; // 0x800000
}
@@ -11798,6 +11799,7 @@
method public int getVolume();
method public int getVolumeHandling();
method public int getVolumeMax();
+ method public boolean isEnabled();
method public void requestSetVolume(int);
method public void requestUpdateVolume(int);
method public void setTag(java.lang.Object);
@@ -25060,7 +25062,6 @@
method public boolean isInLayout();
method public boolean isInTouchMode();
method public boolean isLayoutRequested();
- method public boolean isLayoutRtl();
method public boolean isLongClickable();
method public boolean isOpaque();
method protected boolean isPaddingOffsetRequired();
@@ -25702,7 +25703,6 @@
method public int getLayoutDirection();
method public int getMarginEnd();
method public int getMarginStart();
- method protected boolean isLayoutRtl();
method public boolean isMarginRelative();
method public void setLayoutDirection(int);
method public void setMarginEnd(int);
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index cfc8bbd..a9ccef0 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -221,21 +221,28 @@
void updateRouteCount() {
final int N = mRouter.getRouteCount();
int count = 0;
+ boolean hasVideoRoutes = false;
for (int i = 0; i < N; i++) {
final RouteInfo route = mRouter.getRouteAt(i);
- if ((route.getSupportedTypes() & mRouteTypes) != 0) {
+ final int routeTypes = route.getSupportedTypes();
+ if ((routeTypes & mRouteTypes) != 0) {
if (route instanceof RouteGroup) {
count += ((RouteGroup) route).getRouteCount();
} else {
count++;
}
+ if ((routeTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0) {
+ hasVideoRoutes = true;
+ }
}
}
setEnabled(count != 0);
- // Only allow toggling if we have more than just user routes
- mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0;
+ // Only allow toggling if we have more than just user routes.
+ // Don't toggle if we support video routes, we may have to let the dialog scan.
+ mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0 &&
+ !hasVideoRoutes;
}
@Override
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b3ab385..5b49ba3 100755
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -7659,6 +7659,54 @@
public static final int MODE_LARGE = 3;
/**
+ * Constructs the QuickContacts intent with a view's rect.
+ * @hide
+ */
+ public static Intent composeQuickContactsIntent(Context context, View target, Uri lookupUri,
+ int mode, String[] excludeMimes) {
+ // Find location and bounds of target view, adjusting based on the
+ // assumed local density.
+ final float appScale = context.getResources().getCompatibilityInfo().applicationScale;
+ final int[] pos = new int[2];
+ target.getLocationOnScreen(pos);
+
+ final Rect rect = new Rect();
+ rect.left = (int) (pos[0] * appScale + 0.5f);
+ rect.top = (int) (pos[1] * appScale + 0.5f);
+ rect.right = (int) ((pos[0] + target.getWidth()) * appScale + 0.5f);
+ rect.bottom = (int) ((pos[1] + target.getHeight()) * appScale + 0.5f);
+
+ return composeQuickContactsIntent(context, rect, lookupUri, mode, excludeMimes);
+ }
+
+ /**
+ * Constructs the QuickContacts intent.
+ * @hide
+ */
+ public static Intent composeQuickContactsIntent(Context context, Rect target,
+ Uri lookupUri, int mode, String[] excludeMimes) {
+ // When launching from an Activiy, we don't want to start a new task, but otherwise
+ // we *must* start a new task. (Otherwise startActivity() would crash.)
+ Context actualContext = context;
+ while ((actualContext instanceof ContextWrapper)
+ && !(actualContext instanceof Activity)) {
+ actualContext = ((ContextWrapper) actualContext).getBaseContext();
+ }
+ final int intentFlags = (actualContext instanceof Activity)
+ ? Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
+ : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK;
+
+ // Launch pivot dialog through intent for now
+ final Intent intent = new Intent(ACTION_QUICK_CONTACT).addFlags(intentFlags);
+
+ intent.setData(lookupUri);
+ intent.setSourceBounds(target);
+ intent.putExtra(EXTRA_MODE, mode);
+ intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes);
+ return intent;
+ }
+
+ /**
* Trigger a dialog that lists the various methods of interacting with
* the requested {@link Contacts} entry. This may be based on available
* {@link ContactsContract.Data} rows under that contact, and may also
@@ -7683,20 +7731,10 @@
*/
public static void showQuickContact(Context context, View target, Uri lookupUri, int mode,
String[] excludeMimes) {
- // Find location and bounds of target view, adjusting based on the
- // assumed local density.
- final float appScale = context.getResources().getCompatibilityInfo().applicationScale;
- final int[] pos = new int[2];
- target.getLocationOnScreen(pos);
-
- final Rect rect = new Rect();
- rect.left = (int) (pos[0] * appScale + 0.5f);
- rect.top = (int) (pos[1] * appScale + 0.5f);
- rect.right = (int) ((pos[0] + target.getWidth()) * appScale + 0.5f);
- rect.bottom = (int) ((pos[1] + target.getHeight()) * appScale + 0.5f);
-
// Trigger with obtained rectangle
- showQuickContact(context, rect, lookupUri, mode, excludeMimes);
+ Intent intent = composeQuickContactsIntent(context, target, lookupUri, mode,
+ excludeMimes);
+ context.startActivity(intent);
}
/**
@@ -7727,25 +7765,9 @@
*/
public static void showQuickContact(Context context, Rect target, Uri lookupUri, int mode,
String[] excludeMimes) {
- // When launching from an Activiy, we don't want to start a new task, but otherwise
- // we *must* start a new task. (Otherwise startActivity() would crash.)
- Context actualContext = context;
- while ((actualContext instanceof ContextWrapper)
- && !(actualContext instanceof Activity)) {
- actualContext = ((ContextWrapper) actualContext).getBaseContext();
- }
- final int intentFlags = (actualContext instanceof Activity)
- ? Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
- : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK;
-
- // Launch pivot dialog through intent for now
- final Intent intent = new Intent(ACTION_QUICK_CONTACT).addFlags(intentFlags);
-
- intent.setData(lookupUri);
- intent.setSourceBounds(target);
- intent.putExtra(EXTRA_MODE, mode);
- intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes);
- context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ Intent intent = composeQuickContactsIntent(context, target, lookupUri, mode,
+ excludeMimes);
+ context.startActivity(intent);
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 550713d..8825f58 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3141,6 +3141,12 @@
public static final String DEVICE_PROVISIONED = Global.DEVICE_PROVISIONED;
/**
+ * Whether the current user has been set up via setup wizard (0 = false, 1 = true)
+ * @hide
+ */
+ public static final String USER_SETUP_COMPLETE = "user_setup_complete";
+
+ /**
* List of input methods that are currently enabled. This is a string
* containing the IDs of all enabled input methods, each ID separated
* by ':'.
@@ -4619,13 +4625,6 @@
public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
/**
- * Prefix for SMS short code regex patterns (country code is appended).
- * @see com.android.internal.telephony.SmsUsageMonitor
- * @hide
- */
- public static final String SMS_SHORT_CODES_PREFIX = "sms_short_codes_";
-
- /**
* Used to disable Tethering on a device - defaults to true
* @hide
*/
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index b0a2711..4873860 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.os.SystemClock;
import android.util.FloatMath;
+import android.util.Log;
import java.util.Arrays;
@@ -223,10 +224,14 @@
* @param id pointer id to clear
* @see #addTouchHistory(MotionEvent)
*/
- private void removeTouchHistoryForId(int id) {
+ private boolean removeTouchHistoryForId(int id) {
+ if (id >= mTouchHistoryLastAccepted.length) {
+ return false;
+ }
mTouchHistoryLastAccepted[id] = Float.NaN;
mTouchHistoryDirection[id] = 0;
mTouchHistoryLastAcceptedTime[id] = 0;
+ return true;
}
/**
@@ -236,6 +241,11 @@
* @see #addTouchHistory(MotionEvent)
*/
private float getAdjustedTouchHistory(int id) {
+ if (id >= mTouchHistoryLastAccepted.length) {
+ Log.e(TAG, "Error retrieving adjusted touch history for id=" + id +
+ " - incomplete event stream?");
+ return 0;
+ }
return mTouchHistoryLastAccepted[id];
}
@@ -244,6 +254,10 @@
* @see #addTouchHistory(MotionEvent)
*/
private void clearTouchHistory() {
+ if (mTouchHistoryLastAccepted == null) {
+ // All three arrays will be null if this is the case; nothing to do.
+ return;
+ }
Arrays.fill(mTouchHistoryLastAccepted, Float.NaN);
Arrays.fill(mTouchHistoryDirection, 0);
Arrays.fill(mTouchHistoryLastAcceptedTime, 0);
@@ -333,7 +347,11 @@
final float focusY = sumY / div;
if (pointerUp) {
- removeTouchHistoryForId(event.getPointerId(event.getActionIndex()));
+ final int id = event.getPointerId(event.getActionIndex());
+ if (!removeTouchHistoryForId(id)) {
+ Log.e(TAG, "Got ACTION_POINTER_UP for previously unknown id=" + id +
+ " - incomplete event stream?");
+ }
} else {
addTouchHistory(event);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b5bb98a..0e0f9de 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5887,6 +5887,8 @@
* layout attribute and/or the inherited value from the parent
*
* @return true if the layout is right-to-left.
+ *
+ * @hide
*/
@ViewDebug.ExportedProperty(category = "layout")
public boolean isLayoutRtl() {
@@ -11628,9 +11630,11 @@
* Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
* that the parent directionality can and will be resolved before its children.
*
+ * @return true if resolution has been done, false otherwise.
+ *
* @hide
*/
- public void resolveLayoutDirection() {
+ public boolean resolveLayoutDirection() {
// Clear any previous layout direction resolution
mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
@@ -11641,15 +11645,13 @@
case LAYOUT_DIRECTION_INHERIT:
// We cannot resolve yet. LTR is by default and let the resolution happen again
// later to get the correct resolved value
- if (!canResolveLayoutDirection()) return;
+ if (!canResolveLayoutDirection()) return false;
- ViewGroup viewGroup = ((ViewGroup) mParent);
+ View parent = ((View) mParent);
+ // Parent has not yet resolved, LTR is still the default
+ if (!parent.isLayoutDirectionResolved()) return false;
- // We cannot resolve yet on the parent too. LTR is by default and let the
- // resolution happen again later
- if (!viewGroup.canResolveLayoutDirection()) return;
-
- if (viewGroup.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ if (parent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
}
break;
@@ -11669,6 +11671,7 @@
// Set to resolved
mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
+ return true;
}
/**
@@ -11679,10 +11682,10 @@
* @hide
*/
public boolean canResolveLayoutDirection() {
- switch ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >>
- PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) {
+ switch (getRawLayoutDirection()) {
case LAYOUT_DIRECTION_INHERIT:
- return (mParent != null) && (mParent instanceof ViewGroup);
+ return (mParent != null) && (mParent instanceof ViewGroup) &&
+ ((ViewGroup) mParent).canResolveLayoutDirection();
default:
return true;
}
@@ -16697,9 +16700,11 @@
/**
* Resolve the text direction.
*
+ * @return true if resolution has been done, false otherwise.
+ *
* @hide
*/
- public void resolveTextDirection() {
+ public boolean resolveTextDirection() {
// Reset any previous text direction resolution
mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
@@ -16708,29 +16713,35 @@
final int textDirection = getRawTextDirection();
switch(textDirection) {
case TEXT_DIRECTION_INHERIT:
- if (canResolveTextDirection()) {
- ViewGroup viewGroup = ((ViewGroup) mParent);
-
- // Set current resolved direction to the same value as the parent's one
- final int parentResolvedDirection = viewGroup.getTextDirection();
- switch (parentResolvedDirection) {
- case TEXT_DIRECTION_FIRST_STRONG:
- case TEXT_DIRECTION_ANY_RTL:
- case TEXT_DIRECTION_LTR:
- case TEXT_DIRECTION_RTL:
- case TEXT_DIRECTION_LOCALE:
- mPrivateFlags2 |=
- (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
- break;
- default:
- // Default resolved direction is "first strong" heuristic
- mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
- }
- } else {
+ if (!canResolveTextDirection()) {
// We cannot do the resolution if there is no parent, so use the default one
mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
// Resolution will need to happen again later
- return;
+ return false;
+ }
+
+ View parent = ((View) mParent);
+ // Parent has not yet resolved, so we still return the default
+ if (!parent.isTextDirectionResolved()) {
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
+ // Resolution will need to happen again later
+ return false;
+ }
+
+ // Set current resolved direction to the same value as the parent's one
+ final int parentResolvedDirection = parent.getTextDirection();
+ switch (parentResolvedDirection) {
+ case TEXT_DIRECTION_FIRST_STRONG:
+ case TEXT_DIRECTION_ANY_RTL:
+ case TEXT_DIRECTION_LTR:
+ case TEXT_DIRECTION_RTL:
+ case TEXT_DIRECTION_LOCALE:
+ mPrivateFlags2 |=
+ (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+ break;
+ default:
+ // Default resolved direction is "first strong" heuristic
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
}
break;
case TEXT_DIRECTION_FIRST_STRONG:
@@ -16752,6 +16763,7 @@
// Set to resolved
mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
+ return true;
}
/**
@@ -16762,7 +16774,8 @@
private boolean canResolveTextDirection() {
switch (getRawTextDirection()) {
case TEXT_DIRECTION_INHERIT:
- return (mParent != null) && (mParent instanceof ViewGroup);
+ return (mParent != null) && (mParent instanceof View) &&
+ ((View) mParent).canResolveTextDirection();
default:
return true;
}
@@ -16892,9 +16905,11 @@
/**
* Resolve the text alignment.
*
+ * @return true if resolution has been done, false otherwise.
+ *
* @hide
*/
- public void resolveTextAlignment() {
+ public boolean resolveTextAlignment() {
// Reset any previous text alignment resolution
mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
@@ -16904,32 +16919,37 @@
switch (textAlignment) {
case TEXT_ALIGNMENT_INHERIT:
// Check if we can resolve the text alignment
- if (canResolveTextAlignment() && mParent instanceof View) {
- View view = (View) mParent;
-
- final int parentResolvedTextAlignment = view.getTextAlignment();
- switch (parentResolvedTextAlignment) {
- case TEXT_ALIGNMENT_GRAVITY:
- case TEXT_ALIGNMENT_TEXT_START:
- case TEXT_ALIGNMENT_TEXT_END:
- case TEXT_ALIGNMENT_CENTER:
- case TEXT_ALIGNMENT_VIEW_START:
- case TEXT_ALIGNMENT_VIEW_END:
- // Resolved text alignment is the same as the parent resolved
- // text alignment
- mPrivateFlags2 |=
- (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
- break;
- default:
- // Use default resolved text alignment
- mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
- }
- }
- else {
+ if (!canResolveTextAlignment()) {
// We cannot do the resolution if there is no parent so use the default
mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
// Resolution will need to happen again later
- return;
+ return false;
+ }
+ View parent = (View) mParent;
+
+ // Parent has not yet resolved, so we still return the default
+ if (!parent.isTextAlignmentResolved()) {
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+ // Resolution will need to happen again later
+ return false;
+ }
+
+ final int parentResolvedTextAlignment = parent.getTextAlignment();
+ switch (parentResolvedTextAlignment) {
+ case TEXT_ALIGNMENT_GRAVITY:
+ case TEXT_ALIGNMENT_TEXT_START:
+ case TEXT_ALIGNMENT_TEXT_END:
+ case TEXT_ALIGNMENT_CENTER:
+ case TEXT_ALIGNMENT_VIEW_START:
+ case TEXT_ALIGNMENT_VIEW_END:
+ // Resolved text alignment is the same as the parent resolved
+ // text alignment
+ mPrivateFlags2 |=
+ (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
+ break;
+ default:
+ // Use default resolved text alignment
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
}
break;
case TEXT_ALIGNMENT_GRAVITY:
@@ -16952,6 +16972,7 @@
// Set the resolved
mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
+ return true;
}
/**
@@ -16962,7 +16983,8 @@
private boolean canResolveTextAlignment() {
switch (getRawTextAlignment()) {
case TEXT_DIRECTION_INHERIT:
- return (mParent != null);
+ return (mParent != null) && (mParent instanceof View) &&
+ ((View) mParent).canResolveTextAlignment();
default:
return true;
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 343db86..9af8f2c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3476,6 +3476,11 @@
ai.mKeepScreenOn = lastKeepOn;
}
+ if (child.isLayoutDirectionInherited()) {
+ child.resetResolvedLayoutDirection();
+ child.resolveRtlPropertiesIfNeeded();
+ }
+
onViewAdded(child);
if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) {
@@ -5347,48 +5352,54 @@
* @hide
*/
@Override
- public void resolveLayoutDirection() {
- super.resolveLayoutDirection();
-
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.isLayoutDirectionInherited()) {
- child.resolveLayoutDirection();
+ public boolean resolveLayoutDirection() {
+ final boolean result = super.resolveLayoutDirection();
+ if (result) {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.isLayoutDirectionInherited()) {
+ child.resolveLayoutDirection();
+ }
}
}
+ return result;
}
/**
* @hide
*/
@Override
- public void resolveTextDirection() {
- super.resolveTextDirection();
-
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.isTextDirectionInherited()) {
- child.resolveTextDirection();
+ public boolean resolveTextDirection() {
+ final boolean result = super.resolveTextDirection();
+ if (result) {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.isTextDirectionInherited()) {
+ child.resolveTextDirection();
+ }
}
}
+ return result;
}
/**
* @hide
*/
@Override
- public void resolveTextAlignment() {
- super.resolveTextAlignment();
-
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.isTextAlignmentInherited()) {
- child.resolveTextAlignment();
+ public boolean resolveTextAlignment() {
+ final boolean result = super.resolveTextAlignment();
+ if (result) {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.isTextAlignmentInherited()) {
+ child.resolveTextAlignment();
+ }
}
}
+ return result;
}
/**
@@ -5984,7 +5995,10 @@
}
}
- protected boolean isLayoutRtl() {
+ /**
+ * @hide
+ */
+ public boolean isLayoutRtl() {
return (layoutDirection == View.LAYOUT_DIRECTION_RTL);
}
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index b72b8cb..e0c5bbd 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -182,6 +182,12 @@
*/
private boolean mIsRtl = true;
+ /**
+ * Offset between the center of the selected child view and the center of the Gallery.
+ * Used to reset position correctly during layout.
+ */
+ private int mSelectedCenterOffset;
+
public Gallery(Context context) {
this(context, null);
}
@@ -395,6 +401,14 @@
setSelectionToCenterChild();
+ final View selChild = mSelectedChild;
+ if (selChild != null) {
+ final int childLeft = selChild.getLeft();
+ final int childCenter = selChild.getWidth() / 2;
+ final int galleryCenter = getWidth() / 2;
+ mSelectedCenterOffset = childLeft + childCenter - galleryCenter;
+ }
+
onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
invalidate();
@@ -537,6 +551,7 @@
// We haven't been callbacking during the fling, so do it now
super.selectionChanged();
}
+ mSelectedCenterOffset = 0;
invalidate();
}
@@ -650,7 +665,8 @@
View sel = makeAndAddView(mSelectedPosition, 0, 0, true);
// Put the selected child in the center
- int selectedOffset = childrenLeft + (childrenWidth / 2) - (sel.getWidth() / 2);
+ int selectedOffset = childrenLeft + (childrenWidth / 2) - (sel.getWidth() / 2) +
+ mSelectedCenterOffset;
sel.offsetLeftAndRight(selectedOffset);
fillToGalleryRight();
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 704f6b6..4918e48 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1361,6 +1361,14 @@
// Allow text entry rather than strictly numeric entry.
mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+ // Make sure the min, max, respect the size of the displayed
+ // values. This will take care of the current value as well.
+ if (getMinValue() >= displayedValues.length) {
+ setMinValue(0);
+ }
+ if (getMaxValue() >= displayedValues.length) {
+ setMaxValue(displayedValues.length - 1);
+ }
} else {
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
}
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index f010d7b..386f387 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -25,7 +25,7 @@
import android.app.MediaRouteButton;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
+import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteCategory;
import android.media.MediaRouter.RouteGroup;
@@ -70,6 +70,7 @@
};
MediaRouter mRouter;
+ DisplayManager mDisplayService;
private int mRouteTypes;
private LayoutInflater mInflater;
@@ -97,6 +98,7 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mDisplayService = (DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE);
}
@Override
@@ -119,6 +121,15 @@
public void setRouteTypes(int types) {
mRouteTypes = types;
+ if ((mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0 && mDisplayService == null) {
+ final Context activity = getActivity();
+ if (activity != null) {
+ mDisplayService = (DisplayManager) activity.getSystemService(
+ Context.DISPLAY_SERVICE);
+ }
+ } else {
+ mDisplayService = null;
+ }
}
void updateVolume() {
@@ -194,6 +205,9 @@
@Override
public void onResume() {
super.onResume();
+ if (mDisplayService != null) {
+ mDisplayService.scanWifiDisplays();
+ }
}
private static class ViewHolder {
@@ -253,7 +267,9 @@
final RouteCategory cat = mRouter.getCategoryAt(i);
routes = cat.getRoutes(mCatRouteList);
- mItems.add(cat);
+ if (!cat.isSystem()) {
+ mItems.add(cat);
+ }
if (cat == mCategoryEditingGroups) {
addGroupEditingCategoryRoutes(routes);
@@ -370,6 +386,7 @@
public boolean isEnabled(int position) {
switch (getItemViewType(position)) {
case VIEW_ROUTE:
+ return ((RouteInfo) mItems.get(position)).isEnabled();
case VIEW_GROUPING_ROUTE:
case VIEW_GROUPING_DONE:
return true;
@@ -434,6 +451,7 @@
}
convertView.setActivated(position == mSelectedItemPosition);
+ convertView.setEnabled(isEnabled(position));
return convertView;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8dbaa26..a16f2ae 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2152,6 +2152,12 @@
</intent-filter>
</receiver>
+ <receiver android:name="com.android.server.updates.SmsShortCodesInstallReceiver" >
+ <intent-filter>
+ <action android:name="android.intent.action.UPDATE_SMS_SHORT_CODES" />
+ </intent-filter>
+ </receiver>
+
<receiver android:name="com.android.server.MasterClearReceiver"
android:permission="android.permission.MASTER_CLEAR"
android:priority="100" >
diff --git a/core/res/res/drawable-hdpi/magnified_region_frame.9.png b/core/res/res/drawable-hdpi/magnified_region_frame.9.png
new file mode 100644
index 0000000..29bdc42
--- /dev/null
+++ b/core/res/res/drawable-hdpi/magnified_region_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/magnified_region_frame.9.png b/core/res/res/drawable-mdpi/magnified_region_frame.9.png
new file mode 100644
index 0000000..a61cbea
--- /dev/null
+++ b/core/res/res/drawable-mdpi/magnified_region_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/magnified_region_frame.9.png b/core/res/res/drawable-nodpi/magnified_region_frame.9.png
deleted file mode 100644
index 4cadefb..0000000
--- a/core/res/res/drawable-nodpi/magnified_region_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/magnified_region_frame.9.png b/core/res/res/drawable-xhdpi/magnified_region_frame.9.png
new file mode 100644
index 0000000..424b3d9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/magnified_region_frame.9.png
Binary files differ
diff --git a/core/res/res/layout/media_route_list_item.xml b/core/res/res/layout/media_route_list_item.xml
index 53d813e..423d544 100644
--- a/core/res/res/layout/media_route_list_item.xml
+++ b/core/res/res/layout/media_route_list_item.xml
@@ -24,7 +24,8 @@
android:layout_height="56dp"
android:scaleType="center"
android:id="@+id/icon"
- android:visibility="gone" />
+ android:visibility="gone"
+ android:duplicateParentState="true" />
<LinearLayout android:layout_width="0dp"
android:layout_height="match_parent"
@@ -32,21 +33,24 @@
android:orientation="vertical"
android:gravity="start|center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:duplicateParentState="true">
<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" />
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:duplicateParentState="true" />
<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" />
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:duplicateParentState="true" />
</LinearLayout>
<ImageButton
@@ -56,6 +60,7 @@
android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_media_group_expand"
android:scaleType="center"
- android:visibility="gone" />
+ android:visibility="gone"
+ android:duplicateParentState="true" />
</LinearLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 02aa537..1b56c29 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3768,8 +3768,8 @@
<!-- 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=50] -->
- <string name="default_audio_route_name_hdmi">HDMI audio</string>
+ <!-- Name of the default media route when HDMI is connected. [CHAR LIMIT=50] -->
+ <string name="default_media_route_name_hdmi">HDMI</string>
<!-- Name of the default audio route category. [CHAR LIMIT=50] -->
<string name="default_audio_route_category_name">System</string>
@@ -3783,6 +3783,18 @@
<!-- Content description of a MediaRouteButton for accessibility support -->
<string name="media_route_button_content_description">Media output</string>
+ <!-- Status message for remote routes attempting to scan/determine availability -->
+ <string name="media_route_status_scanning">Scanning...</string>
+
+ <!-- Status message for a remote route attempting to connect -->
+ <string name="media_route_status_connecting">Connecting...</string>
+
+ <!-- Status message for a remote route that is confirmed to be available for connection -->
+ <string name="media_route_status_available">Available</string>
+
+ <!-- Status message for remote routes that are not available for connection right now -->
+ <string name="media_route_status_not_available">Not available</string>
+
<!-- Display manager service -->
<!-- Name of the built-in display. [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ae7e2a8..74da60e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -823,9 +823,13 @@
<java-symbol type="string" name="default_audio_route_name" />
<java-symbol type="string" name="default_audio_route_name_headphones" />
<java-symbol type="string" name="default_audio_route_name_dock_speakers" />
- <java-symbol type="string" name="default_audio_route_name_hdmi" />
+ <java-symbol type="string" name="default_media_route_name_hdmi" />
<java-symbol type="string" name="default_audio_route_category_name" />
<java-symbol type="string" name="safe_media_volume_warning" />
+ <java-symbol type="string" name="media_route_status_scanning" />
+ <java-symbol type="string" name="media_route_status_connecting" />
+ <java-symbol type="string" name="media_route_status_available" />
+ <java-symbol type="string" name="media_route_status_not_available" />
<java-symbol type="plurals" name="abbrev_in_num_days" />
<java-symbol type="plurals" name="abbrev_in_num_hours" />
@@ -1088,7 +1092,6 @@
<java-symbol type="xml" name="kg_password_kbd_numeric" />
<java-symbol type="xml" name="power_profile" />
<java-symbol type="xml" name="time_zones_by_country" />
- <java-symbol type="xml" name="sms_short_codes" />
<java-symbol type="raw" name="accessibility_gestures" />
<java-symbol type="raw" name="incognito_mode_start_page" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
deleted file mode 100644
index 8b395af..0000000
--- a/core/res/res/xml/sms_short_codes.xml
+++ /dev/null
@@ -1,189 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<!-- Regex patterns for SMS short codes by country. -->
-<shortcodes>
-
- <!-- The country attribute is the ISO country code of the user's account (from SIM card or NV).
- The pattern attribute is a regex that matches all SMS short codes for the country.
- The premium attribute is a regex that matches premium rate SMS short codes.
- The free attribute matches short codes that we know will not cost the user, such as
- emergency numbers. The standard attribute matches short codes that are billed at the
- standard SMS rate. The user is warned when the destination phone number matches the
- "pattern" or "premium" regexes, and does not match the "free" or "standard" regexes. -->
-
- <!-- Harmonised European Short Codes are 6 digit numbers starting with 116 (free helplines).
- Premium patterns include short codes from: http://aonebill.com/coverage&tariffs
- and http://mobilcent.com/info-worldwide.asp and extracted from:
- http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
-
- <!-- Albania: 5 digits, known short codes listed -->
- <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
-
- <!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
- <shortcode country="am" pattern="\\d{3,4}" premium="11[2456]1|3024" free="10[123]" />
-
- <!-- Austria: 10 digits, premium prefix 09xx, plus EU -->
- <shortcode country="at" pattern="11\\d{4}" premium="09.*" free="116\\d{3}" />
-
- <!-- Australia: 6 or 8 digits starting with "19" -->
- <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882" />
-
- <!-- Azerbaijan: 4-5 digits, known premium codes listed -->
- <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" />
-
- <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
- <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
-
- <!-- Bulgaria: 4-5 digits, plus EU -->
- <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}" />
-
- <!-- Belarus: 4 digits -->
- <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
-
- <!-- Canada: 5-6 digits -->
- <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188" />
-
- <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
- <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111" />
-
- <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
- http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
- <shortcode country="cn" premium="1066.*" free="1065.*" />
-
- <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
- <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
-
- <!-- Czech Republic: 7-8 digits, starting with 9, plus EU:
- http://www.o2.cz/osobni/en/services-by-alphabet/91670-premium_sms.html -->
- <shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
-
- <!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
- <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}" />
-
- <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
- <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
-
- <!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU.
- http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
- <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}" />
-
- <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
- http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
- <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}" />
-
- <!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
- <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
-
- <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
- http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements -->
- <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" />
-
- <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
- http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf -->
- <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" />
-
- <!-- Georgia: 4 digits, known premium codes listed -->
- <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
-
- <!-- Greece: 5 digits (54xxx, 19yxx, x=0-9, y=0-5): http://www.cmtelecom.com/premium-sms/greece -->
- <shortcode country="gr" pattern="\\d{5}" premium="54\\d{3}|19[0-5]\\d{2}" free="116\\d{3}" />
-
- <!-- Hungary: 4 or 10 digits starting with 1 or 0, plus EU:
- http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations -->
- <shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" />
-
- <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
- http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
- <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" />
-
- <!-- Israel: 4 digits, known premium codes listed -->
- <shortcode country="il" pattern="\\d{4}" premium="4422|4545" />
-
- <!-- Italy: 5 digits (premium=4xxxx), plus EU:
- http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
- <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
-
- <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
- <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
-
- <!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
- <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
-
- <!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
- <shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}" />
-
- <!-- Luxembourg: 5 digits, 6xxxx, plus EU:
- http://www.luxgsm.lu/assets/files/filepage/file_1253803400.pdf -->
- <shortcode country="lu" premium="6\\d{4}" free="116\\d{3}" />
-
- <!-- Latvia: 4 digits, known premium codes listed, plus EU -->
- <shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}" />
-
- <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" />
-
- <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
- <shortcode country="my" pattern="\\d{5}" premium="32298|33776" />
-
- <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
- <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}" />
-
- <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
-
- <!-- New Zealand: 3-4 digits, known premium codes listed -->
- <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995" />
-
- <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
- <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}" />
-
- <!-- Portugal: 5 digits, plus EU:
- http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
- <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}" />
-
- <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
- <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}" />
-
- <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
- <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)" />
-
- <!-- Sweden: 5 digits (72xxx), plus EU: http://www.viatel.se/en/premium-sms/ -->
- <shortcode country="se" premium="72\\d{3}" free="116\\d{3}" />
-
- <!-- Singapore: 5 digits: http://clients.txtnation.com/entries/306442-singapore-premium-sms-short-code-requirements
- Free government directory info at 74688: http://app.sgdi.gov.sg/sms_help.asp -->
- <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688" />
-
- <!-- Slovenia: 4 digits (premium=3xxx, 6xxx, 8xxx), plus EU: http://www.cmtelecom.com/premium-sms/slovenia -->
- <shortcode country="si" pattern="\\d{4}" premium="[368]\\d{3}" free="116\\d{3}" />
-
- <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia -->
- <shortcode country="sk" premium="\\d{4}" free="116\\d{3}" />
-
- <!-- Tajikistan: 4 digits, known premium codes listed -->
- <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
-
- <!-- Ukraine: 4 digits, known premium codes listed -->
- <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
-
- <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
- <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" />
-
-</shortcodes>
diff --git a/docs/html/distribute/distribute_toc.cs b/docs/html/distribute/distribute_toc.cs
index 76073fb..84103b9 100644
--- a/docs/html/distribute/distribute_toc.cs
+++ b/docs/html/distribute/distribute_toc.cs
@@ -75,7 +75,7 @@
<li><a href="<?cs var:toroot ?>distribute/promote/device-art.html">
<span class="en">Device Art Generator</a></li>
<li><a href="<?cs var:toroot ?>distribute/googleplay/promote/brand.html">
- <span class="en">Brand Assets and Guidelines</a></li>
+ <span class="en">Brand Guidelines</a></li>
</ul>
</li>
diff --git a/docs/html/distribute/googleplay/promote/badges.jd b/docs/html/distribute/googleplay/promote/badges.jd
index 7b64be3..d6f15fb 100644
--- a/docs/html/distribute/googleplay/promote/badges.jd
+++ b/docs/html/distribute/googleplay/promote/badges.jd
@@ -13,7 +13,7 @@
wraps your screenshots in real device artwork.</p>
<p>For guidelines when using the Google Play badge and other brand assets,
-see the <a href="{@docRoot}distribute/googleplay/promote/brand.html">Brand Assets and
+see the <a href="{@docRoot}distribute/googleplay/promote/brand.html">Brand
Guidelines</a>.</p>
<style type="text/css">
diff --git a/docs/html/distribute/googleplay/promote/brand.jd b/docs/html/distribute/googleplay/promote/brand.jd
index 4051553..875794a 100644
--- a/docs/html/distribute/googleplay/promote/brand.jd
+++ b/docs/html/distribute/googleplay/promote/brand.jd
@@ -1,151 +1,172 @@
-page.title=Brand Assets, Icons, and Guidelines
+page.title=Brand Guidelines
@jd:body
-<p>We encourage you to use the Android and Google Play brands in your
-promotional materials. You can use the icons and other assets on this page in
-any way you want, provided that you follow the guidelines described below.</p>
-<h2 id="brand-android">Android Brand</h2>
-<div>
- <div style="float:right;width:50%;padding:1.5em;">
- <img alt="" src="{@docRoot}images/brand/droid.gif">
+<p>We encourage you to use the Android and Google Play brands with your Android app
+promotional materials. You can use the icons and other assets on this page
+provided that you follow the guidelines described below.</p>
+
+<h2 id="brand-android">Android</h2>
+
+ <p>The following are guidelines for the Android brand
+ and related assets.</p>
+
+
+ <h4 style="clear:right">Android in text</h4>
+
+ <div style="float:right;clear:right;width:200px;margin:0 0 20px 30px">
+ <img alt="" src="{@docRoot}images/brand/mediaplayer.png">
+ </div>
+ <ul>
+ <li>Android™ should have a trademark symbol the first time it appears in a creative.</li>
+ <li>Android should always be capitalized and is never plural or possessive.</li>
+ <li>"Android" by itself cannot be used in the name of an application name or accessory product.
+Instead use "for Android."
+ <ul>
+ <li><span style="color:red">Incorrect</span>: "Android MediaPlayer"</li>
+ <li><span style="color:green">Correct</span>: "MediaPlayer for Android"</li>
+ </ul>
+ <p>If used with your logo, "for Android" needs to be smaller in size than your logo.
+ First instance of this use should be followed by a TM symbol, "for Android™".</p>
+ </li>
+ <li>Android may be used as a descriptor, as long as it is followed by a proper generic term.
+ <ul>
+ <li><span style="color:red">Incorrect</span>: "Android MediaPlayer" or "Android XYZ app"</li>
+ <li><span style="color:green">Correct</span>: "Android features" or "Android applications"</li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>Any use of the Android name needs to include this
+ attribution in your communication:</p>
+ <blockquote><em>Android is a trademark of Google Inc.</em></blockquote></p>
+
+
+ <h4>Android robot</h4>
+
+ <div style="float:right;width:200px;margin-left:30px">
+ <img alt="" src="{@docRoot}images/brand/Android_Robot_100.png"
+ style="margin-left:50px">
+ <p style="text-align:center">
+ <a href="{@docRoot}images/brand/Android_Robot_100.png">100x118</a> |
+ <a href="{@docRoot}images/brand/Android_Robot_200.png">200x237</a><br>
+ <a href="{@docRoot}images/brand/Android_Robot_outlined.ai">Illustrator (.ai)</a></p>
</div>
- <div style="width:45%;">
- <h4>01/ Android Robot</h4>
-
- <p> Can be used, reproduced, and modified freely in marketing
- communications. Our standard color value for print is PMS 376C. Our online hex
- color is <span id= "android-green">#A4C639</span>.</p>
+ <p>The Android robot can be used, reproduced, and modified freely in marketing
+ communications. The color value for print is PMS 376C and the online hex
+ color is <span style="color:#A4C639">#A4C639</span>.</p>
<p>When using the Android Robot or any modification of it, proper attribution is
- required under the terms of the Creative Commons Attribution license. For more
- details on proper attribution, please see the <a
- href="{@docRoot}license.html#attribution">Content License</a> document. </p>
+ required under the terms of the <a href="http://creativecommons.org/licenses/by/3.0/">Creative
+Commons Attribution</a> license:</p>
+
+ <blockquote><em>The Android robot is reproduced or modified from work created and shared by Google and
+used according to terms described in the Creative Commons 3.0 Attribution License.</em></blockquote>
+
+ <p>You may not file trademark applications incorporating the Android robot logo or
+derivatives thereof. We want to ensure that the Android robot remains available
+for all to use.</p>
+
+
+<h4 style="clear:right">Android logo</h4>
+
+<div style="float:right;width:210px;margin-left:30px;margin-top:-10px">
+ <img alt="" src="{@docRoot}images/brand/android_logo_no.png">
+</div>
+
+<p>The Android logo may not be used. Nor can this be used with the Android robot.</p>
+<p>The custom typeface may not be used.</p>
+
+
+
+
+<h2 id="brand-google_play">Google Play</h2>
+
+
+ <p>The following are guidelines for the Google Play brand
+ and related assets.</p>
+
+<h4>Google Play in text</h4>
+
+<p>Always include a TM symbol on the first or most prominent instance of Google Play™
+in text.</p>
+
+<p>When referring to the mobile experience, use "Google Play" unless the text is clearly
+instructional for the user. For example, a marketing headline might read "Download our
+games on Google Play™," but instructional text woud read "Download our games using the Google
+Play™ Store app."
+
+ <p>Any use of the Google Play name or icon needs to include this
+ attribution in your communication:</p>
+
+<blockquote><em>Google Play is a trademark of Google Inc.</em></blockquote>
+
+
+ <div style="float:right;width:96px;margin-left:30px;margin-top:-20px">
+ <img src="{@docRoot}images/brand/Google_Play_Store_96.png" alt="">
+ <p style="text-align:center">
+ <a href="{@docRoot}images/brand/Google_Play_Store_48.png">48x48</a> |
+ <a href="{@docRoot}images/brand/Google_Play_Store_96.png">96x96</a><br>
+ <a href="{@docRoot}images/brand/Google_Play_Store.ai">Illustrator (.ai)</a>
+ </p>
</div>
-<div>
+
+<h4>Google Play Store icon</h4>
-<div style="clear:both">
- <div style="float:right;width:50%;padding:1.5em;">
- <img alt="" src="{@docRoot}images/brand/logo_android.gif">
- </div>
+<p>You may use the Google Play Store icon, but you may not modify it.</p>
- <div style="width:45%;">
- <h4>02/ Android Logo</h4>
+<p>When labeling or referring to the icon, the name can be either the full app
+name, Google Play Store, or the app display name, Play Store.</p>
- <p>The Android logo may not be used.</p>
- </div>
-<div>
-
-<div style="clear:both">
- <div style="float:right;width:50%;padding:1.5em;">
- <img alt="" src="{@docRoot}images/brand/norad.gif">
- </div>
-
- <div style="width:45%;">
- <h4>03/ Android Custom Typeface</h4>
-
- <p>The custom typeface may not be used.</p>
- </div>
-<div>
-
-<div style="clear:both">
- <div style="float:right;width:50%;padding:1.5em;">
- <img alt="" src="{@docRoot}images/brand/mediaplayer.gif">
- </div>
-
- <div style="width:45%;">
- <h4>04/ Android in Official Names</h4>
-<p>Any name with 'Android' alone may not be used in a name without permission. Any name
- with 'Droid' alone may not be used in a name.</p>
-
- <p>The word 'Android' may be used only as a descriptor, 'for Android'. If used with your
- logo, 'for Android' needs to be smaller in size than your logo. First instance of this
- use should be followed by a TM symbol, 'for Android™'.</p>
-
- <p>If you are not sure you meet these criteria, <a href=
- "http://services.google.com/permissions/application">please contact us</a>. </p>
- </div>
-<div>
-
-<div style="clear:both">
- <div style="float:right;width:50%;padding:1.5em;">
- <img alt="" src="{@docRoot}images/brand/learnmore.gif">
- </div>
-
- <div style="width:45%;">
- <h4>05/ Android in Messaging</h4>
- <p>
- May be used in text as a descriptor, as long as it is followed by a proper generic term
- (e.g. "Android™ application"). First instance of this use should be followed by a TM
- symbol.
- </p>
- </div>
-<div>
- <p class="caution"><strong>Note: Any usage of #04 or #05 needs to include footer attribution in your
- communication:</strong><br /><span style="margin-left:1.5em">
- "Android is a trademark of Google Inc."</span>
- </p>
-
-
-<h2 id="brand-google_play">Google Play Brand</h2>
-
- <img alt="" src="http://www.android.com/images/brand/google_play_logo_450.png"
- style="float:right;">
-
- <img alt="Android app on Google Play badge, large"
- src="{@docRoot}images/brand/en_app_rgb_wo_60.png"
- style="float:right;clear:right;">
-
- <img alt="Android app on Google Play badge, small"
- src="{@docRoot}images/brand/en_app_rgb_wo_45.png"
- style="float:right;margin:0 30px 30px">
-
- <img alt="Get it on Google Play badge, large"
- src="{@docRoot}images/brand/en_generic_rgb_wo_60.png"
- style="float:right;clear:right;">
-
- <img alt="Get it on Google Play badge, small"
- src="{@docRoot}images/brand/en_generic_rgb_wo_45.png"
- style="float:right;margin:0 30px 30px;">
- <h4>06/ <em>Get it on Google Play</em> Badge
- </h4>
- <p>
- The "Get it on Google Play" and "Android App on Google Play" logos are badges that you
- can use on your web site and promotional materials, to point to your products on Google
- Play.
- </p>
- <p>
- Guidelines for usage:
- </p>
- <ul>
- <li>Do not modify the color, proportions, spacing or any other aspect of the badge image.
- </li>
- <li>When used alongside logos for other application marketplaces, the Google Play logo
- should be of equal or greater size.</li>
- <li>When used online, the badge should link to either:
- <ul>
- <li>A list of products published by you, for example:<br />
- <span style="margin-left:1em;">http://play.google.com/store/search?q=<em>publisherName</em></span>
- </li>
- <li>A specific app product details page within Google Play, for example:<br />
- <span style="margin-left:1em;">http://play.google.com/store/apps/details?id=<em>packageName</em></span>
- </li>
- </ul>
- </li>
+<h4>Google Play badge</h4>
+
+ <div style="float:right;clear:right;width:172px;margin-left:30px">
+ <img src="{@docRoot}images/brand/en_app_rgb_wo_60.png" alt="">
+ <p style="text-align:center">
+ <a href="{@docRoot}images/brand/en_app_rgb_wo_45.png">129x45</a> |
+ <a href="{@docRoot}images/brand/en_app_rgb_wo_60.png">172x60</a><br>
+ <a href="{@docRoot}images/brand/en_app_rgb_wo.ai">Illustrator (.ai)</a></p>
+ </div>
+
+ <div style="float:right;clear:right;width:172px;margin-left:30px">
+ <img src="{@docRoot}images/brand/en_generic_rgb_wo_60.png" alt="">
+ <p style="text-align:center">
+ <a href="{@docRoot}images/brand/en_generic_rgb_wo_45.png">129x45</a> |
+ <a href="{@docRoot}images/brand/en_generic_rgb_wo_60.png">172x60</a><br>
+ <a href="{@docRoot}images/brand/en_generic_rgb_wo.ai">Illustrator (.ai)</a></p>
+ </div>
+
+ <p>The "Get it on Google Play" and "Android App on Google Play" logos are badges that you
+ can use on your web site and promotional materials, to point to your products on Google
+ Play.</p>
+
+ <ul>
+ <li>Do not modify the color, proportions, spacing or any other aspect of the badge image.
+ </li>
+ <li>When used alongside logos for other application marketplaces, the Google Play logo
+ should be of equal or greater size.</li>
+ <li>When used online, the badge should link to either:
+ <ul>
+ <li>A list of products published by you, for example:<br />
+ <span style="margin-left:1em;">http://play.google.com/store/search?q=<em>publisherName</em></span>
+ </li>
+ <li>A specific app product details page within Google Play, for example:<br />
+ <span style="margin-left:1em;">http://play.google.com/store/apps/details?id=<em>packageName</em></span>
+ </li>
+ </ul>
+ </li>
</ul>
- <p>For your convenience, you can use the
- <a href="{@docRoot}distribute/googleplay/promote/badges.html">Googe Play badge generator</a>
- to create badges that link to your apps on Google Play.</p>
-
- <p>For details on all the ways that you can link to your product details page in Google Play,
- see <a href="{@docRoot}distribute/googleplay/promote/linking.html">Linking to your products</a></p>
+ <p>For your convenience, you can use the
+ <a href="{@docRoot}distribute/googleplay/promote/badges.html">Googe Play badge generator</a>
+ to create badges that link to your apps on Google Play.</p>
+
+ <p>For details on all the ways that you can link to your product details page in Google Play,
+ see <a href="{@docRoot}distribute/googleplay/promote/linking.html">Linking to your products</a></p>
-<h2>Other Brands</h2>
-<p>Any other brands or icons depicted on this site are <em>not</em> are the property of their
-respective owners and usage is reserved. You must seek the developer for appropriate permission to use them.</p>
-
+<p>If you are not sure you meet these criteria, <a href=
+ "http://services.google.com/permissions/application">please contact us</a>. </p>
diff --git a/docs/html/distribute/googleplay/promote/linking.jd b/docs/html/distribute/googleplay/promote/linking.jd
index 4a1b198..2d3bd05 100644
--- a/docs/html/distribute/googleplay/promote/linking.jd
+++ b/docs/html/distribute/googleplay/promote/linking.jd
@@ -5,7 +5,7 @@
<div class="sidebox">
<a href="badges.html">
<img alt="Get it on Google Play"
- src="http://www.android.com/images/brand/get_it_on_play_logo_small.png" />
+ src="{@docRoot}en_app_rgb_wo_45.png" />
</a>
<p>For a link that includes the Google Play brand icon, check out the <a href="badges.html">Badges</a> page. </p>
</div>
diff --git a/docs/html/images/brand/Android_Robot_100.png b/docs/html/images/brand/Android_Robot_100.png
new file mode 100644
index 0000000..946ee3a
--- /dev/null
+++ b/docs/html/images/brand/Android_Robot_100.png
Binary files differ
diff --git a/docs/html/images/brand/Android_Robot_200.png b/docs/html/images/brand/Android_Robot_200.png
new file mode 100644
index 0000000..40bf934
--- /dev/null
+++ b/docs/html/images/brand/Android_Robot_200.png
Binary files differ
diff --git a/docs/html/images/brand/Android_Robot_500.png b/docs/html/images/brand/Android_Robot_500.png
new file mode 100644
index 0000000..1fbfc51
--- /dev/null
+++ b/docs/html/images/brand/Android_Robot_500.png
Binary files differ
diff --git a/docs/html/images/brand/Android_Robot_outlined.ai b/docs/html/images/brand/Android_Robot_outlined.ai
new file mode 100644
index 0000000..9105cba
--- /dev/null
+++ b/docs/html/images/brand/Android_Robot_outlined.ai
Binary files differ
diff --git a/docs/html/images/brand/Google_Play_Store.ai b/docs/html/images/brand/Google_Play_Store.ai
new file mode 100644
index 0000000..51f07c6
--- /dev/null
+++ b/docs/html/images/brand/Google_Play_Store.ai
Binary files differ
diff --git a/docs/html/images/brand/Google_Play_Store_48.png b/docs/html/images/brand/Google_Play_Store_48.png
new file mode 100644
index 0000000..2f0cfe0
--- /dev/null
+++ b/docs/html/images/brand/Google_Play_Store_48.png
Binary files differ
diff --git a/docs/html/images/brand/Google_Play_Store_96.png b/docs/html/images/brand/Google_Play_Store_96.png
new file mode 100644
index 0000000..6e2c835
--- /dev/null
+++ b/docs/html/images/brand/Google_Play_Store_96.png
Binary files differ
diff --git a/docs/html/images/brand/android_logo_no.png b/docs/html/images/brand/android_logo_no.png
new file mode 100644
index 0000000..8de22d8
--- /dev/null
+++ b/docs/html/images/brand/android_logo_no.png
Binary files differ
diff --git a/docs/html/images/brand/droid.gif b/docs/html/images/brand/droid.gif
deleted file mode 100644
index 7c7b941..0000000
--- a/docs/html/images/brand/droid.gif
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/brand/en_app_rgb_wo.ai b/docs/html/images/brand/en_app_rgb_wo.ai
new file mode 100644
index 0000000..db27314
--- /dev/null
+++ b/docs/html/images/brand/en_app_rgb_wo.ai
Binary files differ
diff --git a/docs/html/images/brand/en_generic_rgb_wo.ai b/docs/html/images/brand/en_generic_rgb_wo.ai
new file mode 100644
index 0000000..57c1e47
--- /dev/null
+++ b/docs/html/images/brand/en_generic_rgb_wo.ai
Binary files differ
diff --git a/docs/html/images/brand/google_play_logo_450.png b/docs/html/images/brand/google_play_logo_450.png
deleted file mode 100644
index 59a1fcf..0000000
--- a/docs/html/images/brand/google_play_logo_450.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/brand/learnmore.gif b/docs/html/images/brand/learnmore.gif
deleted file mode 100644
index 70a8e6b..0000000
--- a/docs/html/images/brand/learnmore.gif
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/brand/logo_android.gif b/docs/html/images/brand/logo_android.gif
deleted file mode 100644
index 169c764..0000000
--- a/docs/html/images/brand/logo_android.gif
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/brand/mediaplayer.gif b/docs/html/images/brand/mediaplayer.gif
deleted file mode 100644
index 860d110..0000000
--- a/docs/html/images/brand/mediaplayer.gif
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/brand/mediaplayer.png b/docs/html/images/brand/mediaplayer.png
new file mode 100644
index 0000000..f857d5f
--- /dev/null
+++ b/docs/html/images/brand/mediaplayer.png
Binary files differ
diff --git a/docs/html/images/brand/norad.gif b/docs/html/images/brand/norad.gif
deleted file mode 100644
index d8707bd..0000000
--- a/docs/html/images/brand/norad.gif
+++ /dev/null
Binary files differ
diff --git a/docs/html/legal.jd b/docs/html/legal.jd
index 3206503..1698af0f 100644
--- a/docs/html/legal.jd
+++ b/docs/html/legal.jd
@@ -39,7 +39,7 @@
use of it must be attributed as such.</p>
<p>For more information about Android brands, see the <a
-href="{@docRoot}distribute/googleplay/promote/brand.html">Android Branding Guidelines</a>.</p>
+href="{@docRoot}distribute/googleplay/promote/brand.html">Brand Guidelines</a>.</p>
<p>All other trademarks are the property of their respective owners.</p>
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 6ca70a4..f84c847 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -1573,7 +1573,8 @@
}
status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
- const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
+ const bool reject = quickRejectNoScissor(left, top,
+ left + bitmap->width(), top + bitmap->height());
uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
addBitmap(bitmap);
addPoint(left, top);
@@ -1587,7 +1588,7 @@
const mat4 transform(*matrix);
transform.mapRect(r);
- const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
+ const bool reject = quickRejectNoScissor(r.left, r.top, r.right, r.bottom);
uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
addBitmap(bitmap);
addMatrix(matrix);
@@ -1599,7 +1600,7 @@
status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint) {
- const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
+ const bool reject = quickRejectNoScissor(dstLeft, dstTop, dstRight, dstBottom);
uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
addBitmap(bitmap);
addBounds(srcLeft, srcTop, srcRight, srcBottom);
@@ -1611,7 +1612,8 @@
status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
SkPaint* paint) {
- const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
+ const bool reject = quickRejectNoScissor(left, top,
+ left + bitmap->width(), top + bitmap->height());
uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
addBitmapData(bitmap);
addPoint(left, top);
@@ -1644,7 +1646,7 @@
SkXfermode::Mode mode;
OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
- const bool reject = quickReject(left, top, right, bottom);
+ const bool reject = quickRejectNoScissor(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawPatch, reject);
addBitmap(bitmap);
addInts(xDivs, width);
@@ -1667,7 +1669,7 @@
status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
SkPaint* paint) {
const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
- quickReject(left, top, right, bottom);
+ quickRejectNoScissor(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawRect, reject);
addBounds(left, top, right, bottom);
addPaint(paint);
@@ -1678,7 +1680,7 @@
status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint) {
const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
- quickReject(left, top, right, bottom);
+ quickRejectNoScissor(left, top, right, bottom);
uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
addBounds(left, top, right, bottom);
addPoint(rx, ry);
@@ -1721,7 +1723,7 @@
left -= offset;
top -= offset;
- const bool reject = quickReject(left, top, left + width, top + height);
+ const bool reject = quickRejectNoScissor(left, top, left + width, top + height);
uint32_t* location = addOp(DisplayList::DrawPath, reject);
addPath(path);
addPaint(paint);
@@ -1791,7 +1793,7 @@
if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
SkPaint::FontMetrics metrics;
paint->getFontMetrics(&metrics, 0.0f);
- reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
+ reject = quickRejectNoScissor(x, y + metrics.fTop, x + length, y + metrics.fBottom);
}
uint32_t* location = addOp(DisplayList::DrawText, reject);
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 87add17..a924362 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -73,6 +73,11 @@
return mIsIdentity;
}
+bool Matrix4::isPerspective() const {
+ return data[kPerspective0] != 0.0f || data[kPerspective1] != 0.0f ||
+ data[kPerspective2] != 1.0f;
+}
+
void Matrix4::load(const float* v) {
memcpy(data, v, sizeof(data));
// TODO: Do something smarter here
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 02b781e..f86823d 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -115,6 +115,7 @@
bool isPureTranslate() const;
bool isSimple() const;
bool isIdentity() const;
+ bool isPerspective() const;
bool changesBounds() const;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 684d5e1..c015077 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2647,20 +2647,21 @@
setupDrawShaderUniforms(pureTranslate);
setupDrawTextGammaUniforms();
- const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
+ const Rect* clip = pureTranslate ? mSnapshot->clipRect :
+ (mSnapshot->hasPerspectiveTransform() ? NULL : &mSnapshot->getLocalClip());
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
const bool hasActiveLayer = hasLayer();
bool status;
- if (paint->getTextAlign() != SkPaint::kLeft_Align) {
+ if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
SkPaint paintCopy(*paint);
paintCopy.setTextAlign(SkPaint::kLeft_Align);
status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL);
+ positions, hasActiveLayer ? &bounds : NULL);
} else {
status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL);
+ positions, hasActiveLayer ? &bounds : NULL);
}
if (status && hasActiveLayer) {
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 4484676..fbc8455 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -178,6 +178,10 @@
flags |= Snapshot::kFlagClipSet;
}
+bool Snapshot::hasPerspectiveTransform() const {
+ return transform->isPerspective();
+}
+
const Rect& Snapshot::getLocalClip() {
mat4 inverse;
inverse.loadInverse(*transform);
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index a89b740..9c612ff 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -121,6 +121,11 @@
bool isIgnored() const;
/**
+ * Indicates whether the current transform has perspective components.
+ */
+ bool hasPerspectiveTransform() const;
+
+ /**
* Dirty flags.
*/
int flags;
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 6e205b8..7bfa63d 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "OpenGLRenderer"
+
#include <cutils/compiler.h>
#include <SkUtils.h>
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index a256079..36c9c70 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -22,12 +22,17 @@
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.WifiDisplay;
+import android.hardware.display.WifiDisplayStatus;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;
+import android.view.Display;
+import android.view.DisplayInfo;
import java.util.ArrayList;
import java.util.HashMap;
@@ -51,6 +56,7 @@
static class Static {
final Resources mResources;
final IAudioService mAudioService;
+ final DisplayManager mDisplayService;
final Handler mHandler;
final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
new CopyOnWriteArrayList<CallbackInfo>();
@@ -60,18 +66,20 @@
final RouteCategory mSystemCategory;
- final AudioRoutesInfo mCurRoutesInfo = new AudioRoutesInfo();
+ final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
- RouteInfo mDefaultAudio;
+ RouteInfo mDefaultAudioVideo;
RouteInfo mBluetoothA2dpRoute;
RouteInfo mSelectedRoute;
- final IAudioRoutesObserver.Stub mRoutesObserver = new IAudioRoutesObserver.Stub() {
+ WifiDisplayStatus mLastKnownWifiDisplayStatus;
+
+ final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
mHandler.post(new Runnable() {
@Override public void run() {
- updateRoutes(newRoutes);
+ updateAudioRoutes(newRoutes);
}
});
}
@@ -84,34 +92,42 @@
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
mAudioService = IAudioService.Stub.asInterface(b);
+ mDisplayService = (DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);
+
mSystemCategory = new RouteCategory(
com.android.internal.R.string.default_audio_route_category_name,
- ROUTE_TYPE_LIVE_AUDIO, false);
+ ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO, false);
+ mSystemCategory.mIsSystem = true;
}
// Called after sStatic is initialized
void startMonitoringRoutes(Context appContext) {
- mDefaultAudio = new RouteInfo(mSystemCategory);
- mDefaultAudio.mNameResId = com.android.internal.R.string.default_audio_route_name;
- mDefaultAudio.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
- addRoute(mDefaultAudio);
+ mDefaultAudioVideo = new RouteInfo(mSystemCategory);
+ mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name;
+ mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
+ addRoute(mDefaultAudioVideo);
appContext.registerReceiver(new VolumeChangeReceiver(),
new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
- AudioRoutesInfo newRoutes = null;
+ AudioRoutesInfo newAudioRoutes = null;
try {
- newRoutes = mAudioService.startWatchingRoutes(mRoutesObserver);
+ newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
} catch (RemoteException e) {
}
- if (newRoutes != null) {
- updateRoutes(newRoutes);
+ if (newAudioRoutes != null) {
+ updateAudioRoutes(newAudioRoutes);
}
+
+ updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
+
+ appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
+ new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
}
- void updateRoutes(AudioRoutesInfo newRoutes) {
- if (newRoutes.mMainType != mCurRoutesInfo.mMainType) {
- mCurRoutesInfo.mMainType = newRoutes.mMainType;
+ void updateAudioRoutes(AudioRoutesInfo newRoutes) {
+ if (newRoutes.mMainType != mCurAudioRoutesInfo.mMainType) {
+ mCurAudioRoutesInfo.mMainType = newRoutes.mMainType;
int name;
if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
|| (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
@@ -119,12 +135,12 @@
} else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
} else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
- name = com.android.internal.R.string.default_audio_route_name_hdmi;
+ name = com.android.internal.R.string.default_media_route_name_hdmi;
} else {
name = com.android.internal.R.string.default_audio_route_name;
}
- sStatic.mDefaultAudio.mNameResId = name;
- dispatchRouteChanged(sStatic.mDefaultAudio);
+ sStatic.mDefaultAudioVideo.mNameResId = name;
+ dispatchRouteChanged(sStatic.mDefaultAudioVideo);
}
boolean a2dpEnabled;
@@ -135,17 +151,17 @@
a2dpEnabled = false;
}
- if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) {
- mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
- if (mCurRoutesInfo.mBluetoothName != null) {
+ if (!TextUtils.equals(newRoutes.mBluetoothName, mCurAudioRoutesInfo.mBluetoothName)) {
+ mCurAudioRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
+ if (mCurAudioRoutesInfo.mBluetoothName != null) {
if (sStatic.mBluetoothA2dpRoute == null) {
final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
- info.mName = mCurRoutesInfo.mBluetoothName;
+ info.mName = mCurAudioRoutesInfo.mBluetoothName;
info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
sStatic.mBluetoothA2dpRoute = info;
addRoute(sStatic.mBluetoothA2dpRoute);
} else {
- sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName;
+ sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.mBluetoothName;
dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
}
} else if (sStatic.mBluetoothA2dpRoute != null) {
@@ -155,11 +171,11 @@
}
if (mBluetoothA2dpRoute != null) {
- if (mCurRoutesInfo.mMainType != AudioRoutesInfo.MAIN_SPEAKER &&
+ if (mCurAudioRoutesInfo.mMainType != AudioRoutesInfo.MAIN_SPEAKER &&
mSelectedRoute == mBluetoothA2dpRoute) {
- selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudio);
- } else if (mCurRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
- mSelectedRoute == mDefaultAudio && a2dpEnabled) {
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
+ } else if (mCurAudioRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
+ mSelectedRoute == mDefaultAudioVideo && a2dpEnabled) {
selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
}
}
@@ -181,6 +197,20 @@
public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1;
/**
+ * Route type flag for live video.
+ *
+ * <p>A device that supports live video routing will allow a mirrored version
+ * of the device's primary display or a customized
+ * {@link android.app.Presentation Presentation} to be routed to supported destinations.</p>
+ *
+ * <p>Once initiated, display mirroring is transparent to the application.
+ * While remote routing is active the application may use a
+ * {@link android.app.Presentation Presentation} to replace the mirrored view
+ * on the external display with different content.</p>
+ */
+ public static final int ROUTE_TYPE_LIVE_VIDEO = 0x2;
+
+ /**
* Route type flag for application-specific usage.
*
* <p>Unlike other media route types, user routes are managed by the application.
@@ -219,7 +249,7 @@
* @hide for use by framework routing UI
*/
public RouteInfo getSystemAudioRoute() {
- return sStatic.mDefaultAudio;
+ return sStatic.mDefaultAudioVideo;
}
/**
@@ -296,7 +326,8 @@
}
static void selectRouteStatic(int types, RouteInfo route) {
- if (sStatic.mSelectedRoute == route) return;
+ final RouteInfo oldRoute = sStatic.mSelectedRoute;
+ if (oldRoute == route) return;
if ((route.getSupportedTypes() & types) == 0) {
Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
typesToString(route.getSupportedTypes()) + " into route types " +
@@ -306,7 +337,7 @@
final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute;
if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 &&
- (route == btRoute || route == sStatic.mDefaultAudio)) {
+ (route == btRoute || route == sStatic.mDefaultAudioVideo)) {
try {
sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute);
} catch (RemoteException e) {
@@ -314,10 +345,21 @@
}
}
- if (sStatic.mSelectedRoute != null) {
+ final WifiDisplay activeDisplay =
+ sStatic.mDisplayService.getWifiDisplayStatus().getActiveDisplay();
+ final boolean oldRouteHasAddress = oldRoute != null && oldRoute.mDeviceAddress != null;
+ final boolean newRouteHasAddress = route != null && route.mDeviceAddress != null;
+ if (activeDisplay != null || oldRouteHasAddress || newRouteHasAddress) {
+ if (newRouteHasAddress && !matchesDeviceAddress(activeDisplay, route)) {
+ sStatic.mDisplayService.connectWifiDisplay(route.mDeviceAddress);
+ } else if (activeDisplay != null && !newRouteHasAddress) {
+ sStatic.mDisplayService.disconnectWifiDisplay();
+ }
+ }
+
+ if (oldRoute != null) {
// TODO filter types properly
- dispatchRouteUnselected(types & sStatic.mSelectedRoute.getSupportedTypes(),
- sStatic.mSelectedRoute);
+ dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
}
sStatic.mSelectedRoute = route;
if (route != null) {
@@ -327,6 +369,22 @@
}
/**
+ * Compare the device address of a display and a route.
+ * Nulls/no device address will match another null/no address.
+ */
+ static boolean matchesDeviceAddress(WifiDisplay display, RouteInfo info) {
+ final boolean routeHasAddress = info != null && info.mDeviceAddress != null;
+ if (display == null && !routeHasAddress) {
+ return true;
+ }
+
+ if (display != null && routeHasAddress) {
+ return display.getDeviceAddress().equals(info.mDeviceAddress);
+ }
+ return false;
+ }
+
+ /**
* Add an app-specified route for media to the MediaRouter.
* App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
*
@@ -419,7 +477,7 @@
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);
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudioVideo);
}
if (!found) {
sStatic.mCategories.remove(removingCat);
@@ -444,7 +502,8 @@
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);
+ selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO | ROUTE_TYPE_USER,
+ sStatic.mDefaultAudioVideo);
}
if (!found) {
sStatic.mCategories.remove(removingCat);
@@ -611,20 +670,151 @@
if (selectedRoute == null) return;
if (selectedRoute == sStatic.mBluetoothA2dpRoute ||
- selectedRoute == sStatic.mDefaultAudio) {
+ selectedRoute == sStatic.mDefaultAudioVideo) {
dispatchRouteVolumeChanged(selectedRoute);
} else if (sStatic.mBluetoothA2dpRoute != null) {
try {
dispatchRouteVolumeChanged(sStatic.mAudioService.isBluetoothA2dpOn() ?
- sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudio);
+ sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo);
} catch (RemoteException e) {
Log.e(TAG, "Error checking Bluetooth A2DP state to report volume change", e);
}
} else {
- dispatchRouteVolumeChanged(sStatic.mDefaultAudio);
+ dispatchRouteVolumeChanged(sStatic.mDefaultAudioVideo);
}
}
+ static void updateWifiDisplayStatus(WifiDisplayStatus newStatus) {
+ final WifiDisplayStatus oldStatus = sStatic.mLastKnownWifiDisplayStatus;
+
+ // TODO Naive implementation. Make this smarter later.
+ boolean needScan = false;
+ WifiDisplay[] oldDisplays = oldStatus != null ?
+ oldStatus.getRememberedDisplays() : new WifiDisplay[0];
+ WifiDisplay[] newDisplays = newStatus.getRememberedDisplays();
+ WifiDisplay[] availableDisplays = newStatus.getAvailableDisplays();
+
+ for (int i = 0; i < newDisplays.length; i++) {
+ final WifiDisplay d = newDisplays[i];
+ final WifiDisplay oldRemembered = findMatchingDisplay(d, oldDisplays);
+ if (oldRemembered == null) {
+ addRoute(makeWifiDisplayRoute(d));
+ needScan = true;
+ } else {
+ final boolean available = findMatchingDisplay(d, availableDisplays) != null;
+ final RouteInfo route = findWifiDisplayRoute(d);
+ updateWifiDisplayRoute(route, d, available, newStatus);
+ }
+ }
+ for (int i = 0; i < oldDisplays.length; i++) {
+ final WifiDisplay d = oldDisplays[i];
+ final WifiDisplay newDisplay = findMatchingDisplay(d, newDisplays);
+ if (newDisplay == null) {
+ removeRoute(findWifiDisplayRoute(d));
+ }
+ }
+
+ if (needScan) {
+ sStatic.mDisplayService.scanWifiDisplays();
+ }
+
+ sStatic.mLastKnownWifiDisplayStatus = newStatus;
+ }
+
+ static RouteInfo makeWifiDisplayRoute(WifiDisplay display) {
+ final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
+ newRoute.mDeviceAddress = display.getDeviceAddress();
+ newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
+ newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
+ newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
+ newRoute.mStatus = sStatic.mResources.getText(
+ com.android.internal.R.string.media_route_status_connecting);
+ newRoute.mEnabled = false;
+
+ newRoute.mName = makeWifiDisplayName(display);
+ return newRoute;
+ }
+
+ static String makeWifiDisplayName(WifiDisplay display) {
+ String name = display.getDeviceAlias();
+ if (TextUtils.isEmpty(name)) {
+ name = display.getDeviceName();
+ }
+ return name;
+ }
+
+ private static void updateWifiDisplayRoute(RouteInfo route, WifiDisplay display,
+ boolean available, WifiDisplayStatus wifiDisplayStatus) {
+ final boolean isScanning =
+ wifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING;
+
+ boolean changed = false;
+ int newStatus = RouteInfo.STATUS_NONE;
+
+ if (available) {
+ newStatus = isScanning ? RouteInfo.STATUS_SCANNING : RouteInfo.STATUS_AVAILABLE;
+ } else {
+ newStatus = RouteInfo.STATUS_NOT_AVAILABLE;
+ }
+
+ if (display.equals(wifiDisplayStatus.getActiveDisplay())) {
+ final int activeState = wifiDisplayStatus.getActiveDisplayState();
+ switch (activeState) {
+ case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
+ newStatus = RouteInfo.STATUS_NONE;
+ break;
+ case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
+ newStatus = RouteInfo.STATUS_CONNECTING;
+ break;
+ case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
+ Log.e(TAG, "Active display is not connected!");
+ break;
+ }
+ }
+
+ final String newName = makeWifiDisplayName(display);
+ if (route.getName().equals(newName)) {
+ route.mName = newName;
+ changed = true;
+ }
+
+ changed |= route.mEnabled != available;
+ route.mEnabled = available;
+
+ changed |= route.setStatusCode(newStatus);
+
+ if (changed) {
+ dispatchRouteChanged(route);
+ }
+
+ if (!available && route == sStatic.mSelectedRoute) {
+ // Oops, no longer available. Reselect the default.
+ final RouteInfo defaultRoute = sStatic.mDefaultAudioVideo;
+ selectRouteStatic(defaultRoute.getSupportedTypes(), defaultRoute);
+ }
+ }
+
+ private static WifiDisplay findMatchingDisplay(WifiDisplay address, WifiDisplay[] displays) {
+ for (int i = 0; i < displays.length; i++) {
+ final WifiDisplay d = displays[i];
+ if (d.equals(address)) {
+ return d;
+ }
+ }
+ return null;
+ }
+
+ private static RouteInfo findWifiDisplayRoute(WifiDisplay d) {
+ final int count = sStatic.mRoutes.size();
+ for (int i = 0; i < count; i++) {
+ final RouteInfo info = sStatic.mRoutes.get(i);
+ if (d.getDeviceAddress().equals(info.mDeviceAddress)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
/**
* Information about a media route.
*/
@@ -644,6 +834,18 @@
int mPlaybackStream = AudioManager.STREAM_MUSIC;
VolumeCallbackInfo mVcb;
+ String mDeviceAddress;
+ boolean mEnabled = true;
+
+ // A predetermined connection status that can override mStatus
+ private int mStatusCode;
+
+ static final int STATUS_NONE = 0;
+ static final int STATUS_SCANNING = 1;
+ static final int STATUS_CONNECTING = 2;
+ static final int STATUS_AVAILABLE = 3;
+ static final int STATUS_NOT_AVAILABLE = 4;
+
private Object mTag;
/**
@@ -711,6 +913,34 @@
}
/**
+ * Set this route's status by predetermined status code. If the caller
+ * should dispatch a route changed event this call will return true;
+ */
+ boolean setStatusCode(int statusCode) {
+ if (statusCode != mStatusCode) {
+ mStatusCode = statusCode;
+ int resId = 0;
+ switch (statusCode) {
+ case STATUS_SCANNING:
+ resId = com.android.internal.R.string.media_route_status_scanning;
+ break;
+ case STATUS_CONNECTING:
+ resId = com.android.internal.R.string.media_route_status_connecting;
+ break;
+ case STATUS_AVAILABLE:
+ resId = com.android.internal.R.string.media_route_status_available;
+ break;
+ case STATUS_NOT_AVAILABLE:
+ resId = com.android.internal.R.string.media_route_status_not_available;
+ break;
+ }
+ mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
+ return true;
+ }
+ return false;
+ }
+
+ /**
* @return A media type flag set describing which types this route supports.
*/
public int getSupportedTypes() {
@@ -866,6 +1096,13 @@
return mVolumeHandling;
}
+ /**
+ * @return true if this route is enabled and may be selected
+ */
+ public boolean isEnabled() {
+ return mEnabled;
+ }
+
void setStatusInt(CharSequence status) {
if (!status.equals(mStatus)) {
mStatus = status;
@@ -881,7 +1118,6 @@
sStatic.mHandler.post(new Runnable() {
@Override
public void run() {
- //Log.d(TAG, "dispatchRemoteVolumeUpdate dir=" + direction + " val=" + value);
if (mVcb != null) {
if (direction != 0) {
mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
@@ -1400,6 +1636,7 @@
int mNameResId;
int mTypes;
final boolean mGroupable;
+ boolean mIsSystem;
RouteCategory(CharSequence name, int types, boolean groupable) {
mName = name;
@@ -1486,6 +1723,14 @@
return mGroupable;
}
+ /**
+ * @return true if this is the category reserved for system routes.
+ * @hide
+ */
+ public boolean isSystem() {
+ return mIsSystem;
+ }
+
public String toString() {
return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) +
" groupable=" + mGroupable + " }";
@@ -1671,7 +1916,6 @@
}
static class VolumeChangeReceiver extends BroadcastReceiver {
-
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
@@ -1689,6 +1933,15 @@
}
}
}
+ }
+ static class WifiDisplayStatusChangedReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
+ updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra(
+ DisplayManager.EXTRA_WIFI_DISPLAY_STATUS));
+ }
+ }
}
}
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 4f0d113..e084368 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1073,7 +1073,7 @@
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if (mTicking) {
- mTicker.halt();
+ haltTicker();
}
mNotificationIcons.animate()
@@ -1095,7 +1095,7 @@
}
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
- mTicker.halt();
+ haltTicker();
}
}
}
@@ -1359,7 +1359,7 @@
if (lightsOut) {
animateCollapsePanels();
if (mTicking) {
- mTicker.halt();
+ haltTicker();
}
}
@@ -1489,8 +1489,7 @@
mStatusBarContents.setVisibility(View.VISIBLE);
mTickerView.setVisibility(View.GONE);
mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
- mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
- mTickingDoneListener));
+ // we do not animate the ticker away at this point, just get rid of it (b/6992707)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 35b9f85..165250b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -246,9 +246,10 @@
@Override
public void onClick(View v) {
mBar.collapseAllPanels(true);
- ContactsContract.QuickContact.showQuickContact(mContext, v,
- ContactsContract.Profile.CONTENT_URI,
+ Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(mContext,
+ v, ContactsContract.Profile.CONTENT_URI,
ContactsContract.QuickContact.MODE_LARGE, null);
+ mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
}
});
mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index bba2c7f..72cb1dd 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -993,7 +993,11 @@
if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
if (cb != null && !isDestroyed() && mActionBar.getVisibility() == View.VISIBLE) {
final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
- if (cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
+
+ // If we don't have a menu or we're waiting for a full content refresh,
+ // forget it. This is a lingering event that no longer matters.
+ if (st.menu != null && !st.refreshMenuContent &&
+ cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
mActionBar.showOverflowMenu();
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e4eeceb..c3bd988 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -169,11 +169,6 @@
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
- // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
- // No longer recommended for desk docks; still useful in car docks.
- static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
- static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
-
static final int LONG_PRESS_POWER_NOTHING = 0;
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -347,7 +342,6 @@
boolean mSystemReady;
boolean mSystemBooted;
boolean mHdmiPlugged;
- int mUiMode;
int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
int mLidOpenRotation;
int mCarDockRotation;
@@ -892,8 +886,6 @@
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context, mHandler);
mShortcutManager.observe();
- mUiMode = context.getResources().getInteger(
- com.android.internal.R.integer.config_defaultUiModeType);
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -3563,13 +3555,6 @@
if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
- } else {
- try {
- IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
- ServiceManager.getService(Context.UI_MODE_SERVICE));
- mUiMode = uiModeService.getCurrentModeType();
- } catch (RemoteException e) {
- }
}
updateRotation(true);
updateOrientationListenerLp();
@@ -4122,63 +4107,8 @@
}
}
- /**
- * Return an Intent to launch the currently active dock app as home. Returns
- * null if the standard home should be launched, which is the case if any of the following is
- * true:
- * <ul>
- * <li>The device is not in either car mode or desk mode
- * <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
- * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
- * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
- * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
- * </ul>
- * @return
- */
- Intent createHomeDockIntent() {
- Intent intent = null;
-
- // What home does is based on the mode, not the dock state. That
- // is, when in car mode you should be taken to car home regardless
- // of whether we are actually in a car dock.
- if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
- if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
- intent = mCarDockIntent;
- }
- } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
- if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
- intent = mDeskDockIntent;
- }
- }
-
- if (intent == null) {
- return null;
- }
-
- ActivityInfo ai = intent.resolveActivityInfo(
- mContext.getPackageManager(), PackageManager.GET_META_DATA);
- if (ai == null) {
- return null;
- }
-
- if (ai.metaData != null && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) {
- intent = new Intent(intent);
- intent.setClassName(ai.packageName, ai.name);
- return intent;
- }
-
- return null;
- }
-
void startDockOrHome() {
- Intent dock = createHomeDockIntent();
- if (dock != null) {
- try {
- mContext.startActivity(dock);
- return;
- } catch (ActivityNotFoundException e) {
- }
- }
+ // We don't have dock home anymore. Home is home. If you lived here, you'd be home by now.
mContext.startActivityAsUser(mHomeIntent, UserHandle.CURRENT);
}
@@ -4205,18 +4135,6 @@
} else {
ActivityManagerNative.getDefault().stopAppSwitches();
sendCloseSystemWindows();
- Intent dock = createHomeDockIntent();
- if (dock != null) {
- int result = ActivityManagerNative.getDefault()
- .startActivityAsUser(null, dock,
- dock.resolveTypeIfNeeded(mContext.getContentResolver()),
- null, null, 0,
- ActivityManager.START_FLAG_ONLY_IF_NEEDED,
- null, null, null, UserHandle.USER_CURRENT);
- if (result == ActivityManager.START_RETURN_INTENT_TO_CALLER) {
- return false;
- }
- }
}
int result = ActivityManagerNative.getDefault()
.startActivityAsUser(null, mHomeIntent,
@@ -4403,8 +4321,7 @@
pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
pw.println(mLastFocusNeedsMenu);
}
- pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
- pw.print(" mDockMode="); pw.print(mDockMode);
+ pw.print(prefix); pw.print("mDockMode="); pw.print(mDockMode);
pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index c5ec33b..1d1c7fc 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -547,8 +547,9 @@
oldView.onPause();
newView.onResume();
+ final boolean needsInput = newView.needsInput();
if (mViewMediatorCallback != null) {
- mViewMediatorCallback.setNeedsInput(newView.needsInput());
+ mViewMediatorCallback.setNeedsInput(needsInput);
}
// Find and show this child.
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 542cc07..3e9bef0 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -102,6 +102,10 @@
// The timeout after which we are no longer trying to detect a gesture.
private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000;
+ // The timeout to send interaction end events in case we did not
+ // receive the expected hover exit event due to a misbehaving app.
+ private static final int SEND_INTERACTION_END_EVENTS_TIMEOUT = 200;
+
// Temporary array for storing pointer IDs.
private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT];
@@ -135,6 +139,9 @@
// Command for delayed sending of a hover exit event.
private final SendHoverDelayed mSendHoverExitDelayed;
+ // Command for delayed sending of interaction ending events.
+ private final SendInteractionEndEventsDelayed mSendInteractionEndEventsDelayed;
+
// Command for delayed sending of a long press.
private final PerformLongPressDelayed mPerformLongPressDelayed;
@@ -233,6 +240,7 @@
mGestureLibrary.load();
mSendHoverEnterDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_ENTER, true);
mSendHoverExitDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_EXIT, false);
+ mSendInteractionEndEventsDelayed = new SendInteractionEndEventsDelayed();
mDoubleTapDetector = new DoubleTapDetector();
final float density = context.getResources().getDisplayMetrics().density;
mScaledMinPointerDistanceToUseMiddleLocation =
@@ -278,6 +286,7 @@
mSendHoverExitDelayed.remove();
mPerformLongPressDelayed.remove();
mExitGestureDetectionModeDelayed.remove();
+ mSendInteractionEndEventsDelayed.remove();
// Reset the pointer trackers.
mReceivedPointerTracker.clear();
mInjectedPointerTracker.clear();
@@ -334,6 +343,7 @@
// last hover exit event.
if (mTouchExplorationGestureEnded
&& eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ mSendInteractionEndEventsDelayed.remove();
mTouchExplorationGestureEnded = false;
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
}
@@ -342,6 +352,7 @@
// last hover exit and the touch exploration gesture end events.
if (mTouchInteractionEnded
&& eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ mSendInteractionEndEventsDelayed.remove();
mTouchInteractionEnded = false;
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
}
@@ -416,6 +427,10 @@
mSendHoverExitDelayed.remove();
}
+ if (mSendInteractionEndEventsDelayed.isPending()) {
+ mSendInteractionEndEventsDelayed.forceSendAndRemove();
+ }
+
mPerformLongPressDelayed.remove();
// If we have the first tap schedule a long press and break
@@ -873,6 +888,9 @@
final int pointerIdBits = event.getPointerIdBits();
mTouchExplorationGestureEnded = true;
mTouchInteractionEnded = true;
+ if (!mSendInteractionEndEventsDelayed.isPending()) {
+ mSendInteractionEndEventsDelayed.post();
+ }
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags);
}
}
@@ -1484,10 +1502,16 @@
} else {
mTouchExplorationGestureEnded = true;
mTouchInteractionEnded = true;
+ if (!mSendInteractionEndEventsDelayed.isPending()) {
+ mSendInteractionEndEventsDelayed.post();
+ }
}
} else {
if (!mGestureStarted) {
mTouchInteractionEnded = true;
+ if (!mSendInteractionEndEventsDelayed.isPending()) {
+ mSendInteractionEndEventsDelayed.post();
+ }
}
}
sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags);
@@ -1495,6 +1519,40 @@
}
}
+ private class SendInteractionEndEventsDelayed implements Runnable {
+
+ public void remove() {
+ mHandler.removeCallbacks(this);
+ }
+
+ public void post() {
+ mHandler.postDelayed(this, SEND_INTERACTION_END_EVENTS_TIMEOUT);
+ }
+
+ public boolean isPending() {
+ return mHandler.hasCallbacks(this);
+ }
+
+ public void forceSendAndRemove() {
+ if (isPending()) {
+ run();
+ remove();
+ }
+ }
+
+ @Override
+ public void run() {
+ if (mTouchExplorationGestureEnded) {
+ mTouchExplorationGestureEnded = false;
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
+ }
+ if (mTouchInteractionEnded) {
+ mTouchInteractionEnded = false;
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
+ }
+ }
+ }
+
@Override
public String toString() {
return LOG_TAG;
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index e07230d..4480151 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -126,7 +126,7 @@
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(istream);
} catch (CertificateException e) {
- throw new IllegalStateException("Got malformed certificate from settings, ignoring", e);
+ throw new IllegalStateException("Got malformed certificate from settings, ignoring");
}
}
@@ -167,7 +167,7 @@
String strVersion = IoUtils.readFileAsString(updateVersion.getCanonicalPath()).trim();
return Integer.parseInt(strVersion);
} catch (IOException e) {
- Slog.i(TAG, "Couldn't find current metadata, assuming first update", e);
+ Slog.i(TAG, "Couldn't find current metadata, assuming first update");
return 0;
}
}
@@ -181,7 +181,7 @@
try {
return IoUtils.readFileAsString(updateContent.getCanonicalPath()).trim();
} catch (IOException e) {
- Slog.i(TAG, "Failed to read current content, assuming first update!", e);
+ Slog.i(TAG, "Failed to read current content, assuming first update!");
return null;
}
}
diff --git a/services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java b/services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java
new file mode 100644
index 0000000..0f14f57
--- /dev/null
+++ b/services/java/com/android/server/updates/SmsShortCodesInstallReceiver.java
@@ -0,0 +1,24 @@
+/*
+ * 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.server.updates;
+
+public class SmsShortCodesInstallReceiver extends ConfigUpdateInstallReceiver {
+
+ public SmsShortCodesInstallReceiver() {
+ super("/data/misc/sms/", "codes", "metadata/", "version");
+ }
+}
diff --git a/services/jni/com_android_server_power_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
index 38af38d..dcc2b58 100644
--- a/services/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -183,14 +183,16 @@
gPowerModule->setInteractive(gPowerModule, true);
}
+ const sp<IBinder>& display = s->getBuiltInDisplay(0); // TODO: support multiple displays
{
ALOGD_IF_SLOW(100, "Excessive delay in unblank() while turning screen on");
- s->unblank();
+ s->unblank(display);
}
} else {
+ const sp<IBinder>& display = s->getBuiltInDisplay(0); // TODO: support multiple displays
{
ALOGD_IF_SLOW(100, "Excessive delay in blank() while turning screen off");
- s->blank();
+ s->blank(display);
}
if (gPowerModule) {