Merge "Add documentation to NetworkStateTracker and a small change to the API."
diff --git a/api/current.xml b/api/current.xml
index b0056d7..d35037e 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -10657,6 +10657,17 @@
visibility="public"
>
</field>
+<field name="windowActionBarSize"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843563"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowActionBarStyle"
type="int"
transient="false"
@@ -73982,7 +73993,7 @@
<method name="setShadowLayer"
return="void"
abstract="false"
- native="true"
+ native="false"
synchronized="false"
static="false"
final="false"
@@ -86983,6 +86994,24 @@
</parameter>
<parameter name="modeId" type="int">
</parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+</constructor>
+<constructor name="Keyboard"
+ type="android.inputmethodservice.Keyboard"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="xmlLayoutResId" type="int">
+</parameter>
+<parameter name="modeId" type="int">
+</parameter>
</constructor>
<constructor name="Keyboard"
type="android.inputmethodservice.Keyboard"
@@ -147418,11 +147447,11 @@
visibility="public"
>
</field>
-<field name="CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY"
+<field name="CAPABILITY_HAS_VIDEO"
type="int"
transient="false"
volatile="false"
- value="1"
+ value="2"
static="true"
final="true"
deprecated="not deprecated"
@@ -147433,7 +147462,7 @@
type="int"
transient="false"
volatile="false"
- value="2"
+ value="1"
static="true"
final="true"
deprecated="not deprecated"
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index e1d431f..8105843 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -851,8 +851,14 @@
*/
public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
+ if ("*/*".equals(mimeTypeFilter)) {
+ // If they can take anything, the untyped open call is good enough.
+ return openAssetFile(uri, "r");
+ }
String baseType = getType(uri);
if (baseType != null && compareMimeTypes(baseType, mimeTypeFilter)) {
+ // Use old untyped open call if this provider has a type for this
+ // URI and it matches the request.
return openAssetFile(uri, "r");
}
throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index 4814b0a..885a6b8 100755
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -500,7 +500,30 @@
public Keyboard(Context context, int xmlLayoutResId) {
this(context, xmlLayoutResId, 0);
}
-
+
+ /**
+ * Creates a keyboard from the given xml key layout file. Weeds out rows
+ * that have a keyboard mode defined but don't match the specified mode.
+ * @param context the application or service context
+ * @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
+ * @param modeId keyboard mode identifier
+ * @param width sets width of keyboard
+ * @param height sets height of keyboard
+ */
+ public Keyboard(Context context, int xmlLayoutResId, int modeId, int width, int height) {
+ mDisplayWidth = width;
+ mDisplayHeight = height;
+
+ mDefaultHorizontalGap = 0;
+ mDefaultWidth = mDisplayWidth / 10;
+ mDefaultVerticalGap = 0;
+ mDefaultHeight = mDefaultWidth;
+ mKeys = new ArrayList<Key>();
+ mModifierKeys = new ArrayList<Key>();
+ mKeyboardMode = modeId;
+ loadKeyboard(context, context.getResources().getXml(xmlLayoutResId));
+ }
+
/**
* Creates a keyboard from the given xml key layout file. Weeds out rows
* that have a keyboard mode defined but don't match the specified mode.
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index f34f4a3..c7f8ab2 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -91,7 +91,8 @@
/**
* Returns an adapter that can be attached to a {@link PreferenceActivity}
- * to show the preferences contained in this {@link PreferenceScreen}.
+ * or {@link PreferenceFragment} to show the preferences contained in this
+ * {@link PreferenceScreen}.
* <p>
* This {@link PreferenceScreen} will NOT appear in the returned adapter, instead
* it appears in the hierarchy above this {@link PreferenceScreen}.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c93d9b2..1981780 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -2461,18 +2461,19 @@
public static final String CHAT_CAPABILITY = "chat_capability";
/**
- * An allowed value of {@link #CHAT_CAPABILITY}. Indicates that the contact's device can
+ * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates audio-chat capability (microphone
+ * and speaker)
+ */
+ public static final int CAPABILITY_HAS_VOICE = 1;
+
+ /**
+ * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates that the contact's device can
* display a video feed.
*/
- public static final int CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY = 1;
+ public static final int CAPABILITY_HAS_VIDEO = 2;
/**
- * An allowed value of {@link #CHAT_CAPABILITY}. Indicates audio-chat capability.
- */
- public static final int CAPABILITY_HAS_VOICE = 2;
-
- /**
- * An allowed value of {@link #CHAT_CAPABILITY}. Indicates that the contact's device has a
+ * An allowed flag of {@link #CHAT_CAPABILITY}. Indicates that the contact's device has a
* camera that can be used for video chat (e.g. a front-facing camera on a phone).
*/
public static final int CAPABILITY_HAS_CAMERA = 4;
@@ -3632,10 +3633,11 @@
* <td>int</td>
* <td>{@link #CHAT_CAPABILITY}</td>
* <td>read/write</td>
- * <td>Contact IM chat compatibility value. The allowed values are:
+ * <td>Contact IM chat compatibility value. The allowed values combinations of the following
+ * flags. If None of these flags is set, the device can only do text messaging.
* <p>
* <ul>
- * <li>{@link #CAPABILITY_HAS_VIDEO_PLAYBACK_ONLY}</li>
+ * <li>{@link #CAPABILITY_HAS_VIDEO}</li>
* <li>{@link #CAPABILITY_HAS_VOICE}</li>
* <li>{@link #CAPABILITY_HAS_CAMERA}</li>
* </ul>
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 91dbe1f..4c72e95 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -756,6 +756,12 @@
private boolean setupModifiers(Paint paint) {
boolean hasModifier = false;
+ if (paint.hasShadow) {
+ nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
+ paint.shadowColor);
+ hasModifier = true;
+ }
+
final Shader shader = paint.getShader();
if (shader != null) {
nSetupShader(mRenderer, shader.native_shader);
@@ -770,7 +776,7 @@
return hasModifier;
}
-
+
private boolean setupColorFilter(Paint paint) {
final ColorFilter filter = paint.getColorFilter();
if (filter != null) {
@@ -782,5 +788,7 @@
private native void nSetupShader(int renderer, int shader);
private native void nSetupColorFilter(int renderer, int colorFilter);
+ private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color);
+
private native void nResetModifiers(int renderer);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 32009be..9f60f44 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3557,11 +3557,11 @@
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
- // bring it back to the default scale so that user can enter text
- boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
+ // bring it back to the reading level scale so that user can enter text
+ boolean zoom = mZoomManager.getScale() < mZoomManager.getReadingLevelScale();
if (zoom) {
mZoomManager.setZoomCenter(mLastTouchX, mLastTouchY);
- mZoomManager.setZoomScale(mZoomManager.getDefaultScale(), false);
+ mZoomManager.setZoomScale(mZoomManager.getReadingLevelScale(), false);
}
if (isTextView) {
rebuildWebTextView();
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7f7f46e..8033c9c 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -56,6 +56,13 @@
private ZoomControlExternal mExternalZoomControl;
/*
+ * For large screen devices, the defaultScale usually set to 1.0 and
+ * equal to the overview scale, to differentiate the zoom level for double tapping,
+ * a minimum reading level scale is used.
+ */
+ private static final float MIN_READING_LEVEL_SCALE = 1.5f;
+
+ /*
* The scale factors that determine the upper and lower bounds for the
* default zoom scale.
*/
@@ -245,6 +252,10 @@
return mDefaultScale;
}
+ public final float getReadingLevelScale() {
+ return Math.max(mDefaultScale, MIN_READING_LEVEL_SCALE);
+ }
+
public final float getInvDefaultScale() {
return mInvDefaultScale;
}
@@ -337,9 +348,9 @@
mInitialScrollX = mWebView.getScrollX();
mInitialScrollY = mWebView.getScrollY();
- // snap to DEFAULT_SCALE if it is close
- if (!exceedsMinScaleIncrement(scale, mDefaultScale)) {
- scale = mDefaultScale;
+ // snap to reading level scale if it is close
+ if (!exceedsMinScaleIncrement(scale, getReadingLevelScale())) {
+ scale = getReadingLevelScale();
}
setZoomScale(scale, reflowText);
@@ -535,7 +546,7 @@
} else if (!mInZoomOverview) {
zoomToOverview();
} else {
- zoomToDefaultLevel();
+ zoomToReadingLevel();
}
}
@@ -563,7 +574,8 @@
startZoomAnimation(getZoomOverviewScale(), true);
}
- private void zoomToDefaultLevel() {
+ private void zoomToReadingLevel() {
+ final float readingScale = getReadingLevelScale();
int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);
if (left != WebView.NO_LEFTEDGE) {
// add a 5pt padding to the left edge.
@@ -572,13 +584,13 @@
// Re-calculate the zoom center so that the new scroll x will be
// on the left edge.
if (viewLeft > 0) {
- mZoomCenterX = viewLeft * mDefaultScale / (mDefaultScale - mActualScale);
+ mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
} else {
mWebView.scrollBy(viewLeft, 0);
mZoomCenterX = 0;
}
}
- startZoomAnimation(mDefaultScale, true);
+ startZoomAnimation(readingScale, true);
}
public void updateMultiTouchSupport(Context context) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 2b723c9..ef00d88 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -685,14 +685,6 @@
verticalOffset = 0;
}
- void setHorizontalOffset(int newHorizontalOffset) {
- horizontalOffset = newHorizontalOffset;
- if (mView != null) {
- mView.requestLayout();
- mView.invalidate();
- }
- }
-
private Rect parentRect = new Rect();
void invalidateGlobalRegion(View v, Rect r) {
View p = v;
@@ -722,5 +714,17 @@
invalidateGlobalRegion(mView, invalidateRect);
}
}
+
+ public void setHorizontalOffset(int newHorizontalOffset) {
+ int offsetDelta = newHorizontalOffset - horizontalOffset;
+ horizontalOffset = newHorizontalOffset;
+ if (mView != null) {
+ mView.requestLayout();
+ int left = Math.min(mView.getLeft() + offsetDelta, mView.getLeft());
+ int right = Math.max(mView.getRight() + offsetDelta, mView.getRight());
+ invalidateRect.set(left, mView.getTop(), right, mView.getBottom());
+ invalidateGlobalRegion(mView, invalidateRect);
+ }
+ }
}
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 4cd44d9..e3aca6a 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -20,6 +20,12 @@
import android.animation.PropertyAnimator;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -72,11 +78,9 @@
* These variables are all related to the current state of touch interaction
* with the stack
*/
- private boolean mGestureComplete = false;
private float mInitialY;
private float mInitialX;
private int mActivePointerId;
- private int mYOffset = 0;
private int mYVelocity = 0;
private int mSwipeGestureType = GESTURE_NONE;
private int mViewHeight;
@@ -85,6 +89,8 @@
private int mMaximumVelocity;
private VelocityTracker mVelocityTracker;
+ private ImageView mHighlight;
+ private StackSlider mStackSlider;
private boolean mFirstLayoutHappened = false;
// TODO: temp hack to get this thing started
@@ -107,6 +113,15 @@
mTouchSlop = configuration.getScaledTouchSlop();// + 5;
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mActivePointerId = INVALID_POINTER;
+
+ mHighlight = new ImageView(getContext());
+ mHighlight.setLayoutParams(new LayoutParams(mHighlight));
+ addViewInLayout(mHighlight, -1, new LayoutParams(mHighlight));
+ mStackSlider = new StackSlider();
+
+ if (!sPaintsInitialized) {
+ initializePaints(getContext());
+ }
}
/**
@@ -124,6 +139,7 @@
} else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
// Slide item in
view.setVisibility(VISIBLE);
+
LayoutParams lp = (LayoutParams) view.getLayoutParams();
int largestDuration = (int) Math.round(
@@ -136,19 +152,18 @@
duration = Math.min(duration, largestDuration);
duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
- PropertyAnimator slideDown = new PropertyAnimator(duration, lp,
- "verticalOffset", lp.verticalOffset, 0);
- slideDown.start();
+ PropertyAnimator slideInY = new PropertyAnimator(duration, mStackSlider,
+ "YProgress", mStackSlider.getYProgress(), 0);
+ slideInY.start();
+ PropertyAnimator slideInX = new PropertyAnimator(duration, mStackSlider,
+ "XProgress", mStackSlider.getXProgress(), 0);
+ slideInX.start();
- PropertyAnimator fadeIn = new PropertyAnimator(duration, view,
- "alpha", view.getAlpha(), 1.0f);
- fadeIn.start();
} else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) {
// Slide item out
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- int largestDuration = (int) Math.round(
- (1 - (lp.verticalOffset*1.0f/-mViewHeight))*DEFAULT_ANIMATION_DURATION);
+ int largestDuration = (int) Math.round(mStackSlider.getYProgress()*DEFAULT_ANIMATION_DURATION);
int duration = largestDuration;
if (mYVelocity != 0) {
duration = 1000*(lp.verticalOffset + mViewHeight)/Math.abs(mYVelocity);
@@ -157,13 +172,13 @@
duration = Math.min(duration, largestDuration);
duration = Math.max(duration, MINIMUM_ANIMATION_DURATION);
- PropertyAnimator slideUp = new PropertyAnimator(duration, lp,
- "verticalOffset", lp.verticalOffset, -mViewHeight);
- slideUp.start();
+ PropertyAnimator slideOutY = new PropertyAnimator(duration, mStackSlider,
+ "YProgress", mStackSlider.getYProgress(), 1);
+ slideOutY.start();
+ PropertyAnimator slideOutX = new PropertyAnimator(duration, mStackSlider,
+ "XProgress", mStackSlider.getXProgress(), 0);
+ slideOutX.start();
- PropertyAnimator fadeOut = new PropertyAnimator(duration, view,
- "alpha", view.getAlpha(), 0.0f);
- fadeOut.start();
} else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) {
// Make sure this view that is "waiting in the wings" is invisible
view.setAlpha(0.0f);
@@ -233,7 +248,6 @@
view.setClipChildren(false);
view.setClipToPadding(false);
}
-
mFirstLayoutHappened = true;
}
}
@@ -258,16 +272,10 @@
Log.d(TAG, "Error: No data for our primary pointer.");
return false;
}
-
float newY = ev.getY(pointerIndex);
float deltaY = newY - mInitialY;
- if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
- mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
- mGestureComplete = false;
- cancelLongPress();
- requestDisallowInterceptTouchEvent(true);
- }
+ beginGestureIfNeeded(deltaY);
break;
}
case MotionEvent.ACTION_POINTER_UP: {
@@ -278,13 +286,33 @@
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER;
mSwipeGestureType = GESTURE_NONE;
- mGestureComplete = true;
}
}
return mSwipeGestureType != GESTURE_NONE;
}
+ private void beginGestureIfNeeded(float deltaY) {
+ if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
+ mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
+ cancelLongPress();
+ requestDisallowInterceptTouchEvent(true);
+
+ int activeIndex = mSwipeGestureType == GESTURE_SLIDE_DOWN ? mNumActiveViews - 1
+ : mNumActiveViews - 2;
+
+ View v = getViewAtRelativeIndex(activeIndex);
+ if (v != null) {
+ mHighlight.setImageBitmap(createOutline(v));
+ mHighlight.bringToFront();
+ v.bringToFront();
+ mStackSlider.setView(v);
+ if (mSwipeGestureType == GESTURE_SLIDE_DOWN)
+ v.setVisibility(VISIBLE);
+ }
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -296,8 +324,9 @@
}
float newY = ev.getY(pointerIndex);
+ float newX = ev.getX(pointerIndex);
float deltaY = newY - mInitialY;
-
+ float deltaX = newX - mInitialX;
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
@@ -305,48 +334,21 @@
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
- if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
- mSwipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
- mGestureComplete = false;
- cancelLongPress();
- requestDisallowInterceptTouchEvent(true);
+ beginGestureIfNeeded(deltaY);
+
+ float rx = 0.3f*deltaX/(mViewHeight*1.0f);
+ if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
+ float r = (deltaY-mTouchSlop*1.0f)/mViewHeight*1.0f;
+ mStackSlider.setYProgress(1 - r);
+ mStackSlider.setXProgress(rx);
+ return true;
+ } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
+ float r = -(deltaY + mTouchSlop*1.0f)/mViewHeight*1.0f;
+ mStackSlider.setYProgress(r);
+ mStackSlider.setXProgress(rx);
+ return true;
}
- if (!mGestureComplete) {
- if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
- View v = getViewAtRelativeIndex(mNumActiveViews - 1);
- if (v != null) {
- // This view is present but hidden, make sure it's visible
- // if they pull down
- v.setVisibility(VISIBLE);
-
- float r = (deltaY-mTouchSlop)*1.0f / (mSwipeThreshold);
- mYOffset = Math.min(-mViewHeight + (int) Math.round(
- r*mSwipeThreshold) - mTouchSlop, 0);
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- lp.setVerticalOffset(mYOffset);
-
- float alpha = Math.max(0.0f, 1.0f - (1.0f*mYOffset/-mViewHeight));
- alpha = Math.min(1.0f, alpha);
- v.setAlpha(alpha);
- }
- return true;
- } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
- View v = getViewAtRelativeIndex(mNumActiveViews - 2);
-
- if (v != null) {
- float r = -(deltaY*1.0f + mTouchSlop) / (mSwipeThreshold);
- mYOffset = Math.min((int) Math.round(r*-mSwipeThreshold), 0);
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- lp.setVerticalOffset(mYOffset);
-
- float alpha = Math.max(0.0f, 1.0f - (1.0f*mYOffset/-mViewHeight));
- alpha = Math.min(1.0f, alpha);
- v.setAlpha(alpha);
- }
- return true;
- }
- }
break;
}
case MotionEvent.ACTION_UP: {
@@ -359,9 +361,7 @@
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER;
- mGestureComplete = true;
mSwipeGestureType = GESTURE_NONE;
- mYOffset = 0;
break;
}
}
@@ -427,56 +427,108 @@
mVelocityTracker = null;
}
- if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN &&
- !mGestureComplete) {
+ if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN) {
// Swipe threshold exceeded, swipe down
showNext();
- } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP &&
- !mGestureComplete) {
+ mHighlight.bringToFront();
+ } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP) {
// Swipe threshold exceeded, swipe up
showPrevious();
- } else if (mSwipeGestureType == GESTURE_SLIDE_UP && !mGestureComplete) {
+ mHighlight.bringToFront();
+ } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
// Didn't swipe up far enough, snap back down
- View v = getViewAtRelativeIndex(mNumActiveViews - 2);
- if (v != null) {
- // Compute the animation duration based on how far they pulled it up
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- int duration = (int) Math.round(
- lp.verticalOffset*1.0f/-mViewHeight*DEFAULT_ANIMATION_DURATION);
- duration = Math.max(MINIMUM_ANIMATION_DURATION, duration);
+ int duration = (int) Math.round(mStackSlider.getYProgress()*DEFAULT_ANIMATION_DURATION);
- // Animate back down
- PropertyAnimator slideDown = new PropertyAnimator(duration, lp,
- "verticalOffset", lp.verticalOffset, 0);
- slideDown.start();
- PropertyAnimator fadeIn = new PropertyAnimator(duration, v,
- "alpha",v.getAlpha(), 1.0f);
- fadeIn.start();
- }
- } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN && !mGestureComplete) {
+ PropertyAnimator snapBackY = new PropertyAnimator(duration, mStackSlider,
+ "YProgress", mStackSlider.getYProgress(), 0);
+ snapBackY.start();
+ PropertyAnimator snapBackX = new PropertyAnimator(duration, mStackSlider,
+ "XProgress", mStackSlider.getXProgress(), 0);
+ snapBackX.start();
+ } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
// Didn't swipe down far enough, snap back up
- View v = getViewAtRelativeIndex(mNumActiveViews - 1);
- if (v != null) {
- // Compute the animation duration based on how far they pulled it down
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- int duration = (int) Math.round(
- (1 - lp.verticalOffset*1.0f/-mViewHeight)*DEFAULT_ANIMATION_DURATION);
- duration = Math.max(MINIMUM_ANIMATION_DURATION, duration);
-
- // Animate back up
- PropertyAnimator slideUp = new PropertyAnimator(duration, lp,
- "verticalOffset", lp.verticalOffset, -mViewHeight);
- slideUp.start();
- PropertyAnimator fadeOut = new PropertyAnimator(duration, v,
- "alpha",v.getAlpha(), 0.0f);
- fadeOut.start();
- }
+ int duration = (int) Math.round((1 -
+ mStackSlider.getYProgress())*DEFAULT_ANIMATION_DURATION);
+ PropertyAnimator snapBackY = new PropertyAnimator(duration, mStackSlider,
+ "YProgress", mStackSlider.getYProgress(), 1);
+ snapBackY.start();
+ PropertyAnimator snapBackX = new PropertyAnimator(duration, mStackSlider,
+ "XProgress", mStackSlider.getXProgress(), 0);
+ snapBackX.start();
}
mActivePointerId = INVALID_POINTER;
- mGestureComplete = true;
mSwipeGestureType = GESTURE_NONE;
- mYOffset = 0;
+ }
+
+ private class StackSlider {
+ View mView;
+ float mYProgress;
+ float mXProgress;
+
+ private float cubic(float r) {
+ return (float) (Math.pow(2*r-1, 3) + 1)/2.0f;
+ }
+
+ private float highlightAlphaInterpolator(float r) {
+ float pivot = 0.4f;
+ if (r < pivot) {
+ return 0.85f*cubic(r/pivot);
+ } else {
+ return 0.85f*cubic(1 - (r-pivot)/(1-pivot));
+ }
+ }
+
+ private float viewAlphaInterpolator(float r) {
+ float pivot = 0.3f;
+ if (r > pivot) {
+ return (r - pivot)/(1 - pivot);
+ } else {
+ return 0;
+ }
+ }
+
+ void setView(View v) {
+ mView = v;
+ }
+
+ public void setYProgress(float r) {
+ // enforce r between 0 and 1
+ r = Math.min(1.0f, r);
+ r = Math.max(0, r);
+
+ mYProgress = r;
+
+ final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
+ final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
+
+ viewLp.setVerticalOffset((int) Math.round(-r*mViewHeight));
+ highlightLp.setVerticalOffset((int) Math.round(-r*mViewHeight));
+ mHighlight.setAlpha(highlightAlphaInterpolator(r));
+ mView.setAlpha(viewAlphaInterpolator(1-r));
+ }
+
+ public void setXProgress(float r) {
+ // enforce r between 0 and 1
+ r = Math.min(1.0f, r);
+ r = Math.max(-1.0f, r);
+
+ mXProgress = r;
+
+ final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
+ final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();
+
+ viewLp.setHorizontalOffset((int) Math.round(r*mViewHeight));
+ highlightLp.setHorizontalOffset((int) Math.round(r*mViewHeight));
+ }
+
+ float getYProgress() {
+ return mYProgress;
+ }
+
+ float getXProgress() {
+ return mXProgress;
+ }
}
@Override
@@ -484,4 +536,49 @@
super.onRemoteAdapterConnected();
setDisplayedChild(mIndex);
}
+
+ private static final Paint sHolographicPaint = new Paint();
+ private static final Paint sErasePaint = new Paint();
+ private static boolean sPaintsInitialized = false;
+ private static final float STROKE_WIDTH = 3.0f;
+
+ static void initializePaints(Context context) {
+ sHolographicPaint.setColor(0xff6699ff);
+ sHolographicPaint.setFilterBitmap(true);
+ sErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+ sErasePaint.setFilterBitmap(true);
+ sPaintsInitialized = true;
+ }
+
+ static Bitmap createOutline(View v) {
+ Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ canvas.concat(v.getMatrix());
+ v.draw(canvas);
+
+ Bitmap outlineBitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas outlineCanvas = new Canvas(outlineBitmap);
+ drawOutline(outlineCanvas, v.getMeasuredWidth(), v.getMeasuredHeight(), bitmap);
+ bitmap.recycle();
+ return outlineBitmap;
+ }
+
+ static void drawOutline(Canvas dest, int destWidth, int destHeight, Bitmap src) {
+ dest.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ Bitmap mask = src.extractAlpha();
+ Matrix id = new Matrix();
+
+ Matrix m = new Matrix();
+ float xScale = STROKE_WIDTH*2/(src.getWidth());
+ float yScale = STROKE_WIDTH*2/(src.getHeight());
+ m.preScale(1+xScale, 1+yScale, src.getWidth()/2, src.getHeight()/2);
+ dest.drawBitmap(mask, m, sHolographicPaint);
+
+ dest.drawBitmap(src, id, sErasePaint);
+ mask.recycle();
+ }
}
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index dd2ad6c..75084db 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -110,6 +110,7 @@
com.android.internal.R.id.lower_action_context_bar);
mAnimatorView = (ViewAnimator) decor.findViewById(
com.android.internal.R.id.action_bar_animator);
+ mActionView.setContextView(mUpperContextView);
if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 6a476d0..8918a8e 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -27,6 +27,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -35,9 +36,6 @@
* @hide
*/
public class ActionBarContextView extends ViewGroup {
- // TODO: This must be defined in the default theme
- private static final int CONTENT_HEIGHT_DIP = 50;
-
private int mItemPadding;
private int mItemMargin;
private int mActionSpacing;
@@ -75,11 +73,15 @@
com.android.internal.R.styleable.Theme_actionModeCloseDrawable);
mItemMargin = mItemPadding / 2;
- mContentHeight =
- (int) (CONTENT_HEIGHT_DIP * getResources().getDisplayMetrics().density + 0.5f);
+ mContentHeight = a.getLayoutDimension(
+ com.android.internal.R.styleable.Theme_windowActionBarSize, 0);
a.recycle();
}
+ public void setHeight(int height) {
+ mContentHeight = height;
+ }
+
public void setCustomView(View view) {
if (mCustomView != null) {
removeView(mCustomView);
@@ -208,8 +210,12 @@
final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
final int itemMargin = mItemPadding;
+ int maxHeight = mContentHeight > 0 ?
+ mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
+
+ final int verticalPadding = getPaddingTop() + getPaddingBottom();
int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
- final int height = mContentHeight - getPaddingTop() - getPaddingBottom();
+ final int height = maxHeight - verticalPadding;
final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
if (mCloseButton != null) {
@@ -246,7 +252,20 @@
MeasureSpec.makeMeasureSpec(customHeight, customHeightMode));
}
- setMeasuredDimension(contentWidth, mContentHeight);
+ if (mContentHeight <= 0) {
+ int measuredHeight = 0;
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View v = getChildAt(i);
+ int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
+ if (paddedViewHeight > measuredHeight) {
+ measuredHeight = paddedViewHeight;
+ }
+ }
+ setMeasuredDimension(contentWidth, measuredHeight);
+ } else {
+ setMeasuredDimension(contentWidth, maxHeight);
+ }
}
@Override
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 73d3c95..c3c0db2 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -53,7 +53,6 @@
private static final String TAG = "ActionBarView";
// TODO: This must be defined in the default theme
- private static final int CONTENT_HEIGHT_DIP = 50;
private static final int CONTENT_PADDING_DIP = 3;
private static final int CONTENT_SPACING_DIP = 6;
private static final int CONTENT_ACTION_SPACING_DIP = 12;
@@ -90,12 +89,17 @@
private LinearLayout mTabLayout;
private View mCustomNavView;
+ private int mTitleStyleRes;
+ private int mSubtitleStyleRes;
+
private boolean mShowMenu;
private boolean mUserTitle;
private MenuBuilder mOptionsMenu;
private ActionMenuView mMenuView;
+ private ActionBarContextView mContextView;
+
private ActionMenuItem mLogoNavItem;
private NavigationCallback mCallback;
@@ -151,6 +155,9 @@
setBackgroundDrawable(background);
}
+ mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
+ mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
+
final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
if (customNavId != 0) {
LayoutInflater inflater = LayoutInflater.from(context);
@@ -159,11 +166,7 @@
addView(mCustomNavView);
}
- final int padding = a.getDimensionPixelSize(R.styleable.ActionBar_padding,
- (int) (CONTENT_PADDING_DIP * metrics.density + 0.5f));
- setPadding(padding, padding, padding, padding);
- mContentHeight = a.getDimensionPixelSize(R.styleable.ActionBar_height,
- (int) (CONTENT_PADDING_DIP * metrics.density + 0.5f)) - padding * 2;
+ mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
a.recycle();
@@ -473,13 +476,22 @@
mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null);
mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
+
+ if (mTitleStyleRes != 0) {
+ mTitleView.setTextAppearance(mContext, mTitleStyleRes);
+ }
if (mTitle != null) {
mTitleView.setText(mTitle);
}
+
+ if (mSubtitleStyleRes != 0) {
+ mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
+ }
if (mSubtitle != null) {
mSubtitleView.setText(mSubtitle);
mSubtitleView.setVisibility(VISIBLE);
}
+
addView(mTitleLayout);
}
@@ -491,6 +503,10 @@
}
}
+ public void setContextView(ActionBarContextView view) {
+ mContextView = view;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@@ -506,9 +522,13 @@
}
int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
+
+ int maxHeight = mContentHeight > 0 ?
+ mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
+ final int verticalPadding = getPaddingTop() + getPaddingBottom();
int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
- final int height = mContentHeight - getPaddingTop() - getPaddingBottom();
+ final int height = maxHeight - verticalPadding;
final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
if (mLogoView != null && mLogoView.getVisibility() != GONE) {
@@ -561,7 +581,24 @@
break;
}
- setMeasuredDimension(contentWidth, mContentHeight);
+ if (mContentHeight <= 0) {
+ int measuredHeight = 0;
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View v = getChildAt(i);
+ int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
+ if (paddedViewHeight > measuredHeight) {
+ measuredHeight = paddedViewHeight;
+ }
+ }
+ setMeasuredDimension(contentWidth, measuredHeight);
+ } else {
+ setMeasuredDimension(contentWidth, maxHeight);
+ }
+
+ if (mContextView != null) {
+ mContextView.setHeight(getMeasuredHeight());
+ }
}
private int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) {
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index e1a6737..facda36 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -67,8 +67,22 @@
this(context, xmlLayoutResId, 0);
}
+ public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int width, int height) {
+ this(context, xmlLayoutResId, 0, width, height);
+ }
+
public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode) {
super(context, xmlLayoutResId, mode);
+ init(context);
+ }
+
+ public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode,
+ int width, int height) {
+ super(context, xmlLayoutResId, mode, width, height);
+ init(context);
+ }
+
+ private void init(Context context) {
final Resources res = context.getResources();
mRes = res;
mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 53720e4..384f7bc 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -54,10 +54,20 @@
private Vibrator mVibrator;
public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
+ this(context, keyboardView, targetView, true);
+ }
+
+ public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView,
+ boolean useFullScreenWidth) {
mContext = context;
mTargetView = targetView;
mKeyboardView = keyboardView;
- createKeyboards();
+ if (useFullScreenWidth || mKeyboardView.getLayoutParams().width == -1) {
+ createKeyboards();
+ } else {
+ createKeyboardsWithSpecificSize(mKeyboardView.getLayoutParams().width,
+ mKeyboardView.getLayoutParams().height);
+ }
mKeyboardView.setOnKeyboardActionListener(this);
mVibrator = new Vibrator();
}
@@ -66,6 +76,29 @@
return mKeyboardMode == KEYBOARD_MODE_ALPHA;
}
+ private void createKeyboardsWithSpecificSize(int viewWidth, int viewHeight) {
+ mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric,
+ viewWidth, viewHeight);
+ mQwertyKeyboard = new PasswordEntryKeyboard(mContext,
+ R.xml.password_kbd_qwerty, R.id.mode_normal, viewWidth, viewHeight);
+ mQwertyKeyboard.enableShiftLock();
+
+ mQwertyKeyboardShifted = new PasswordEntryKeyboard(mContext,
+ R.xml.password_kbd_qwerty_shifted,
+ R.id.mode_normal, viewWidth, viewHeight);
+ mQwertyKeyboardShifted.enableShiftLock();
+ mQwertyKeyboardShifted.setShifted(true); // always shifted.
+
+ mSymbolsKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_symbols,
+ viewWidth, viewHeight);
+ mSymbolsKeyboard.enableShiftLock();
+
+ mSymbolsKeyboardShifted = new PasswordEntryKeyboard(mContext,
+ R.xml.password_kbd_symbols_shift, viewWidth, viewHeight);
+ mSymbolsKeyboardShifted.enableShiftLock();
+ mSymbolsKeyboardShifted.setShifted(true); // always shifted
+ }
+
private void createKeyboards() {
mNumericKeyboard = new PasswordEntryKeyboard(mContext, R.xml.password_kbd_numeric);
mQwertyKeyboard = new PasswordEntryKeyboard(mContext,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index e4d4850..ca9f371 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -738,7 +738,7 @@
(void*) SkPaintGlue::getStringBounds },
{"nativeGetCharArrayBounds", "(I[CIILandroid/graphics/Rect;)V",
(void*) SkPaintGlue::getCharArrayBounds },
- {"setShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
+ {"nSetShadowLayer", "(FFFI)V", (void*)SkPaintGlue::setShadowLayer}
};
static jfieldID req_fieldID(jfieldID id) {
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 9f94af9..4c6eced 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -259,6 +259,7 @@
OpenGLRenderer* renderer) {
renderer->resetShader();
renderer->resetColorFilter();
+ renderer->resetShadow();
}
static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
@@ -271,6 +272,11 @@
renderer->setupColorFilter(filter);
}
+static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) {
+ renderer->setupShadow(radius, dx, dy, color);
+}
+
// ----------------------------------------------------------------------------
// Text
// ----------------------------------------------------------------------------
@@ -402,6 +408,7 @@
{ "nResetModifiers", "(I)V", (void*) android_view_GLES20Canvas_resetModifiers },
{ "nSetupShader", "(II)V", (void*) android_view_GLES20Canvas_setupShader },
{ "nSetupColorFilter", "(II)V", (void*) android_view_GLES20Canvas_setupColorFilter },
+ { "nSetupShadow", "(IFFFI)V", (void*) android_view_GLES20Canvas_setupShadow },
{ "nDrawText", "(I[CIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArray },
{ "nDrawText", "(ILjava/lang/String;IIFFII)V",
diff --git a/core/res/res/anim/push_down_in_no_alpha.xml b/core/res/res/anim/push_down_in_no_alpha.xml
new file mode 100644
index 0000000..045d691
--- /dev/null
+++ b/core/res/res/anim/push_down_in_no_alpha.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate android:fromYDelta="-100%p" android:toYDelta="0"
+ android:duration="@android:integer/config_longAnimTime"/>
+</set>
diff --git a/core/res/res/anim/push_down_out_no_alpha.xml b/core/res/res/anim/push_down_out_no_alpha.xml
new file mode 100644
index 0000000..3c2474a
--- /dev/null
+++ b/core/res/res/anim/push_down_out_no_alpha.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <translate android:fromYDelta="0" android:toYDelta="100%p"
+ android:duration="@android:integer/config_longAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png b/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png
new file mode 100644
index 0000000..336a820
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_charging.png b/core/res/res/drawable-xlarge/ic_lock_idle_charging.png
new file mode 100644
index 0000000..ebef531
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_charging.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_lock.png b/core/res/res/drawable-xlarge/ic_lock_idle_lock.png
new file mode 100644
index 0000000..405e218
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_lock.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png b/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png
new file mode 100644
index 0000000..f349b63
--- /dev/null
+++ b/core/res/res/drawable-xlarge/ic_lock_idle_low_battery.png
Binary files differ
diff --git a/core/res/res/layout-xlarge/keyguard.xml b/core/res/res/layout-xlarge/keyguard.xml
new file mode 100644
index 0000000..ca629f8
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/layout/keyguard.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingLeft="20dip"
+ android:paddingTop="20dip"
+ android:paddingRight="20dip"
+ android:paddingBottom="20dip"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="#ff000000">
+
+ <TextView
+ android:id="@+id/label"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:textColor="#FFFFFFFF"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/keyguard_label_text" />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
new file mode 100644
index 0000000..8a46546
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@android:color/background_dark"
+ >
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:layout_above="@+id/emergencyCall">
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <TextView
+ android:id="@+id/topHeader"
+ android:layout_width="match_parent"
+ android:layout_height="64dip"
+ android:layout_alignParentTop="true"
+ android:layout_marginLeft="4dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_vertical"
+ android:drawableLeft="@drawable/ic_lock_idle_lock"
+ android:drawablePadding="5dip"
+ />
+
+ <!-- spacer below header -->
+ <View
+ android:id="@+id/spacerTop"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_below="@id/topHeader"
+ android:background="@drawable/divider_horizontal_dark"/>
+
+ <TextView
+ android:id="@+id/instructions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/spacerTop"
+ android:layout_marginTop="8dip"
+ android:layout_marginLeft="9dip"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@android:string/lockscreen_glogin_instructions"
+ />
+
+ <EditText
+ android:id="@+id/login"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/instructions"
+ android:layout_marginTop="8dip"
+ android:layout_marginLeft="7dip"
+ android:layout_marginRight="7dip"
+ android:hint="@android:string/lockscreen_glogin_username_hint"
+ android:inputType="textEmailAddress"
+ />
+
+ <EditText
+ android:id="@+id/password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/login"
+ android:layout_marginTop="15dip"
+ android:layout_marginLeft="7dip"
+ android:layout_marginRight="7dip"
+ android:inputType="textPassword"
+ android:hint="@android:string/lockscreen_glogin_password_hint"
+ android:nextFocusRight="@+id/ok"
+ android:nextFocusDown="@+id/ok"
+ />
+
+ <!-- ok below password, aligned to right of screen -->
+ <Button
+ android:id="@+id/ok"
+ android:layout_width="85dip"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/password"
+ android:layout_marginTop="7dip"
+ android:layout_marginRight="7dip"
+ android:layout_alignParentRight="true"
+ android:text="@android:string/lockscreen_glogin_submit_button"
+ />
+
+ </RelativeLayout>
+ </ScrollView>
+
+ <!-- spacer above emergency call -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginBottom="4dip"
+
+ android:background="@drawable/divider_horizontal_dark"/>
+
+ <!-- emergency call button at bottom center -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@android:string/lockscreen_emergency_call"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_lock.xml b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
new file mode 100644
index 0000000..733a350
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+ state of the device, as well as instructions on how to get past it
+ depending on the state of the device. It is the same for landscape
+ and portrait.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:gravity="bottom"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#ff800000"
+ >
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginBottom="15dip"
+ android:layout_marginLeft="15dip"
+ android:layout_marginRight="15dip"
+ android:paddingTop="20dip"
+ android:paddingBottom="20dip"
+ android:background="@android:drawable/popup_full_dark"
+ >
+
+ <!-- when sim is present -->
+ <TextView android:id="@+id/headerSimOk1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textSize="34sp"/>
+ <TextView android:id="@+id/headerSimOk2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textSize="34sp"/>
+
+ <!-- when sim is missing / locked -->
+ <TextView android:id="@+id/headerSimBad1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@android:string/lockscreen_missing_sim_message"
+ android:textAppearance="?android:attr/textAppearanceLarge"/>
+ <TextView android:id="@+id/headerSimBad2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="7dip"
+ android:layout_marginBottom="7dip"
+ android:gravity="center"
+ android:text="@android:string/lockscreen_missing_sim_instructions"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+ <!-- spacer after carrier info / sim messages -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="8dip"
+ android:background="@android:drawable/divider_horizontal_dark"/>
+
+ <!-- time and date -->
+ <TextView android:id="@+id/time"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textSize="34sp"/>
+
+ <TextView android:id="@+id/date"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textSize="18sp"/>
+
+ <!-- spacer after time and date -->
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginBottom="8dip"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <!-- battery info -->
+ <LinearLayout android:id="@+id/batteryInfo"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ >
+
+ <ImageView android:id="@+id/batteryInfoIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="6dip"
+ android:baselineAligned="true"
+ android:gravity="center"
+ />
+
+ <TextView android:id="@+id/batteryInfoText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:gravity="center"
+ />
+
+ </LinearLayout>
+
+ <!-- spacer after battery info -->
+ <View android:id="@+id/batteryInfoSpacer"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <!-- next alarm info -->
+
+ <LinearLayout android:id="@+id/nextAlarmInfo"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="6dip"
+ android:baselineAligned="true"
+ android:src="@android:drawable/ic_lock_idle_alarm"
+ android:gravity="center"
+ />
+
+ <TextView android:id="@+id/nextAlarmText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:gravity="center"
+ />
+ </LinearLayout>
+
+ <!-- spacer after alarm info -->
+ <View android:id="@+id/nextAlarmSpacer"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ android:background="@android:drawable/divider_horizontal_dark"/>
+
+ <!-- lock icon with 'screen locked' message
+ (shown when SIM card is present) -->
+ <LinearLayout android:id="@+id/screenLockedInfo"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ >
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="6dip"
+ android:baselineAligned="true"
+ android:src="@android:drawable/ic_lock_idle_lock"
+ android:gravity="center"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@android:string/lockscreen_screen_locked"
+ android:gravity="center"
+ />
+ </LinearLayout>
+
+ <!-- message about how to unlock
+ (shown when SIM card is present) -->
+ <TextView android:id="@+id/lockInstructions"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="5dip"
+ android:gravity="center"
+ android:textSize="14sp"/>
+
+
+ <!-- emergency call button shown when sim is missing or PUKd -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="5dip"
+ android:layout_marginTop="5dip"
+ android:layout_gravity="center_horizontal"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@android:string/lockscreen_emergency_call"
+ />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
new file mode 100644
index 0000000..c2d87a2
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ >
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+ <include layout="@layout/keyguard_screen_status_land" />
+ </LinearLayout>
+
+ <!-- right side: password -->
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ android:gravity="center">
+
+ <!-- Password entry field -->
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="330dip"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:textSize="24sp"
+ android:layout_marginTop="120dip"
+ android:layout_marginBottom="5dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/password_field_default"
+ android:textColor="#ffffffff"
+ />
+
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="330dip"
+ android:layout_height="260dip"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ />
+ <!-- Alphanumeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+ android:layout_width="450dip"
+ android:layout_height="230dip"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ />
+
+ <!-- emergency call button -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@string/lockscreen_emergency_call"
+ android:visibility="gone"
+ style="@style/Widget.Button.Transparent"
+ />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
new file mode 100644
index 0000000..0927e59
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+ <include layout="@layout/keyguard_screen_status_land" />
+ </LinearLayout>
+
+ <!-- right side: password -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <!-- Password entry field -->
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="330dip"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:textSize="24sp"
+ android:layout_marginTop="120dip"
+ android:layout_marginBottom="5dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/password_field_default"
+ android:textColor="#ffffffff"
+ />
+
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="330dip"
+ android:layout_height="260dip"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ />
+ <!-- Alphanumeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+ android:layout_width="450dip"
+ android:layout_height="230dip"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ />
+
+ <!-- emergency call button -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@string/lockscreen_emergency_call"
+ android:visibility="gone"
+ style="@style/Widget.Button.Transparent"
+ />
+
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml
new file mode 100644
index 0000000..b8cbe51
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_landscape.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/background_dark"
+ >
+
+
+ <!-- right side -->
+ <!-- header text ('Enter Pin Code') -->
+ <TextView android:id="@+id/headerText"
+ android:layout_above="@+id/carrier"
+ android:layout_centerHorizontal="true"
+ android:layout_marginBottom="30dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="24sp"
+ />
+
+ <!-- Carrier info -->
+ <TextView android:id="@+id/carrier"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/pinDisplayGroup"
+ android:layout_marginTop="9dip"
+ android:gravity="left|bottom"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+
+ <!-- displays dots as user enters pin -->
+ <LinearLayout android:id="@+id/pinDisplayGroup"
+ android:orientation="horizontal"
+ android:layout_centerInParent="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:addStatesFromChildren="true"
+ android:gravity="center_vertical"
+ android:baselineAligned="false"
+ android:paddingRight="0dip"
+ android:layout_marginRight="30dip"
+ android:layout_marginLeft="30dip"
+ android:background="@android:drawable/edit_text"
+ >
+
+ <EditText android:id="@+id/pinDisplay"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:maxLines="1"
+ android:background="@null"
+ android:textSize="32sp"
+ android:inputType="textPassword"
+ />
+
+ <ImageButton android:id="@+id/backspace"
+ android:src="@android:drawable/ic_input_delete"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginTop="2dip"
+ android:layout_marginRight="2dip"
+ android:layout_marginBottom="2dip"
+ android:gravity="center"
+ />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_alignParentBottom="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dip"
+ android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip">
+
+ <Button android:id="@+id/ok"
+ android:text="@android:string/ok"
+ android:layout_alignParentBottom="true"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_marginBottom="8dip"
+ android:layout_marginRight="8dip"
+ android:textSize="18sp"
+ />
+
+ <Button android:id="@+id/emergencyCall"
+ android:text="@android:string/lockscreen_emergency_call"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_marginBottom="8dip"
+ android:layout_marginLeft="8dip"
+ android:textSize="18sp"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ />
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml
new file mode 100644
index 0000000..009148f
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_sim_pin_portrait.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@android:color/background_dark"
+ android:gravity="center_horizontal">
+
+ <LinearLayout android:id="@+id/topDisplayGroup"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <!-- header text ('Enter Pin Code') -->
+ <TextView android:id="@+id/headerText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+ <!-- Carrier info -->
+ <TextView android:id="@+id/carrier"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="9dip"
+ android:gravity="center"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+ <!-- password entry -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginRight="6dip"
+ android:layout_marginLeft="6dip"
+ android:gravity="center_vertical"
+ android:background="@android:drawable/edit_text">
+
+ <!-- displays dots as user enters pin -->
+ <TextView android:id="@+id/pinDisplay"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:maxLines="1"
+ android:textAppearance="?android:attr/textAppearanceLargeInverse"
+ android:textStyle="bold"
+ android:inputType="textPassword"
+ />
+
+ <ImageButton android:id="@+id/backspace"
+ android:src="@android:drawable/ic_input_delete"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="-3dip"
+ android:layout_marginBottom="-3dip"
+ />
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <include
+ android:id="@+id/keyPad"
+ layout="@android:layout/twelve_key_entry"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/topDisplayGroup"
+ android:layout_marginTop="10dip"
+ />
+
+ <!-- spacer below keypad -->
+ <View
+ android:id="@+id/spacerBottom"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="6dip"
+ android:layout_above="@id/emergencyCall"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <!-- The emergency button should take the rest of the space and be centered vertically -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <!-- emergency call button -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@android:drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@android:string/lockscreen_emergency_call"
+ />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_status_land.xml b/core/res/res/layout-xlarge/keyguard_screen_status_land.xml
new file mode 100644
index 0000000..8589862
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_status_land.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<!-- Status to show on the left side of lock screen -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="140dip"
+ android:layout_marginTop="20dip"
+ android:gravity="left"
+ >
+
+ <TextView
+ android:id="@+id/carrier"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="17sp"
+ android:drawablePadding="4dip"
+ android:layout_marginTop="32dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ />
+
+ <com.android.internal.widget.DigitalClock android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ >
+
+ <TextView android:id="@+id/timeDisplay"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:textSize="120sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:shadowColor="#C0000000"
+ android:shadowDx="0"
+ android:shadowDy="0"
+ android:shadowRadius="3.0"
+ android:layout_marginBottom="6dip"
+ />
+
+
+ <TextView android:id="@+id/am_pm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/timeDisplay"
+ android:layout_alignBaseline="@id/timeDisplay"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:textSize="30sp"
+ android:layout_marginLeft="8dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:shadowColor="#C0000000"
+ android:shadowDx="0"
+ android:shadowDy="0"
+ android:shadowRadius="3.0"
+ />
+
+ </com.android.internal.widget.DigitalClock>
+
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/time"
+ android:layout_marginTop="5dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="32sp"
+ />
+
+ <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+ status. -->
+ <TextView
+ android:id="@+id/status2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="32sp"
+ android:layout_marginTop="50dip"
+ android:drawablePadding="4dip"
+ />
+ <TextView
+ android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="15dip"
+ android:textSize="32sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+
+ <TextView
+ android:id="@+id/propertyOf"
+ android:lineSpacingExtra="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="22sp"
+ android:layout_marginTop="50dip"
+ android:singleLine="false"
+ android:visibility="invisible"
+ />
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_status_port.xml b/core/res/res/layout-xlarge/keyguard_screen_status_port.xml
new file mode 100644
index 0000000..8589862
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_status_port.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2010, 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.
+*/
+-->
+
+<!-- Status to show on the left side of lock screen -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="140dip"
+ android:layout_marginTop="20dip"
+ android:gravity="left"
+ >
+
+ <TextView
+ android:id="@+id/carrier"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="17sp"
+ android:drawablePadding="4dip"
+ android:layout_marginTop="32dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ />
+
+ <com.android.internal.widget.DigitalClock android:id="@+id/time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ >
+
+ <TextView android:id="@+id/timeDisplay"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:textSize="120sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:shadowColor="#C0000000"
+ android:shadowDx="0"
+ android:shadowDy="0"
+ android:shadowRadius="3.0"
+ android:layout_marginBottom="6dip"
+ />
+
+
+ <TextView android:id="@+id/am_pm"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/timeDisplay"
+ android:layout_alignBaseline="@id/timeDisplay"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:textSize="30sp"
+ android:layout_marginLeft="8dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:shadowColor="#C0000000"
+ android:shadowDx="0"
+ android:shadowDy="0"
+ android:shadowRadius="3.0"
+ />
+
+ </com.android.internal.widget.DigitalClock>
+
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/time"
+ android:layout_marginTop="5dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="32sp"
+ />
+
+ <!-- used for instructions such as "draw pattern to unlock", the next alarm, and charging
+ status. -->
+ <TextView
+ android:id="@+id/status2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="32sp"
+ android:layout_marginTop="50dip"
+ android:drawablePadding="4dip"
+ />
+ <TextView
+ android:id="@+id/status1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="15dip"
+ android:textSize="32sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+
+ <TextView
+ android:id="@+id/propertyOf"
+ android:lineSpacingExtra="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="22sp"
+ android:layout_marginTop="50dip"
+ android:singleLine="false"
+ android:visibility="invisible"
+ />
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
new file mode 100644
index 0000000..4761800
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+ state of the device, as well as instructions on how to get past it
+ depending on the state of the device. It is the same for landscape
+ and portrait.-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#70000000"
+ android:gravity="center_horizontal"
+ android:id="@+id/root">
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+ <include layout="@layout/keyguard_screen_status_land" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ >
+ <TextView
+ android:id="@+id/screenLocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/status2"
+ android:layout_marginLeft="24dip"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:layout_marginTop="12dip"
+ android:drawablePadding="4dip"
+ />
+
+ <com.android.internal.widget.SlidingTab
+ android:id="@+id/tab_selector"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="80dip"
+ />
+
+ <!-- "emergency calls only" shown when sim is missing or PUKd -->
+ <TextView
+ android:id="@+id/emergencyCallText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/carrier"
+ android:layout_alignParentRight="true"
+ android:layout_marginTop="0dip"
+ android:layout_marginRight="8dip"
+ android:text="@string/emergency_calls_only"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="@color/white"
+ />
+
+ <!-- emergency call button shown when sim is PUKd and tab_selector is
+ hidden -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:layout_centerInParent="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="80dip"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+
+</RelativeLayout>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
new file mode 100644
index 0000000..bb398f6
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is the general lock screen which shows information about the
+ state of the device, as well as instructions on how to get past it
+ depending on the state of the device.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:background="#70000000"
+ android:id="@+id/root">
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+ <include layout="@layout/keyguard_screen_status_land" />
+ </LinearLayout>
+
+ <!-- right side -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:orientation="horizontal"
+ android:gravity="center_horizontal"
+ >
+ <TextView
+ android:id="@+id/screenLocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/status2"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center"
+ android:layout_marginTop="12dip"
+ android:drawablePadding="4dip"
+ />
+
+ <com.android.internal.widget.SlidingTab
+ android:id="@+id/tab_selector"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginRight="0dip"
+ android:layout_weight="1.0"
+ />
+
+ <!-- "emergency calls only" shown when sim is missing or PUKd -->
+ <TextView
+ android:id="@+id/emergencyCallText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="20dip"
+ android:text="@string/emergency_calls_only"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="@color/white"
+ />
+
+ <!-- emergency call button shown when sim is PUKd and tab_selector is
+ hidden -->
+ <Button
+ android:id="@+id/emergencyCallButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
+ android:drawablePadding="8dip"
+ android:layout_marginRight="80dip"
+ android:visibility="gone"
+ />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
new file mode 100644
index 0000000..42636ad
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<!-- This is the screen that shows the 9 circle unlock widget and instructs
+ the user how to unlock their device, or make an emergency call. This
+ is the portrait layout. -->
+
+<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+
+ <include layout="@layout/keyguard_screen_status_land" />
+
+ <!-- footer -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="140dip"
+ >
+
+ <!-- option 1: a single emergency call button -->
+ <RelativeLayout android:id="@+id/footerNormal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="left"
+ >
+ <Button android:id="@+id/emergencyCallAlone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockscreen_emergency_call"
+ style="@style/Widget.Button.Transparent"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:visibility="gone"
+ />
+ </RelativeLayout>
+
+ <!-- option 2: an emergency call button, and a 'forgot pattern?' button -->
+ <LinearLayout android:id="@+id/footerForgotPattern"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="left"
+ >
+ <Button android:id="@+id/forgotPattern"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/Widget.Button.Transparent"
+ />
+ <Button android:id="@+id/emergencyCallTogether"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/lockscreen_emergency_call"
+ style="@style/Widget.Button.Transparent"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+
+ <!-- right side: lock pattern -->
+ <LinearLayout
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ >
+ <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
+ android:layout_width="350dip"
+ android:layout_height="350dip"
+ android:layout_marginTop="90dip"
+ android:layout_marginRight="90dip"
+ />
+ </LinearLayout>
+
+</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
new file mode 100644
index 0000000..aeed79b
--- /dev/null
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <!-- left side: status and emergency call button -->
+ <LinearLayout
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ >
+
+ <include layout="@layout/keyguard_screen_status_port" />
+
+ <!-- footer -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="140dip"
+ >
+
+ <!-- option 1: a single emergency call button -->
+ <RelativeLayout android:id="@+id/footerNormal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="left"
+ >
+ <Button android:id="@+id/emergencyCallAlone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/lockscreen_emergency_call"
+ style="@style/Widget.Button.Transparent"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:visibility="gone"
+ />
+ </RelativeLayout>
+
+ <!-- option 2: an emergency call button, and a 'forgot pattern?' button -->
+ <LinearLayout android:id="@+id/footerForgotPattern"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="left"
+ >
+ <Button android:id="@+id/forgotPattern"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/Widget.Button.Transparent"
+ />
+ <Button android:id="@+id/emergencyCallTogether"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/lockscreen_emergency_call"
+ style="@style/Widget.Button.Transparent"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+
+ <!-- right side: lock pattern -->
+ <LinearLayout
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:gravity="center"
+ >
+ <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
+ android:layout_width="350dip"
+ android:layout_height="350dip"
+ android:layout_marginTop="50dip"
+ />
+ </LinearLayout>
+
+</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
+
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index 41ce8e4..30a73184 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -24,8 +24,8 @@
<ViewAnimator android:id="@+id/action_bar_animator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:inAnimation="@anim/push_down_in"
- android:outAnimation="@anim/push_down_out">
+ android:inAnimation="@anim/push_down_in_no_alpha"
+ android:outAnimation="@anim/push_down_out_no_alpha">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
android:layout_width="match_parent"
diff --git a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
index d0277f0..cb35ac1 100644
--- a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
@@ -28,8 +28,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
- android:inAnimation="@anim/push_down_in"
- android:outAnimation="@anim/push_down_out">
+ android:inAnimation="@anim/push_down_in_no_alpha"
+ android:outAnimation="@anim/push_down_out_no_alpha">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
android:layout_width="match_parent"
@@ -41,6 +41,7 @@
android:layout_height="wrap_content" />
</ViewAnimator>
<ImageView android:src="?android:attr/windowContentOverlay"
+ android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/action_bar_animator" />
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index ab675c7..3d52f71 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -28,7 +28,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- "Enter PIN(Password) to unlock" -->
- <TextView android:id="@+id/enter_password_label"
+ <TextView android:id="@+id/status1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 9ee8781..af8a3ef 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -24,7 +24,7 @@
android:gravity="center_horizontal">
<!-- "Enter PIN(Password) to unlock" -->
- <TextView android:id="@+id/enter_password_label"
+ <TextView android:id="@+id/status1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index f39852b..3c44b8c 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -24,8 +24,8 @@
<ViewAnimator android:id="@+id/action_bar_animator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:inAnimation="@anim/push_down_in"
- android:outAnimation="@anim/push_down_out">
+ android:inAnimation="@anim/push_down_in_no_alpha"
+ android:outAnimation="@anim/push_down_out_no_alpha">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
android:layout_width="match_parent"
diff --git a/core/res/res/layout/screen_action_bar_overlay.xml b/core/res/res/layout/screen_action_bar_overlay.xml
index cb1ffc5..c854c6f 100644
--- a/core/res/res/layout/screen_action_bar_overlay.xml
+++ b/core/res/res/layout/screen_action_bar_overlay.xml
@@ -28,8 +28,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
- android:inAnimation="@anim/push_down_in"
- android:outAnimation="@anim/push_down_out">
+ android:inAnimation="@anim/push_down_in_no_alpha"
+ android:outAnimation="@anim/push_down_out_no_alpha">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
android:layout_width="match_parent"
@@ -41,6 +41,7 @@
android:layout_height="wrap_content" />
</ViewAnimator>
<ImageView android:src="?android:attr/windowContentOverlay"
+ android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/action_bar_animator" />
diff --git a/core/res/res/values-xlarge/config.xml b/core/res/res/values-xlarge/config.xml
index c5a53b2..e92ed11 100644
--- a/core/res/res/values-xlarge/config.xml
+++ b/core/res/res/values-xlarge/config.xml
@@ -24,5 +24,10 @@
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent">com.android.systemui/com.android.systemui.statusbar.tablet.TabletStatusBarService</string>
<bool name="config_statusBarCanHide">false</bool>
+
+ <!-- Show sliding tab before lockscreen -->
+ <bool name="config_enableSlidingTabFirst">false</bool>
+ <!-- Enable lockscreen rotation -->
+ <bool name="config_enableLockScreenRotation">true</bool>
</resources>
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index b3fdf46..bc1ae58 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -22,5 +22,10 @@
<!-- Height of the status bar -->
<dimen name="status_bar_icon_size">50dip</dimen>
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
+
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
+ <!-- Default height of a key in the password keyboard for numeric -->
+ <dimen name="password_keyboard_key_height_numeric">0.47in</dimen>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a75f1a6..e0608f9 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -256,6 +256,12 @@
<!-- Reference to a style for the Action Bar -->
<attr name="windowActionBarStyle" format="reference" />
+ <!-- Size of the Action Bar, including the contextual
+ bar used to present Action Modes. -->
+ <attr name="windowActionBarSize" format="dimension" >
+ <enum name="wrap_content" value="0" />
+ </attr>
+
<!-- Flag indicating whether action modes should overlay window content
when there is not reserved space for their UI (such as an Action Bar). -->
<attr name="windowActionModeOverlay" format="boolean" />
@@ -1005,6 +1011,7 @@
<attr name="windowActionBarStyle" />
<attr name="windowActionModeOverlay" />
<attr name="windowActionBarOverlay" />
+ <attr name="windowActionBarSize" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
@@ -4003,8 +4010,6 @@
<attr name="customNavigationLayout" format="reference" />
<!-- Specifies a fixed height. -->
<attr name="height" />
- <!-- Specifies padding around all sides. -->
- <attr name="padding" />
</declare-styleable>
</resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index b6af6b2..a2316e0 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -18,8 +18,8 @@
*/
-->
<resources>
- <drawable name="screen_background_light">#ffffffff</drawable>
- <drawable name="screen_background_dark">#ff000000</drawable>
+ <drawable name="screen_background_light">#ffefefef</drawable>
+ <drawable name="screen_background_dark">#ff101010</drawable>
<drawable name="status_bar_closed_default_background">#ff000000</drawable>
<drawable name="status_bar_opened_default_background">#ff000000</drawable>
<drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,18 +36,18 @@
<color name="white">#ffffffff</color>
<color name="black">#ff000000</color>
<color name="transparent">#00000000</color>
- <color name="background_dark">#ff000000</color>
- <color name="bright_foreground_dark">#ffffffff</color>
+ <color name="background_dark">#ff101010</color>
+ <color name="bright_foreground_dark">#ffefefef</color>
<color name="bright_foreground_dark_disabled">#80ffffff</color>
- <color name="bright_foreground_dark_inverse">#ff000000</color>
+ <color name="bright_foreground_dark_inverse">@android:color/background_dark</color>
<color name="dim_foreground_dark">#bebebe</color>
<color name="dim_foreground_dark_disabled">#80bebebe</color>
<color name="dim_foreground_dark_inverse">#323232</color>
<color name="dim_foreground_dark_inverse_disabled">#80323232</color>
<color name="hint_foreground_dark">#808080</color>
- <color name="background_light">#ffffffff</color>
- <color name="bright_foreground_light">#ff000000</color>
- <color name="bright_foreground_light_inverse">#ffffffff</color>
+ <color name="background_light">@android:color/bright_foreground_dark</color>
+ <color name="bright_foreground_light">@android:color/background_dark</color>
+ <color name="bright_foreground_light_inverse">@android:color/bright_foreground_dark</color>
<color name="bright_foreground_light_disabled">#80000000</color>
<color name="dim_foreground_light">#323232</color>
<color name="dim_foreground_light_disabled">#80323232</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cf2b423..91e9a92 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -272,6 +272,12 @@
<!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
<bool name="config_disableMenuKeyInLockScreen">false</bool>
+ <!-- Show sliding tab before lockscreen -->
+ <bool name="config_enableSlidingTabFirst">true</bool>
+
+ <!-- Diable lockscreen rotation by default -->
+ <bool name="config_enableLockScreenRotation">false</bool>
+
<!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
The N entries of this array define N + 1 zones as follows:
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 679e642..fdafaf1 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -41,8 +41,10 @@
<dimen name="fastscroll_thumb_width">64dp</dimen>
<!-- Height of the fastscroll thumb -->
<dimen name="fastscroll_thumb_height">52dp</dimen>
- <!-- Default height of a key in the password keyboard -->
- <dimen name="password_keyboard_key_height">56dip</dimen>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">56dip</dimen>
+ <!-- Default height of a key in the password keyboard for numeric -->
+ <dimen name="password_keyboard_key_height_numeric">56dip</dimen>
<!-- Default correction for the space key in the password keyboard -->
<dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
<!-- Distance between the text base line and virtual finger position used to position cursor -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 539f1c0..b84a613 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1320,6 +1320,8 @@
<public type="attr" name="fragmentOpenExitAnimation" />
<public type="attr" name="fragmentCloseEnterAnimation" />
<public type="attr" name="fragmentCloseExitAnimation" />
+ <public type="attr" name="windowActionBarSize" />
+
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 7e52ebd..2ae3ccd 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -893,8 +893,11 @@
<item name="android:background">@android:drawable/action_bar_background</item>
<item name="android:displayOptions">useLogo</item>
<item name="android:divider">@android:drawable/action_bar_divider</item>
- <item name="android:height">56dip</item>
- <item name="android:padding">3dip</item>
+ <item name="android:height">?android:attr/windowActionBarSize</item>
+ <item name="android:paddingLeft">3dip</item>
+ <item name="android:paddingTop">3dip</item>
+ <item name="android:paddingRight">3dip</item>
+ <item name="android:paddingBottom">3dip</item>
</style>
<style name="Widget.ActionButton">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3348b4e..f9e20f7 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -118,6 +118,7 @@
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">false</item>
<item name="windowActionBarStyle">@android:style/ActionBar</item>
+ <item name="windowActionBarSize">50dip</item>
<!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog</item>
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
index 700c527..fd8bd49 100755
--- a/core/res/res/xml-land/password_kbd_qwerty.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row>
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
index 1e37b6c..9ff6fd7 100755
--- a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty.xml b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
index bae1b42..82a7c75 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row>
diff --git a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
index 612df9c..9fff3cc 100755
--- a/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-mdpi/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
new file mode 100755
index 0000000..0a35040
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+ >
+
+ <Row android:rowEdgeFlags="top">
+ <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="2"/>
+ <Key android:keyLabel="3"/>
+ <Key android:keyLabel="4"/>
+ <Key android:keyLabel="5"/>
+ <Key android:keyLabel="6"/>
+ <Key android:keyLabel="7"/>
+ <Key android:keyLabel="8"/>
+ <Key android:keyLabel="9"/>
+ <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="w"/>
+ <Key android:keyLabel="e"/>
+ <Key android:keyLabel="r"/>
+ <Key android:keyLabel="t"/>
+ <Key android:keyLabel="y"/>
+ <Key android:keyLabel="u"/>
+ <Key android:keyLabel="i"/>
+ <Key android:keyLabel="o"/>
+ <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:keyLabel="a" android:horizontalGap="5%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="s"/>
+ <Key android:keyLabel="d"/>
+ <Key android:keyLabel="f"/>
+ <Key android:keyLabel="g"/>
+ <Key android:keyLabel="h"/>
+ <Key android:keyLabel="j"/>
+ <Key android:keyLabel="k"/>
+ <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15%p" android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="z"/>
+ <Key android:keyLabel="x"/>
+ <Key android:keyLabel="c"/>
+ <Key android:keyLabel="v"/>
+ <Key android:keyLabel="b"/>
+ <Key android:keyLabel="n"/>
+ <Key android:keyLabel="m"/>
+ <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+ android:keyWidth="15%p" android:keyEdgeFlags="right"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"/>
+ </Row>
+
+ <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
+ <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="," />
+ <Key android:keyLabel="-" />
+ <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="20%p"/>
+ <Key android:keyLabel="=" />
+ <Key android:keyLabel="."
+ android:keyWidth="10%p"/>
+ <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
new file mode 100755
index 0000000..9e9db81
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+ >
+
+ <Row android:rowEdgeFlags="top">
+ <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\#"/>
+ <Key android:keyLabel="$"/>
+ <Key android:keyLabel="%"/>
+ <Key android:keyLabel="&"/>
+ <Key android:keyLabel="*"/>
+ <Key android:keyLabel="-"/>
+ <Key android:keyLabel="+"/>
+ <Key android:keyLabel="("/>
+ <Key android:keyLabel=")" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="w"/>
+ <Key android:keyLabel="e"/>
+ <Key android:keyLabel="r"/>
+ <Key android:keyLabel="t"/>
+ <Key android:keyLabel="y"/>
+ <Key android:keyLabel="u"/>
+ <Key android:keyLabel="i"/>
+ <Key android:keyLabel="o"/>
+ <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:keyLabel="a" android:horizontalGap="5%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="s"/>
+ <Key android:keyLabel="d"/>
+ <Key android:keyLabel="f"/>
+ <Key android:keyLabel="g"/>
+ <Key android:keyLabel="h"/>
+ <Key android:keyLabel="j"/>
+ <Key android:keyLabel="k"/>
+ <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row>
+ <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15%p" android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="z"/>
+ <Key android:keyLabel="x"/>
+ <Key android:keyLabel="c"/>
+ <Key android:keyLabel="v"/>
+ <Key android:keyLabel="b"/>
+ <Key android:keyLabel="n"/>
+ <Key android:keyLabel="m"/>
+ <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
+ android:keyWidth="15%p" android:keyEdgeFlags="right"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"/>
+ </Row>
+
+ <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
+ <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="20%p" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="," />
+ <Key android:keyLabel="_" />
+ <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="20%p"/>
+ <Key android:keyLabel="+" />
+ <Key android:keyLabel="."/>
+ <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml/password_kbd_extension.xml b/core/res/res/xml/password_kbd_extension.xml
index 28b7efe..f3fa57b 100755
--- a/core/res/res/xml/password_kbd_extension.xml
+++ b/core/res/res/xml/password_kbd_extension.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
index bdd8afb..2270b8a 100755
--- a/core/res/res/xml/password_kbd_numeric.xml
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -19,9 +19,8 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="33.33%p"
- android:horizontalGap="2px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_numeric"
>
<Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_popup_template.xml b/core/res/res/xml/password_kbd_popup_template.xml
index 5ddfd3e..9b853e2 100644
--- a/core/res/res/xml/password_kbd_popup_template.xml
+++ b/core/res/res/xml/password_kbd_popup_template.xml
@@ -22,6 +22,6 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
</Keyboard>
diff --git a/core/res/res/xml/password_kbd_qwerty.xml b/core/res/res/xml/password_kbd_qwerty.xml
index 5fa9b8a..0a35040 100755
--- a/core/res/res/xml/password_kbd_qwerty.xml
+++ b/core/res/res/xml/password_kbd_qwerty.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_qwerty_shifted.xml b/core/res/res/xml/password_kbd_qwerty_shifted.xml
index e491aff..9e9db81 100755
--- a/core/res/res/xml/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml/password_kbd_qwerty_shifted.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_symbols.xml b/core/res/res/xml/password_kbd_symbols.xml
index 9901526..9a94930 100755
--- a/core/res/res/xml/password_kbd_symbols.xml
+++ b/core/res/res/xml/password_kbd_symbols.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row android:rowEdgeFlags="top">
diff --git a/core/res/res/xml/password_kbd_symbols_shift.xml b/core/res/res/xml/password_kbd_symbols_shift.xml
index 5b73914..a972eb2 100755
--- a/core/res/res/xml/password_kbd_symbols_shift.xml
+++ b/core/res/res/xml/password_kbd_symbols_shift.xml
@@ -22,7 +22,7 @@
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
- android:keyHeight="@dimen/password_keyboard_key_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
>
<Row android:rowEdgeFlags="top">
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 6349cb3..62fbfb4 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -43,6 +43,28 @@
private boolean mHasCompatScaling;
private float mCompatScaling;
private float mInvCompatScaling;
+
+ /**
+ * @hide
+ */
+ public boolean hasShadow;
+ /**
+ * @hide
+ */
+ public float shadowDx;
+ /**
+ * @hide
+ */
+ public float shadowDy;
+ /**
+ * @hide
+ */
+ public float shadowRadius;
+ /**
+ * @hide
+ */
+ public int shadowColor;
+
/**
* @hide
*/
@@ -935,13 +957,23 @@
* offset and color, and blur radius. If radius is 0, then the shadow
* layer is removed.
*/
- public native void setShadowLayer(float radius, float dx, float dy, int color);
+ public void setShadowLayer(float radius, float dx, float dy, int color) {
+ hasShadow = radius > 0.0f;
+ shadowRadius = radius;
+ shadowDx = dx;
+ shadowDy = dy;
+ shadowColor = color;
+ nSetShadowLayer(radius, dx, dy, color);
+ }
+
+ private native void nSetShadowLayer(float radius, float dx, float dy, int color);
/**
* Clear the shadow layer.
*/
public void clearShadowLayer() {
- setShadowLayer(0, 0, 0, 0);
+ hasShadow = false;
+ nSetShadowLayer(0, 0, 0, 0);
}
/**
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 8fea91f..889bf7b 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -28,6 +28,11 @@
public Float2() {
}
+ public Float2(float initX, float initY) {
+ x = initX;
+ y = initY;
+ }
+
public float x;
public float y;
}
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index 9d9e406..ebe140d 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -27,6 +27,11 @@
public class Float3 {
public Float3() {
}
+ public Float3(float initX, float initY, float initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
public float x;
public float y;
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index a703e80..847732f 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -28,6 +28,13 @@
public Float4() {
}
+ public Float4(float initX, float initY, float initZ, float initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
public float x;
public float y;
public float z;
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 1efe6b5..8ed3d7b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -17,7 +17,8 @@
ProgramCache.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
- TextureCache.cpp
+ TextureCache.cpp \
+ TextDropShadowCache.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index e807aba..ccc92eb 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -128,8 +128,11 @@
}
Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) {
- CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
- if (cachedGlyph == NULL) {
+ CachedGlyphInfo* cachedGlyph = NULL;
+ ssize_t index = mCachedGlyphs.indexOfKey(utfChar);
+ if (index >= 0) {
+ cachedGlyph = mCachedGlyphs.valueAt(index);
+ } else {
cachedGlyph = cacheGlyph(paint, utfChar);
}
@@ -510,10 +513,10 @@
uint32_t yOffset = cl->mCurrentRow;
uint32_t width = mCacheWidth;
uint32_t height = cl->mMaxHeight;
- void* textureData = mTextTexture + yOffset*width;
+ void* textureData = mTextTexture + yOffset*width;
glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height,
- GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
+ GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
cl->mDirty = false;
}
@@ -617,21 +620,33 @@
}
}
FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
- uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
+ uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius) {
+ checkInit();
+
+ if (!mCurrentFont) {
+ DropShadow image;
+ image.width = 0;
+ image.height = 0;
+ image.image = NULL;
+ image.penX = 0;
+ image.penY = 0;
+ return image;
+ }
Rect bounds;
mCurrentFont->measureUTF(paint, text, startIndex, len, numGlyphs, &bounds);
- uint32_t paddedWidth = (uint32_t)(bounds.right - bounds.left) + 2*radius;
- uint32_t paddedHeight = (uint32_t)(bounds.top - bounds.bottom) + 2*radius;
+ uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius;
+ uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius;
uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight];
- for(uint32_t i = 0; i < paddedWidth * paddedHeight; i ++) {
+ for (uint32_t i = 0; i < paddedWidth * paddedHeight; i++) {
dataBuffer[i] = 0;
}
+
int penX = radius - bounds.left;
int penY = radius - bounds.bottom;
mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, penX, penY,
- dataBuffer, paddedWidth, paddedHeight);
+ dataBuffer, paddedWidth, paddedHeight);
blurImage(dataBuffer, paddedWidth, paddedHeight, radius);
DropShadow image;
@@ -699,8 +714,7 @@
}
void FontRenderer::horizontalBlur(float* weights, int32_t radius,
- const uint8_t* source, uint8_t* dest,
- int32_t width, int32_t height) {
+ const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
float blurredPixel = 0.0f;
float currentPixel = 0.0f;
@@ -744,8 +758,7 @@
}
void FontRenderer::verticalBlur(float* weights, int32_t radius,
- const uint8_t* source, uint8_t* dest,
- int32_t width, int32_t height) {
+ const uint8_t* source, uint8_t* dest, int32_t width, int32_t height) {
float blurredPixel = 0.0f;
float currentPixel = 0.0f;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 6346ded..96c92d5 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -129,6 +129,14 @@
uint32_t len, int numGlyphs, int x, int y);
struct DropShadow {
+ DropShadow() { };
+
+ DropShadow(const DropShadow& dropShadow):
+ width(dropShadow.width), height(dropShadow.height),
+ image(dropShadow.image), penX(dropShadow.penX),
+ penY(dropShadow.penY) {
+ }
+
uint32_t width;
uint32_t height;
uint8_t* image;
@@ -139,7 +147,7 @@
// After renderDropShadow returns, the called owns the memory in DropShadow.image
// and is responsible for releasing it when it's done with it
DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
- uint32_t len, int numGlyphs, uint32_t radius);
+ uint32_t len, int numGlyphs, uint32_t radius);
GLuint getTexture() {
checkInit();
@@ -154,7 +162,7 @@
uint16_t mMaxWidth;
uint32_t mCurrentRow;
uint32_t mCurrentCol;
- bool mDirty;
+ bool mDirty;
CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
uint32_t currentCol):
@@ -237,9 +245,9 @@
void computeGaussianWeights(float* weights, int32_t radius);
void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
- int32_t width, int32_t height);
+ int32_t width, int32_t height);
void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
- int32_t width, int32_t height);
+ int32_t width, int32_t height);
void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
};
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3c1fe2a..da5b9dd 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -41,6 +41,7 @@
#define DEFAULT_PATH_CACHE_SIZE 6.0f
#define DEFAULT_PATCH_CACHE_SIZE 100
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
+#define DEFAULT_DROP_SHADOW_CACHE_SIZE 1.0f
#define REQUIRED_TEXTURE_UNITS_COUNT 3
@@ -107,7 +108,8 @@
mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)),
mGradientCache(MB(DEFAULT_GRADIENT_CACHE_SIZE)),
mPathCache(MB(DEFAULT_PATH_CACHE_SIZE)),
- mPatchCache(DEFAULT_PATCH_CACHE_SIZE) {
+ mPatchCache(DEFAULT_PATCH_CACHE_SIZE),
+ mDropShadowCache(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) {
LOGD("Create OpenGLRenderer");
char property[PROPERTY_VALUE_MAX];
@@ -139,9 +141,18 @@
LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE);
}
+ if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) {
+ LOGD(" Setting drop shadow cache size to %sMB", property);
+ mDropShadowCache.setMaxSize(MB(atof(property)));
+ } else {
+ LOGD(" Using default drop shadow cache size of %.2fMB", DEFAULT_DROP_SHADOW_CACHE_SIZE);
+ }
+ mDropShadowCache.setFontRenderer(mFontRenderer);
+
mCurrentProgram = NULL;
mShader = NULL;
mColorFilter = NULL;
+ mHasShadow = false;
memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));
@@ -163,6 +174,7 @@
mPathCache.clear();
mPatchCache.clear();
mProgramCache.clear();
+ mDropShadowCache.clear();
}
///////////////////////////////////////////////////////////////////////////////
@@ -550,6 +562,78 @@
drawColorRect(left, top, right, bottom, color, mode);
}
+void OpenGLRenderer::renderShadow(const ShadowTexture* texture, float x, float y,
+ SkXfermode::Mode mode) {
+ const float sx = x - texture->left + mShadowDx;
+ const float sy = y - texture->top + mShadowDy;
+
+ const GLfloat a = ((mShadowColor >> 24) & 0xFF) / 255.0f;
+ const GLfloat r = a * ((mShadowColor >> 16) & 0xFF) / 255.0f;
+ const GLfloat g = a * ((mShadowColor >> 8) & 0xFF) / 255.0f;
+ const GLfloat b = a * ((mShadowColor ) & 0xFF) / 255.0f;
+
+ GLuint textureUnit = 0;
+ renderTextureAlpha8(texture, textureUnit, sx, sy, r, g, b, a, mode, false);
+}
+
+void OpenGLRenderer::renderTextureAlpha8(const Texture* texture, GLuint& textureUnit,
+ float x, float y, float r, float g, float b, float a, SkXfermode::Mode mode,
+ bool applyFilters) {
+ // Describe the required shaders
+ ProgramDescription description;
+ description.hasTexture = true;
+ description.hasAlpha8Texture = true;
+
+ if (applyFilters) {
+ if (mShader) {
+ mShader->describe(description, mExtensions);
+ }
+ if (mColorFilter) {
+ mColorFilter->describe(description, mExtensions);
+ }
+ }
+
+ // Build and use the appropriate shader
+ useProgram(mProgramCache.get(description));
+
+ // Setup the blending mode
+ chooseBlending(true, mode);
+ bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
+ glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);
+
+ int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
+ glEnableVertexAttribArray(texCoordsSlot);
+
+ // Setup attributes
+ glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mMeshVertices[0].position[0]);
+ glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mMeshVertices[0].texture[0]);
+
+ // Setup uniforms
+ mModelView.loadTranslate(x, y, 0.0f);
+ mModelView.scale(texture->width, texture->height, 1.0f);
+ mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
+
+ glUniform4f(mCurrentProgram->color, r, g, b, a);
+
+ textureUnit++;
+ if (applyFilters) {
+ // Setup attributes and uniforms required by the shaders
+ if (mShader) {
+ mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
+ }
+ if (mColorFilter) {
+ mColorFilter->setupProgram(mCurrentProgram);
+ }
+ }
+
+ // Draw the mesh
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ glDisableVertexAttribArray(texCoordsSlot);
+}
+
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
#define kStdUnderline_Offset (1.0f / 9.0f)
#define kStdUnderline_Thickness (1.0f / 18.0f)
@@ -578,6 +662,15 @@
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
+ mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
+ if (mHasShadow) {
+ glActiveTexture(gTextureUnits[0]);
+ const ShadowTexture* shadow = mDropShadowCache.get(paint, text, bytesCount,
+ count, mShadowRadius);
+ const AutoTexture autoCleanup(shadow);
+ renderShadow(shadow, x, y, mode);
+ }
+
uint32_t color = paint->getColor();
const GLfloat a = alpha / 255.0f;
const GLfloat r = a * ((color >> 16) & 0xFF) / 255.0f;
@@ -624,7 +717,6 @@
}
const Rect& clip = mSnapshot->getLocalClip();
- mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -693,55 +785,9 @@
const GLfloat g = a * ((color >> 8) & 0xFF) / 255.0f;
const GLfloat b = a * ((color ) & 0xFF) / 255.0f;
- // Describe the required shaders
- ProgramDescription description;
- description.hasTexture = true;
- description.hasAlpha8Texture = true;
- if (mShader) {
- mShader->describe(description, mExtensions);
- }
- if (mColorFilter) {
- mColorFilter->describe(description, mExtensions);
- }
-
- // Build and use the appropriate shader
- useProgram(mProgramCache.get(description));
-
- // Setup the blending mode
- chooseBlending(true, mode);
- bindTexture(texture->id, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit);
- glUniform1i(mCurrentProgram->getUniform("sampler"), textureUnit);
-
- int texCoordsSlot = mCurrentProgram->getAttrib("texCoords");
- glEnableVertexAttribArray(texCoordsSlot);
-
- // Setup attributes
- glVertexAttribPointer(mCurrentProgram->position, 2, GL_FLOAT, GL_FALSE,
- gMeshStride, &mMeshVertices[0].position[0]);
- glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
- gMeshStride, &mMeshVertices[0].texture[0]);
-
- // Setup uniforms
- mModelView.loadTranslate(texture->left - texture->offset,
- texture->top - texture->offset, 0.0f);
- mModelView.scale(texture->width, texture->height, 1.0f);
- mCurrentProgram->set(mOrthoMatrix, mModelView, mSnapshot->transform);
-
- glUniform4f(mCurrentProgram->color, r, g, b, a);
-
- textureUnit++;
- // Setup attributes and uniforms required by the shaders
- if (mShader) {
- mShader->setupProgram(mCurrentProgram, mModelView, *mSnapshot, &textureUnit);
- }
- if (mColorFilter) {
- mColorFilter->setupProgram(mCurrentProgram);
- }
-
- // Draw the mesh
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
- glDisableVertexAttribArray(texCoordsSlot);
+ const float x = texture->left - texture->offset;
+ const float y = texture->top - texture->offset;
+ renderTextureAlpha8(texture, textureUnit, x, y, r, g, b, a, mode, true);
}
///////////////////////////////////////////////////////////////////////////////
@@ -772,6 +818,22 @@
}
///////////////////////////////////////////////////////////////////////////////
+// Drop shadow
+///////////////////////////////////////////////////////////////////////////////
+
+void OpenGLRenderer::resetShadow() {
+ mHasShadow = false;
+}
+
+void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) {
+ mHasShadow = true;
+ mShadowRadius = radius;
+ mShadowDx = dx;
+ mShadowDy = dy;
+ mShadowColor = color;
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Drawing implementation
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 76783e9..948ff13 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -45,6 +45,7 @@
#include "SkiaShader.h"
#include "SkiaColorFilter.h"
#include "PathCache.h"
+#include "TextDropShadowCache.h"
namespace android {
namespace uirenderer {
@@ -101,6 +102,9 @@
void resetColorFilter();
void setupColorFilter(SkiaColorFilter* filter);
+ void resetShadow();
+ void setupShadow(float radius, float dx, float dy, int color);
+
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
private:
@@ -222,6 +226,34 @@
GLvoid* vertices, GLvoid* texCoords, GLvoid* indices, GLsizei elementsCount = 0);
/**
+ * Renders the specified shadow.
+ *
+ * @param texture The shadow texture
+ * @param x The x coordinate of the shadow
+ * @param y The y coordinate of the shadow
+ * @param mode The blending mode
+ */
+ void renderShadow(const ShadowTexture* texture, float x, float y, SkXfermode::Mode mode);
+
+ /**
+ * Renders the specified Alpha8 texture as a rectangle.
+ *
+ * @param texture The texture to render with
+ * @param textureUnit The texture unit to use, may be modified
+ * @param x The x coordinate of the rectangle to draw
+ * @param y The y coordinate of the rectangle to draw
+ * @param r The red component of the color
+ * @param g The green component of the color
+ * @param b The blue component of the color
+ * @param a The alpha component of the color
+ * @param mode The blending mode
+ * @param applyFilters Whether or not to take color filters and
+ * shaders into account
+ */
+ void renderTextureAlpha8(const Texture* texture, GLuint& textureUnit, float x, float y,
+ float r, float g, float b, float a, SkXfermode::Mode mode, bool applyFilters);
+
+ /**
* Resets the texture coordinates stored in mMeshVertices. Setting the values
* back to default is achieved by calling:
*
@@ -304,6 +336,13 @@
// Font renderer
FontRenderer mFontRenderer;
+ // Drop shadow
+ bool mHasShadow;
+ float mShadowRadius;
+ float mShadowDx;
+ float mShadowDy;
+ int mShadowColor;
+
// Various caches
TextureCache mTextureCache;
LayerCache mLayerCache;
@@ -311,6 +350,7 @@
ProgramCache mProgramCache;
PathCache mPathCache;
PatchCache mPatchCache;
+ TextDropShadowCache mDropShadowCache;
}; // class OpenGLRenderer
}; // namespace uirenderer
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 9a22dc0..10440ea 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -166,7 +166,7 @@
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
texture->blend = true;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap.rowBytesAsPixels(), texture->height, 0,
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 915b0be..7514b6f 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -27,6 +27,7 @@
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
+#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
// These properties are defined in pixels
#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
new file mode 100644
index 0000000..aab5bd4
--- /dev/null
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "TextDropShadowCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize):
+ mCache(GenerationCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity),
+ mSize(0), mMaxSize(maxByteSize) {
+ mCache.setOnEntryRemovedListener(this);
+}
+
+TextDropShadowCache::~TextDropShadowCache() {
+ mCache.clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+uint32_t TextDropShadowCache::getSize() {
+ return mSize;
+}
+
+uint32_t TextDropShadowCache::getMaxSize() {
+ return mMaxSize;
+}
+
+void TextDropShadowCache::setMaxSize(uint32_t maxSize) {
+ mMaxSize = maxSize;
+ while (mSize > mMaxSize) {
+ mCache.removeOldest();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Callbacks
+///////////////////////////////////////////////////////////////////////////////
+
+void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) {
+ const uint32_t size = texture->width * texture->height;
+ mSize -= size;
+
+ if (texture) {
+ glDeleteTextures(1, &texture->id);
+ delete texture;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+void TextDropShadowCache::clear() {
+ mCache.clear();
+}
+
+ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len,
+ int numGlyphs, uint32_t radius) {
+ ShadowText entry(paint, radius, len, text);
+ ShadowTexture* texture = mCache.get(entry);
+
+ if (!texture) {
+ FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(paint, text, 0,
+ len, numGlyphs, radius);
+
+ texture = new ShadowTexture;
+ texture->left = shadow.penX;
+ texture->top = shadow.penY;
+ texture->width = shadow.width;
+ texture->height = shadow.height;
+ texture->generation = 0;
+ texture->blend = true;
+
+ const uint32_t size = shadow.width * shadow.height;
+ // Don't even try to cache a bitmap that's bigger than the cache
+ if (size < mMaxSize) {
+ while (mSize + size > mMaxSize) {
+ mCache.removeOldest();
+ }
+ }
+
+ glGenTextures(1, &texture->id);
+
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ // Textures are Alpha8
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (size < mMaxSize) {
+ mSize += size;
+ mCache.put(entry, texture);
+ } else {
+ texture->cleanup = true;
+ }
+
+ // Cleanup shadow
+ delete[] shadow.image;
+ }
+
+ return texture;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
new file mode 100644
index 0000000..9c86187
--- /dev/null
+++ b/libs/hwui/TextDropShadowCache.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+#define ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <SkPaint.h>
+
+#include "GenerationCache.h"
+#include "FontRenderer.h"
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+struct ShadowText {
+ ShadowText() { }
+
+ ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
+ paint(paint), radius(radius), len(len) {
+ text = new char[len];
+ memcpy(text, srcText, len);
+
+ hash = 0;
+ uint32_t multiplier = 1;
+ for (uint32_t i = 0; i < len; i++) {
+ hash += text[i] * multiplier;
+ uint32_t shifted = multiplier << 5;
+ multiplier = shifted - multiplier;
+ }
+ }
+
+ ShadowText(const ShadowText& shadow):
+ paint(shadow.paint), radius(shadow.radius), len(shadow.len), hash(shadow.hash) {
+ text = new char[len];
+ memcpy(text, shadow.text, shadow.len);
+ }
+
+ ~ShadowText() {
+ delete[] text;
+ }
+
+ SkPaint* paint;
+ uint32_t radius;
+ uint32_t len;
+ uint32_t hash;
+ char *text;
+
+ bool operator<(const ShadowText& rhs) const {
+ if (len < rhs.len) return true;
+ else if (len == rhs.len) {
+ if (radius < rhs.radius) return true;
+ else if (radius == rhs.radius) {
+ if (paint < rhs.paint) return true;
+ else if (paint == rhs.paint) {
+ if (hash < rhs.hash) return true;
+ if (hash == rhs.hash) {
+ return strncmp(text, rhs.text, len) < 0;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}; // struct ShadowText
+
+/**
+ * Alpha texture used to represent a shadow.
+ */
+struct ShadowTexture: public Texture {
+ ShadowTexture(): Texture() {
+ }
+
+ float left;
+ float top;
+}; // struct ShadowTexture
+
+class TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> {
+public:
+ TextDropShadowCache(uint32_t maxByteSize);
+ ~TextDropShadowCache();
+
+ /**
+ * Used as a callback when an entry is removed from the cache.
+ * Do not invoke directly.
+ */
+ void operator()(ShadowText& text, ShadowTexture*& texture);
+
+ ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
+ int numGlyphs, uint32_t radius);
+
+ /**
+ * Clears the cache. This causes all textures to be deleted.
+ */
+ void clear();
+
+ void setFontRenderer(FontRenderer& fontRenderer) {
+ mRenderer = &fontRenderer;
+ }
+
+ /**
+ * Sets the maximum size of the cache in bytes.
+ */
+ void setMaxSize(uint32_t maxSize);
+ /**
+ * Returns the maximum size of the cache in bytes.
+ */
+ uint32_t getMaxSize();
+ /**
+ * Returns the current size of the cache in bytes.
+ */
+ uint32_t getSize();
+
+private:
+ GenerationCache<ShadowText, ShadowTexture*> mCache;
+
+ uint32_t mSize;
+ uint32_t mMaxSize;
+ FontRenderer* mRenderer;
+}; // class TextDropShadowCache
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
diff --git a/libs/rs/java/SceneGraph/Android.mk b/libs/rs/java/SceneGraph/Android.mk
new file mode 100644
index 0000000..5520446
--- /dev/null
+++ b/libs/rs/java/SceneGraph/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 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.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := SceneGraph
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/libs/rs/java/SceneGraph/AndroidManifest.xml b/libs/rs/java/SceneGraph/AndroidManifest.xml
new file mode 100644
index 0000000..8a8f87a
--- /dev/null
+++ b/libs/rs/java/SceneGraph/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.scenegraph">
+ <application android:label="SceneGraph">
+ <activity android:name="SceneGraph"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/SceneGraph/res/drawable/robot.png b/libs/rs/java/SceneGraph/res/drawable/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/drawable/robot.png
Binary files differ
diff --git a/libs/rs/java/SceneGraph/res/raw/robot.a3d b/libs/rs/java/SceneGraph/res/raw/robot.a3d
new file mode 100644
index 0000000..2d7d32b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/res/raw/robot.a3d
Binary files differ
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
new file mode 100644
index 0000000..5daa4ac
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraph.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class SceneGraph extends Activity {
+
+ private SceneGraphView mView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new SceneGraphView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.onPause();
+ }
+
+}
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
new file mode 100644
index 0000000..3db4a2b6
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphRS.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+
+public class SceneGraphRS {
+
+ private final int STATE_LAST_FOCUS = 1;
+
+ int mWidth;
+ int mHeight;
+ int mRotation;
+
+ public SceneGraphRS() {
+ }
+
+ public void init(RenderScriptGL rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ mWidth = width;
+ mHeight = height;
+ mRotation = 0;
+ initRS();
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ private Sampler mSampler;
+ private ProgramStore mPSBackground;
+ private ProgramFragment mPFBackground;
+ private ProgramVertex mPVBackground;
+ private ProgramVertex.MatrixAllocation mPVA;
+
+ private Allocation mGridImage;
+ private Allocation mAllocPV;
+
+ private Mesh mMesh;
+
+ private Font mItalic;
+ private Allocation mTextAlloc;
+
+ private ScriptC_Scenegraph mScript;
+ private ScriptC_Transform mTransformScript;
+
+ int mLastX;
+ int mLastY;
+
+ public void touchEvent(int x, int y) {
+ int dx = mLastX - x;
+ if(Math.abs(dx) > 50 || Math.abs(dx) < 3) {
+ dx = 0;
+ }
+
+ mRotation -= dx;
+ if(mRotation > 360) {
+ mRotation -= 360;
+ }
+ if(mRotation < 0) {
+ mRotation += 360;
+ }
+
+ mScript.set_gRotate(-(float)mRotation);
+
+ mLastX = x;
+ mLastY = y;
+ }
+
+ private void initPFS() {
+ ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null);
+
+ b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ b.setDitherEnable(false);
+ b.setDepthMask(true);
+ mPSBackground = b.create();
+
+ mScript.set_gPFSBackground(mPSBackground);
+ }
+
+ private void initPF() {
+ Sampler.Builder bs = new Sampler.Builder(mRS);
+ bs.setMin(Sampler.Value.LINEAR);
+ bs.setMag(Sampler.Value.LINEAR);
+ bs.setWrapS(Sampler.Value.CLAMP);
+ bs.setWrapT(Sampler.Value.WRAP);
+ mSampler = bs.create();
+
+ ProgramFragment.Builder b = new ProgramFragment.Builder(mRS);
+ b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE,
+ ProgramFragment.Builder.Format.RGBA, 0);
+ mPFBackground = b.create();
+ mPFBackground.bindSampler(mSampler, 0);
+
+ mScript.set_gPFBackground(mPFBackground);
+ }
+
+ private void initPV() {
+ ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
+ mPVBackground = pvb.create();
+
+ mPVA = new ProgramVertex.MatrixAllocation(mRS);
+ mPVBackground.bindAllocation(mPVA);
+ mPVA.setupProjectionNormalized(mWidth, mHeight);
+
+ mScript.set_gPVBackground(mPVBackground);
+ }
+
+ private void loadImage() {
+ mGridImage = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.robot, Element.RGB_565(mRS), true);
+ mGridImage.uploadToTexture(0);
+
+ mScript.set_gTGrid(mGridImage);
+ }
+
+ private void initTextAllocation() {
+ String allocString = "Displaying file: R.raw.robot";
+ mTextAlloc = Allocation.createFromString(mRS, allocString);
+ mScript.set_gTextAlloc(mTextAlloc);
+ }
+
+ SgTransform mRootTransform;
+ SgTransform mGroup1;
+
+ SgTransform mRobot1;
+ SgTransform mRobot2;
+
+ void initTransformHierarchy() {
+ mRootTransform = new SgTransform(mRS);
+
+ mGroup1 = new SgTransform(mRS);
+ mRootTransform.addChild(mGroup1);
+
+ mRobot1 = new SgTransform(mRS);
+ mRobot2 = new SgTransform(mRS);
+
+ mGroup1.addChild(mRobot1);
+ mGroup1.addChild(mRobot2);
+
+ mGroup1.setTransform(0, new Float4(0.0f, 0.0f, 5.0f, 0.0f), TransformType.TRANSLATE);
+ mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE);
+
+ mRobot1.setTransform(0, new Float4(-2.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE);
+ mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE);
+ mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE);
+
+ mRobot2.setTransform(0, new Float4(2.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE);
+ mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE);
+ mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE);
+ }
+
+ private void initRS() {
+
+ mScript = new ScriptC_Scenegraph(mRS, mRes, R.raw.scenegraph, true);
+ mTransformScript = new ScriptC_Transform(mRS, mRes, R.raw.transform, false);
+ mTransformScript.set_transformScript(mTransformScript);
+
+ mScript.set_gTransformRS(mTransformScript);
+
+ initPFS();
+ initPF();
+ initPV();
+
+ loadImage();
+
+ FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+ FileA3D.IndexEntry entry = model.getIndexEntry(0);
+ if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
+ Log.e("rs", "could not load model");
+ }
+ else {
+ mMesh = (Mesh)entry.getObject();
+ mScript.set_gTestMesh(mMesh);
+ }
+
+ mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8);
+ mScript.set_gItalic(mItalic);
+
+ initTextAllocation();
+
+ initTransformHierarchy();
+
+ Log.v("========SceneGraph========", "transform hierarchy initialized");
+
+ mScript.bind_gRootNode(mRootTransform.getField());
+
+ mScript.bind_gGroup(mGroup1.mParent.mChildField);
+ mScript.bind_gRobot1(mRobot1.mParent.mChildField);
+ mScript.set_gRobot1Index(mRobot1.mIndexInParentGroup);
+ mScript.bind_gRobot2(mRobot2.mParent.mChildField);
+ mScript.set_gRobot2Index(mRobot2.mIndexInParentGroup);
+
+ mRS.contextBindRootScript(mScript);
+ }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
new file mode 100644
index 0000000..ae94869
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SceneGraphView.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class SceneGraphView extends RSSurfaceView {
+
+ public SceneGraphView(Context context) {
+ super(context);
+ //setFocusable(true);
+ }
+
+ private RenderScriptGL mRS;
+ private SceneGraphRS mRender;
+
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ if (mRS == null) {
+ mRS = createRenderScript(true);
+ mRS.contextSetSurface(w, h, holder.getSurface());
+ mRender = new SceneGraphRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if(mRS != null) {
+ mRS = null;
+ destroyRenderScript();
+ }
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ // break point at here
+ // this method doesn't work when 'extends View' include 'extends ScrollView'.
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev)
+ {
+ boolean ret = true;
+ int act = ev.getAction();
+ if (act == ev.ACTION_UP) {
+ ret = false;
+ }
+
+ mRender.touchEvent((int)ev.getX(), (int)ev.getY());
+ return ret;
+ }
+}
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
new file mode 100644
index 0000000..e81f1a7
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/SgTransform.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 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.scenegraph;
+
+import java.io.Writer;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+enum TransformType {
+
+ NONE(0),
+ TRANSLATE(1),
+ ROTATE(2),
+ SCALE(3);
+
+ int mID;
+ TransformType(int id) {
+ mID = id;
+ }
+}
+
+public class SgTransform {
+
+
+ ScriptField_SgTransform mTransformField;
+ ScriptField_SgTransform mChildField;
+ public ScriptField_SgTransform.Item mTransformData;
+
+ Float4[] mTransforms;
+ TransformType[] mTransformTypes;
+
+ RenderScript mRS;
+
+ Vector mChildren;
+ SgTransform mParent;
+ int mIndexInParentGroup;
+
+ public void setParent(SgTransform parent, int parentIndex) {
+ mParent = parent;
+ mIndexInParentGroup = parentIndex;
+ }
+
+ public void addChild(SgTransform child) {
+ mChildren.add(child);
+ child.setParent(this, mChildren.size() - 1);
+ }
+
+ public void setTransform(int index, Float4 value, TransformType type) {
+ mTransforms[index] = value;
+ mTransformTypes[index] = type;
+ }
+
+ void initData() {
+ int numTransforms = 16;
+ mTransforms = new Float4[numTransforms];
+ mTransformTypes = new TransformType[numTransforms];
+ for(int i = 0; i < numTransforms; i ++) {
+ mTransforms[i] = new Float4(0, 0, 0, 0);
+ mTransformTypes[i] = TransformType.NONE;
+ }
+ }
+
+ void setData() {
+
+ mTransformData.globalMat_Row0 = new Float4(1, 0, 0, 0);
+ mTransformData.globalMat_Row1 = new Float4(0, 1, 0, 0);
+ mTransformData.globalMat_Row2 = new Float4(0, 0, 1, 0);
+ mTransformData.globalMat_Row3 = new Float4(0, 0, 0, 1);
+
+ mTransformData.localMat_Row0 = new Float4(1, 0, 0, 0);
+ mTransformData.localMat_Row1 = new Float4(0, 1, 0, 0);
+ mTransformData.localMat_Row2 = new Float4(0, 0, 1, 0);
+ mTransformData.localMat_Row3 = new Float4(0, 0, 0, 1);
+
+ mTransformData.transforms0 = mTransforms[0];
+ mTransformData.transforms1 = mTransforms[1];
+ mTransformData.transforms2 = mTransforms[2];
+ mTransformData.transforms3 = mTransforms[3];
+ mTransformData.transforms4 = mTransforms[4];
+ mTransformData.transforms5 = mTransforms[5];
+ mTransformData.transforms6 = mTransforms[6];
+ mTransformData.transforms7 = mTransforms[7];
+ mTransformData.transforms8 = mTransforms[8];
+ mTransformData.transforms9 = mTransforms[9];
+ mTransformData.transforms10 = mTransforms[10];
+ mTransformData.transforms11 = mTransforms[11];
+ mTransformData.transforms12 = mTransforms[12];
+ mTransformData.transforms13 = mTransforms[13];
+ mTransformData.transforms14 = mTransforms[14];
+ mTransformData.transforms15 = mTransforms[15];
+
+ mTransformData.transformType0 = mTransformTypes[0].mID;
+ mTransformData.transformType1 = mTransformTypes[1].mID;
+ mTransformData.transformType2 = mTransformTypes[2].mID;
+ mTransformData.transformType3 = mTransformTypes[3].mID;
+ mTransformData.transformType4 = mTransformTypes[4].mID;
+ mTransformData.transformType5 = mTransformTypes[5].mID;
+ mTransformData.transformType6 = mTransformTypes[6].mID;
+ mTransformData.transformType7 = mTransformTypes[7].mID;
+ mTransformData.transformType8 = mTransformTypes[8].mID;
+ mTransformData.transformType9 = mTransformTypes[9].mID;
+ mTransformData.transformType10 = mTransformTypes[10].mID;
+ mTransformData.transformType11 = mTransformTypes[11].mID;
+ mTransformData.transformType12 = mTransformTypes[12].mID;
+ mTransformData.transformType13 = mTransformTypes[13].mID;
+ mTransformData.transformType14 = mTransformTypes[14].mID;
+ mTransformData.transformType15 = mTransformTypes[15].mID;
+
+ mTransformData.isDirty = 1;
+ mTransformData.children = null;
+
+ }
+
+ public SgTransform(RenderScript rs) {
+ mRS = rs;
+ mTransformData = new ScriptField_SgTransform.Item();
+ mChildren = new Vector();
+ initData();
+ }
+
+ public ScriptField_SgTransform.Item getData() {
+ setData();
+ if(mChildren.size() != 0) {
+ mChildField = new ScriptField_SgTransform(mRS, mChildren.size());
+ mTransformData.children = mChildField.getAllocation();
+
+ for(int i = 0; i < mChildren.size(); i ++) {
+ SgTransform child = (SgTransform)mChildren.get(i);
+ mChildField.set(child.getData(), i, false);
+ }
+ mChildField.copyAll();
+ }
+
+ return mTransformData;
+ }
+
+ public ScriptField_SgTransform getField() {
+ mTransformField = new ScriptField_SgTransform(mRS, 1);
+ mTransformField.set(getData(), 0, true);
+ return mTransformField;
+ }
+}
+
+
+
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
new file mode 100644
index 0000000..e6ae6df
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/scenegraph.rs
@@ -0,0 +1,92 @@
+// Copyright (C) 2009 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "transform_def.rsh"
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gTGrid;
+rs_mesh gTestMesh;
+
+rs_program_store gPFSBackground;
+
+float gRotate;
+
+rs_font gItalic;
+rs_allocation gTextAlloc;
+
+rs_script gTransformRS;
+
+SgTransform *gGroup;
+SgTransform *gRobot1;
+int gRobot1Index;
+SgTransform *gRobot2;
+int gRobot2Index;
+
+SgTransform *gRootNode;
+
+#pragma rs export_var(gPVBackground, gPFBackground, gTGrid, gTestMesh, gPFSBackground, gRotate, gItalic, gTextAlloc, gTransformRS, gGroup, gRobot1, gRobot1Index, gRobot2, gRobot2Index, gRootNode)
+
+float gDT;
+int64_t gLastTime;
+
+void init() {
+ gRotate = 0.0f;
+}
+
+int root(int launchID) {
+
+ gGroup->transforms1.w += 0.5f;
+ gGroup->isDirty = 1;
+
+ SgTransform *robot1Ptr = gRobot1 + gRobot1Index;
+
+ robot1Ptr->transforms1.w -= 1.5f;
+ robot1Ptr->isDirty = 1;
+
+ SgTransform *robot2Ptr = gRobot2 + gRobot2Index;
+ robot2Ptr->transforms1.w += 2.5f;
+ robot2Ptr->isDirty = 1;
+
+ rsForEach(gTransformRS, gRootNode->children, gRootNode->children, 0);
+
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+
+ rsgBindProgramVertex(gPVBackground);
+
+ rsgBindProgramFragment(gPFBackground);
+ rsgBindProgramStore(gPFSBackground);
+ rsgBindTexture(gPFBackground, 0, gTGrid);
+
+ rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot1Ptr->globalMat_Row0);
+ rsgDrawMesh(gTestMesh);
+
+ rsgProgramVertexLoadModelMatrix((rs_matrix4x4 *)&robot2Ptr->globalMat_Row0);
+ rsgDrawMesh(gTestMesh);
+
+ color(0.3f, 0.3f, 0.3f, 1.0f);
+ rsgDrawText("Renderscript transform test", 30, 695);
+
+ rsgBindFont(gItalic);
+ rsgDrawText(gTextAlloc, 30, 730);
+
+ return 10;
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
new file mode 100644
index 0000000..a62d12b
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -0,0 +1,102 @@
+// Copyright (C) 2009 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#include "transform_def.rsh"
+
+rs_script transformScript;
+
+#pragma rs export_var(transformScript)
+
+typedef struct {
+ int changed;
+ rs_matrix4x4 *mat;
+} ParentData;
+
+void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) {
+ rs_matrix4x4 temp;
+
+ switch(type) {
+ case TRANSFORM_TRANSLATE:
+ rsMatrixLoadTranslate(&temp, data.x, data.y, data.z);
+ break;
+ case TRANSFORM_ROTATE:
+ rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z);
+ break;
+ case TRANSFORM_SCALE:
+ rsMatrixLoadScale(&temp, data.x, data.y, data.z);
+ break;
+ }
+ rsMatrixMultiply(mat, &temp);
+}
+
+void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) {
+
+ SgTransform *data = (SgTransform *)v_out;
+ const ParentData *parent = (const ParentData *)usrData;
+
+ //rsDebug("Transform data", (int)data);
+ //rsDebug("Entering parent", (int)parent);
+
+ rs_matrix4x4 *localMat = (rs_matrix4x4*)&data->localMat_Row0;
+ rs_matrix4x4 *globalMat = (rs_matrix4x4*)&data->globalMat_Row0;
+
+ ParentData toChild;
+ toChild.changed = 0;
+ toChild.mat = globalMat;
+
+ //rsDebug("Transform is dirty", data->isDirty);
+
+ // Refresh matrices if dirty
+ if(data->isDirty) {
+ data->isDirty = 0;
+ toChild.changed = 1;
+
+ // Reset our local matrix
+ rsMatrixLoadIdentity(localMat);
+
+ float4 *transformSource = &data->transforms0;
+ int *transformTypes = &data->transformType0;
+
+ for(int i = 0; i < 16; i ++) {
+ if(transformTypes[i] == TRANSFORM_NONE) {
+ break;
+ }
+ //rsDebug("Transform adding transformation", transformTypes[i]);
+ appendTransformation(transformTypes[i], transformSource[i], localMat);
+ }
+ }
+
+ //rsDebug("Transform checking parent", (int)0);
+
+ if(parent) {
+ if(parent->changed) {
+ toChild.changed = 1;
+
+ rsMatrixLoad(globalMat, parent->mat);
+ rsMatrixMultiply(globalMat, localMat);
+ }
+ }
+ else {
+ rsMatrixLoad(globalMat, localMat);
+ }
+
+ //rsDebug("Transform calling self with child ", (int)data->children.p);
+ if(data->children.p) {
+ rsForEach(transformScript, data->children, data->children, (void*)&toChild);
+ }
+}
diff --git a/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
new file mode 100644
index 0000000..10aac37
--- /dev/null
+++ b/libs/rs/java/SceneGraph/src/com/android/scenegraph/transform_def.rsh
@@ -0,0 +1,73 @@
+// Copyright (C) 2009 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.scenegraph)
+
+#define TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+typedef struct {
+ float4 globalMat_Row0;
+ float4 globalMat_Row1;
+ float4 globalMat_Row2;
+ float4 globalMat_Row3;
+
+ float4 localMat_Row0;
+ float4 localMat_Row1;
+ float4 localMat_Row2;
+ float4 localMat_Row3;
+
+ float4 transforms0;
+ float4 transforms1;
+ float4 transforms2;
+ float4 transforms3;
+ float4 transforms4;
+ float4 transforms5;
+ float4 transforms6;
+ float4 transforms7;
+ float4 transforms8;
+ float4 transforms9;
+ float4 transforms10;
+ float4 transforms11;
+ float4 transforms12;
+ float4 transforms13;
+ float4 transforms14;
+ float4 transforms15;
+
+ int transformType0;
+ int transformType1;
+ int transformType2;
+ int transformType3;
+ int transformType4;
+ int transformType5;
+ int transformType6;
+ int transformType7;
+ int transformType8;
+ int transformType9;
+ int transformType10;
+ int transformType11;
+ int transformType12;
+ int transformType13;
+ int transformType14;
+ int transformType15;
+
+ int isDirty;
+
+ rs_allocation children;
+
+} SgTransform;
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 9026578..810e4ff 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -224,6 +224,49 @@
return mesh;
}
+void Mesh::computeBBox() {
+ float *posPtr = NULL;
+ uint32_t vectorSize = 0;
+ uint32_t stride = 0;
+ uint32_t numVerts = 0;
+ // First we need to find the position ptr and stride
+ for (uint32_t ct=0; ct < mVertexBufferCount; ct++) {
+ const Type *bufferType = mVertexBuffers[ct]->getType();
+ const Element *bufferElem = bufferType->getElement();
+
+ for (uint32_t ct=0; ct < bufferElem->getFieldCount(); ct++) {
+ if(strcmp(bufferElem->getFieldName(ct), "position") == 0) {
+ vectorSize = bufferElem->getField(ct)->getComponent().getVectorSize();
+ stride = bufferElem->getSizeBytes() / sizeof(float);
+ uint32_t offset = bufferElem->getFieldOffsetBytes(ct);
+ posPtr = (float*)((uint8_t*)mVertexBuffers[ct]->getPtr() + offset);
+ numVerts = bufferType->getDimX();
+ break;
+ }
+ }
+ if(posPtr) {
+ break;
+ }
+ }
+
+ mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 1e6;
+ mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = -1e6;
+ if(!posPtr) {
+ LOGE("Unable to compute bounding box");
+ mBBoxMin[0] = mBBoxMin[1] = mBBoxMin[2] = 0.0f;
+ mBBoxMax[0] = mBBoxMax[1] = mBBoxMax[2] = 0.0f;
+ return;
+ }
+
+ for(uint32_t i = 0; i < numVerts; i ++) {
+ for(uint32_t v = 0; v < vectorSize; v ++) {
+ mBBoxMin[v] = rsMin(mBBoxMin[v], posPtr[v]);
+ mBBoxMax[v] = rsMax(mBBoxMax[v], posPtr[v]);
+ }
+ posPtr += stride;
+ }
+}
+
MeshContext::MeshContext()
{
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 765a971..ed01c38 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -61,6 +61,11 @@
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
static Mesh *createFromStream(Context *rsc, IStream *stream);
+ // Bounding volumes
+ float mBBoxMin[3];
+ float mBBoxMax[3];
+ void computeBBox();
+
protected:
};
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index f5e59534..4b8de76 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -251,6 +251,20 @@
sm->renderPrimitiveRange(rsc, primIndex, start, len);
}
+static void SC_meshComputeBoundingBox(RsMesh vsm, float *minX, float *minY, float *minZ,
+ float *maxX, float *maxY, float *maxZ)
+{
+ GET_TLS();
+ Mesh *sm = static_cast<Mesh *>(vsm);
+ sm->computeBBox();
+ *minX = sm->mBBoxMin[0];
+ *minY = sm->mBBoxMin[1];
+ *minZ = sm->mBBoxMin[2];
+ *maxX = sm->mBBoxMax[0];
+ *maxY = sm->mBBoxMax[1];
+ *maxZ = sm->mBBoxMax[2];
+}
+
//////////////////////////////////////////////////////////////////////////////
//
@@ -390,6 +404,7 @@
{ "_Z11rsgDrawMesh7rs_mesh", (void *)&SC_drawMesh },
{ "_Z11rsgDrawMesh7rs_meshj", (void *)&SC_drawMeshPrimitive },
{ "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_drawMeshPrimitiveRange },
+ { "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_meshComputeBoundingBox },
{ "_Z13rsgClearColorffff", (void *)&SC_ClearColor },
{ "_Z13rsgClearDepthf", (void *)&SC_ClearDepth },
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index fd0491c..63bd9d7 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -77,6 +77,23 @@
extern void __attribute__((overloadable))
rsgFontColor(float, float, float, float);
+extern void __attribute__((overloadable))
+ rsgMeshComputeBoundingBox(rs_mesh mesh, float *minX, float *minY, float *minZ,
+ float *maxX, float *maxY, float *maxZ);
+void __attribute__((overloadable))
+rsgMeshComputeBoundingBox(rs_mesh mesh, float3 *bBoxMin, float3 *bBoxMax) {
+ float x1, y1, z1, x2, y2, z2;
+ rsgMeshComputeBoundingBox(mesh, &x1, &y1, &z1, &x2, &y2, &z2);
+ bBoxMin->x = x1;
+ bBoxMin->y = y1;
+ bBoxMin->z = z1;
+ bBoxMax->x = x2;
+ bBoxMax->y = y2;
+ bBoxMax->z = z2;
+}
+
+
+
///////////////////////////////////////////////////////
// misc
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_0.png b/packages/SystemUI/res/drawable-hdpi/battery_0.png
new file mode 100644
index 0000000..f4103a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_100.png b/packages/SystemUI/res/drawable-hdpi/battery_100.png
new file mode 100644
index 0000000..061cbe5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_20.png b/packages/SystemUI/res/drawable-hdpi/battery_20.png
new file mode 100644
index 0000000..0064027
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_40.png b/packages/SystemUI/res/drawable-hdpi/battery_40.png
new file mode 100644
index 0000000..10de0e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_60.png b/packages/SystemUI/res/drawable-hdpi/battery_60.png
new file mode 100644
index 0000000..aa2b8ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_80.png b/packages/SystemUI/res/drawable-hdpi/battery_80.png
new file mode 100644
index 0000000..fe231f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/battery_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_0.png b/packages/SystemUI/res/drawable-hdpi/signal_0.png
new file mode 100644
index 0000000..00e36c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_100.png b/packages/SystemUI/res/drawable-hdpi/signal_100.png
new file mode 100644
index 0000000..96e52ff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_20.png b/packages/SystemUI/res/drawable-hdpi/signal_20.png
new file mode 100644
index 0000000..c0f652a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_40.png b/packages/SystemUI/res/drawable-hdpi/signal_40.png
new file mode 100644
index 0000000..995dd8e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_60.png b/packages/SystemUI/res/drawable-hdpi/signal_60.png
new file mode 100644
index 0000000..51e31ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/signal_80.png b/packages/SystemUI/res/drawable-hdpi/signal_80.png
new file mode 100644
index 0000000..afa656e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_0.png b/packages/SystemUI/res/drawable-mdpi/battery_0.png
new file mode 100644
index 0000000..b5d36cc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_100.png b/packages/SystemUI/res/drawable-mdpi/battery_100.png
new file mode 100644
index 0000000..75cc409
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_20.png b/packages/SystemUI/res/drawable-mdpi/battery_20.png
new file mode 100644
index 0000000..c0d0030
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_40.png b/packages/SystemUI/res/drawable-mdpi/battery_40.png
new file mode 100644
index 0000000..e301c08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_60.png b/packages/SystemUI/res/drawable-mdpi/battery_60.png
new file mode 100644
index 0000000..0fde1fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_80.png b/packages/SystemUI/res/drawable-mdpi/battery_80.png
new file mode 100644
index 0000000..15c4e1c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/battery_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_0.png b/packages/SystemUI/res/drawable-mdpi/signal_0.png
new file mode 100644
index 0000000..6533677
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_100.png b/packages/SystemUI/res/drawable-mdpi/signal_100.png
new file mode 100644
index 0000000..e8976a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_20.png b/packages/SystemUI/res/drawable-mdpi/signal_20.png
new file mode 100644
index 0000000..651e2a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_40.png b/packages/SystemUI/res/drawable-mdpi/signal_40.png
new file mode 100644
index 0000000..6ba7906
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_60.png b/packages/SystemUI/res/drawable-mdpi/signal_60.png
new file mode 100644
index 0000000..6d2e812
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/signal_80.png b/packages/SystemUI/res/drawable-mdpi/signal_80.png
new file mode 100644
index 0000000..a152623
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/battery.xml b/packages/SystemUI/res/drawable/battery.xml
new file mode 100644
index 0000000..c2294d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/battery.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="1" android:drawable="@drawable/battery_0" />
+ <item android:maxLevel="5">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_0" android:duration="250" />
+ <item android:drawable="@drawable/battery_20" android:duration="250" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="20" android:drawable="@drawable/battery_20" />
+ <item android:maxLevel="40" android:drawable="@drawable/battery_40" />
+ <item android:maxLevel="60" android:drawable="@drawable/battery_60" />
+ <item android:maxLevel="80" android:drawable="@drawable/battery_80" />
+ <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
+</level-list>
+
diff --git a/packages/SystemUI/res/drawable/battery_charging.xml b/packages/SystemUI/res/drawable/battery_charging.xml
new file mode 100644
index 0000000..2fd0c6d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/battery_charging.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="20">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_0" android:duration="1000" />
+ <item android:drawable="@drawable/battery_20" android:duration="1000" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="40">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_20" android:duration="1000" />
+ <item android:drawable="@drawable/battery_40" android:duration="1000" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="60">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_40" android:duration="1000" />
+ <item android:drawable="@drawable/battery_60" android:duration="1000" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="80">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_60" android:duration="1000" />
+ <item android:drawable="@drawable/battery_80" android:duration="1000" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="92">
+ <animation-list android:oneshot="false">
+ <item android:drawable="@drawable/battery_80" android:duration="1000" />
+ <item android:drawable="@drawable/battery_100" android:duration="1000" />
+ </animation-list>
+ </item>
+ <item android:maxLevel="101" android:drawable="@drawable/battery_100" />
+</level-list>
+
diff --git a/packages/SystemUI/res/drawable/signal.xml b/packages/SystemUI/res/drawable/signal.xml
new file mode 100644
index 0000000..8b4f56b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/signal.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/stat_sys_battery.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="01" android:drawable="@drawable/signal_0" />
+ <item android:maxLevel="20" android:drawable="@drawable/signal_20" />
+ <item android:maxLevel="40" android:drawable="@drawable/signal_40" />
+ <item android:maxLevel="60" android:drawable="@drawable/signal_60" />
+ <item android:maxLevel="80" android:drawable="@drawable/signal_80" />
+ <item android:maxLevel="101" android:drawable="@drawable/signal_100" />
+
+</level-list>
+
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
index c32e997..775fea0 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml
@@ -36,18 +36,20 @@
android:padding="2dip"
/>
<ImageView
- android:layout_width="wrap_content"
+ android:id="@+id/battery"
+ android:layout_width="50dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/clock"
- android:src="@drawable/dots_empty"
+ android:src="@drawable/battery"
/>
<ImageView
- android:layout_width="wrap_content"
+ android:id="@+id/signal"
+ android:layout_width="50dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/clock"
- android:src="@drawable/dots_full"
+ android:src="@drawable/signal"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
index fc37900..e5b2f53 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml
@@ -96,6 +96,7 @@
<TextView android:id="@+id/battery_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="center"
android:layout_below="@id/battery_meter"
/>
@@ -121,12 +122,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:src="@drawable/dots_full"
+ android:src="@drawable/signal"
/>
<TextView android:id="@+id/signal_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:gravity="center"
android:layout_below="@id/signal_meter"
/>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index 236b521..c864daa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -78,14 +78,25 @@
private ImageButton mOrientationButton;
private ImageButton mAirplaneButton;
+ private ImageView mBatteryMeter;
+ private ImageView mSignalMeter;
+
+ private TextView mBatteryText;
+ private TextView mSignalText;
+
private final AudioManager mAudioManager;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+ final String action = intent.getAction();
+ if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
+ } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ // hack for now
+ mBar.updateBatteryDisplay(intent.getIntExtra("level", 0),
+ (intent.getIntExtra("plugged", 0) != 0));
}
}
};
@@ -93,6 +104,12 @@
public void setBar(TabletStatusBarService bar) {
mBar = bar;
}
+
+ public void setBatteryLevel(int level, boolean plugged) {
+ mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
+ mBatteryMeter.setImageLevel(level);
+ mBatteryText.setText(String.format("Battery: %d%%", level));
+ }
public SystemPanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -151,8 +168,21 @@
}
});
- IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_POWER_CONNECTED);
getContext().registerReceiver(mReceiver, filter);
+
+ mBatteryMeter = (ImageView)findViewById(R.id.battery_meter);
+ mBatteryMeter.setImageResource(R.drawable.battery);
+ mBatteryMeter.setImageLevel(0);
+ mSignalMeter = (ImageView)findViewById(R.id.signal_meter);
+ mBatteryMeter.setImageResource(R.drawable.signal);
+ mBatteryMeter.setImageLevel(0);
+
+ mBatteryText = (TextView)findViewById(R.id.battery_info);
+ mSignalText = (TextView)findViewById(R.id.signal_info);
}
public void onDetachedFromWindow() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 9c86f2d..b0ffaa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -75,6 +75,9 @@
ViewGroup mPile;
TextView mClearButton;
+ ImageView mBatteryMeter;
+ ImageView mSignalMeter;
+
NotificationIconArea.IconLayout mIconLayout;
KickerController mKicker;
@@ -151,6 +154,10 @@
mKicker = new KickerController((Context)this, mStatusBarView);
+ // System info (center)
+ mBatteryMeter = (ImageView) sb.findViewById(R.id.battery);
+ mSignalMeter = (ImageView) sb.findViewById(R.id.signal);
+
// Add the windows
addPanelWindows();
@@ -198,18 +205,27 @@
}
}
}
+
+ StatusBarIcon mBatterySBI;
+ StatusBarIcon mSignalSBI;
+ public void updateBatteryDisplay(int level, boolean plugged) {
+ if (DEBUG) Slog.d(TAG, "battery=" + level + (plugged ? " - plugged" : " - unplugged"));
+ mBatteryMeter.setImageResource(plugged ? R.drawable.battery_charging : R.drawable.battery);
+ mBatteryMeter.setImageLevel(level);
+ mSystemPanel.setBatteryLevel(level, plugged);
+ }
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
- // TODO
+ if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
}
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon) {
- // TODO
+ if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
}
public void removeIcon(String slot, int index, int viewIndex) {
- // TODO
+ if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
}
public void addNotification(IBinder key, StatusBarNotification notification) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index ba1d7f5..70a4b20 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -113,7 +113,15 @@
flags, PixelFormat.TRANSLUCENT);
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
- lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+
+ if (mContext.getResources().getBoolean(R.bool.config_enableLockScreenRotation)) {
+ Log.d(TAG, "Rotation sensor for lock screen On!");
+ lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
+ } else {
+ Log.d(TAG, "Rotation sensor for lock screen Off!");
+ lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+ }
+
lp.setTitle("Keyguard");
mWindowLayoutParams = lp;
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 8693294..822be46 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -645,7 +645,9 @@
// Show LockScreen first for any screen other than Pattern unlock.
final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- if (isSecure() && usingLockPattern) {
+
+ boolean showSlidingTab = getResources().getBoolean(R.bool.config_enableSlidingTabFirst);
+ if (isSecure() && (usingLockPattern || !showSlidingTab)) {
return Mode.UnlockScreen;
} else {
return Mode.LockScreen;
@@ -688,7 +690,7 @@
private void showTimeoutDialog() {
int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
- int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;;
+ int messageId = R.string.lockscreen_too_many_failed_attempts_dialog_message;
if(getUnlockMode() == UnlockMode.Password) {
if(mLockPatternUtils.getKeyguardStoredPasswordQuality() ==
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index b3707b0..f8c0aba 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -59,12 +59,7 @@
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
- private TextView mCarrier;
private SlidingTab mSelector;
- private TextView mTime;
- private TextView mDate;
- private TextView mStatus1;
- private TextView mStatus2;
private TextView mScreenLocked;
private TextView mEmergencyCallText;
private Button mEmergencyCallButton;
@@ -93,6 +88,8 @@
private java.text.DateFormat mTimeFormat;
private boolean mEnableMenuKeyInLockScreen;
+ private StatusView mStatusView;
+
/**
* The status of this lock screen.
*/
@@ -195,14 +192,7 @@
inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true);
}
- mCarrier = (TextView) findViewById(R.id.carrier);
- // Required for Marquee to work
- mCarrier.setSelected(true);
- mCarrier.setTextColor(0xffffffff);
-
- mDate = (TextView) findViewById(R.id.date);
- mStatus1 = (TextView) findViewById(R.id.status1);
- mStatus2 = (TextView) findViewById(R.id.status2);
+ mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
mScreenLocked = (TextView) findViewById(R.id.screenLocked);
mSelector = (SlidingTab) findViewById(R.id.tab_selector);
@@ -427,38 +417,11 @@
}
private void refreshTimeAndDateDisplay() {
- mDate.setText(DateFormat.format(mDateFormatString, new Date()));
+ mStatusView.refreshTimeAndDateDisplay();
}
private void updateStatusLines() {
- if (!mStatus.showStatusLines()
- || (mCharging == null && mNextAlarm == null)) {
- mStatus1.setVisibility(View.INVISIBLE);
- mStatus2.setVisibility(View.INVISIBLE);
- } else if (mCharging != null && mNextAlarm == null) {
- // charging only
- mStatus1.setVisibility(View.VISIBLE);
- mStatus2.setVisibility(View.INVISIBLE);
-
- mStatus1.setText(mCharging);
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null);
- } else if (mNextAlarm != null && mCharging == null) {
- // next alarm only
- mStatus1.setVisibility(View.VISIBLE);
- mStatus2.setVisibility(View.INVISIBLE);
-
- mStatus1.setText(mNextAlarm);
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null);
- } else if (mCharging != null && mNextAlarm != null) {
- // both charging and next alarm
- mStatus1.setVisibility(View.VISIBLE);
- mStatus2.setVisibility(View.VISIBLE);
-
- mStatus1.setText(mCharging);
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null);
- mStatus2.setText(mNextAlarm);
- mStatus2.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null);
- }
+ mStatusView.updateStatusLines(mStatus.showStatusLines(), mCharging, mChargingIcon, mAlarmIcon);
}
/** {@inheritDoc} */
@@ -508,7 +471,7 @@
switch (status) {
case Normal:
// text
- mCarrier.setText(
+ mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
mUpdateMonitor.getTelephonySpn()));
@@ -524,7 +487,7 @@
case NetworkLocked:
// The carrier string shows both sim card status (i.e. No Sim Card) and
// carrier's name and/or "Emergency Calls Only" status
- mCarrier.setText(
+ mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_network_locked_message)));
@@ -537,7 +500,7 @@
break;
case SimMissing:
// text
- mCarrier.setText(R.string.lockscreen_missing_sim_message_short);
+ mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions);
// layout
@@ -548,7 +511,7 @@
break;
case SimMissingLocked:
// text
- mCarrier.setText(
+ mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_missing_sim_message_short)));
@@ -562,7 +525,7 @@
break;
case SimLocked:
// text
- mCarrier.setText(
+ mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_sim_locked_message)));
@@ -574,7 +537,7 @@
break;
case SimPukLocked:
// text
- mCarrier.setText(
+ mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_sim_puk_locked_message)));
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 60cd56c..9db86aa 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -30,6 +30,7 @@
import android.telephony.TelephonyManager;
import android.text.method.DigitsKeyListener;
import android.text.method.TextKeyListener;
+import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -50,6 +51,7 @@
public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen,
View.OnClickListener, KeyguardUpdateMonitor.InfoCallback, OnEditorActionListener {
+ private static final String TAG = "PasswordUnlockScreen";
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
@@ -59,12 +61,15 @@
private Button mEmergencyCallButton;
private LockPatternUtils mLockPatternUtils;
private PasswordEntryKeyboardView mKeyboardView;
+ private PasswordEntryKeyboardView mKeyboardViewAlpha;
private PasswordEntryKeyboardHelper mKeyboardHelper;
+ private PasswordEntryKeyboardHelper mKeyboardHelperAlpha;
private int mCreationOrientation;
private int mCreationHardKeyboardHidden;
private CountDownTimer mCountdownTimer;
- private TextView mTitle;
+
+ private StatusView mStatusView;
// To avoid accidental lockout due to events while the device in in the pocket, ignore
// any passwords with length less than or equal to this length.
@@ -88,25 +93,43 @@
layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true);
}
+ mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
+
final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
+ mKeyboardViewAlpha = (PasswordEntryKeyboardView) findViewById(R.id.keyboardAlpha);
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
mPasswordEntry.setOnEditorActionListener(this);
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
mEmergencyCallButton.setOnClickListener(this);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
- mTitle = (TextView) findViewById(R.id.enter_password_label);
- mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this);
- mKeyboardHelper.setKeyboardMode(mIsAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
- : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+ mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
+ if (mKeyboardViewAlpha == null || !mIsAlpha) {
+ mKeyboardHelper.setKeyboardMode(mIsAlpha ?
+ PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA
+ : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+ mKeyboardView.setVisibility(
+ mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
+ ? View.INVISIBLE : View.VISIBLE);
+ } else {
+ mKeyboardHelperAlpha = new PasswordEntryKeyboardHelper(context, mKeyboardViewAlpha,
+ this, false);
+ mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
+ mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
+ mKeyboardView.setVisibility(View.GONE);
+ mKeyboardViewAlpha.setVisibility(
+ mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
+ ? View.INVISIBLE : View.VISIBLE);
+ mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width);
+ }
- mKeyboardView.setVisibility(mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
- ? View.INVISIBLE : View.VISIBLE);
+ mPasswordEntry.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
+ 0, 0);
mPasswordEntry.requestFocus();
// This allows keyboards with overlapping qwerty/numeric keys to choose just the
@@ -115,11 +138,20 @@
mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
} else {
mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
- mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
+ mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code);
}
mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
com.android.internal.R.array.config_virtualKeyVibePattern : 0);
+ if (mKeyboardHelperAlpha != null) {
+ mKeyboardHelperAlpha.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
+ com.android.internal.R.array.config_virtualKeyVibePattern : 0);
+ }
+
+ // until we get an update...
+ mStatusView.setCarrierText(LockScreen.getCarrierString(
+ mUpdateMonitor.getTelephonyPlmn(),
+ mUpdateMonitor.getTelephonySpn()));
}
@Override
@@ -140,6 +172,9 @@
/** {@inheritDoc} */
public void onResume() {
+ // reset status
+ mStatusView.resetStatusInfo(mUpdateMonitor, mLockPatternUtils);
+
// start fresh
mPasswordEntry.setText("");
resetStatusInfo();
@@ -179,9 +214,9 @@
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
handleAttemptLockout(deadline);
}
- mTitle.setText(R.string.lockscreen_password_wrong);
+ mStatusView.setInstructionText(R.string.lockscreen_password_wrong);
} else if (entry.length() > 0) {
- mTitle.setText(R.string.lockscreen_password_wrong);
+ mStatusView.setInstructionText(R.string.lockscreen_password_wrong);
}
mPasswordEntry.setText("");
}
@@ -199,7 +234,7 @@
String instructions = getContext().getString(
R.string.lockscreen_too_many_failed_attempts_countdown,
secondsRemaining);
- mTitle.setText(instructions);
+ mStatusView.setInstructionText(instructions);
}
@Override
@@ -252,31 +287,40 @@
return false;
}
+ // ---------- InfoCallback
+
+ /** {@inheritDoc} */
+ public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+ mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel);
+ }
+
+ /** {@inheritDoc} */
+ public void onTimeChanged() {
+ mStatusView.onTimeChanged();
+ }
+
+ /** {@inheritDoc} */
+ public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+ mStatusView.onRefreshCarrierInfo(plmn, spn);
+ }
+
+ /** {@inheritDoc} */
+ public void onRingerModeChanged(int state) {
+ // not currently used
+ }
+
+ // ---------- SimStateCallback
+
+ /** {@inheritDoc} */
public void onPhoneStateChanged(String newState) {
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
}
- public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
-
- }
-
- public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
-
- }
-
- public void onRingerModeChanged(int state) {
-
- }
-
- public void onTimeChanged() {
-
- }
-
private void resetStatusInfo() {
if(mIsAlpha) {
- mTitle.setText(R.string.keyguard_password_enter_password_code);
+ mStatusView.setInstructionText(R.string.keyguard_password_enter_password_code);
} else {
- mTitle.setText(R.string.keyguard_password_enter_pin_password_code);
+ mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 418e243..35fa3e5 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -25,9 +25,6 @@
import android.view.ViewGroup;
import android.view.MotionEvent;
import android.widget.Button;
-import android.widget.TextView;
-import android.text.format.DateFormat;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.telephony.IccCard;
@@ -37,7 +34,6 @@
import com.android.internal.widget.LockPatternView.Cell;
import java.util.List;
-import java.util.Date;
/**
* This is the screen that shows the 9 circle unlock widget and instructs
@@ -75,27 +71,7 @@
*/
private boolean mEnableFallback;
- private String mDateFormatString;
-
- private TextView mCarrier;
- private TextView mDate;
-
- // are we showing battery information?
- private boolean mShowingBatteryInfo = false;
-
- // last known plugged in state
- private boolean mPluggedIn = false;
-
- // last known battery level
- private int mBatteryLevel = 100;
-
- private String mNextAlarm = null;
-
- private String mInstructions = null;
- private TextView mStatus1;
- private TextView mStatusSep;
- private TextView mStatus2;
-
+ private StatusView mStatusView;
private LockPatternView mLockPatternView;
@@ -133,15 +109,18 @@
private void updateFooter(FooterMode mode) {
switch (mode) {
case Normal:
+ Log.d(TAG, "mode normal");
mFooterNormal.setVisibility(View.VISIBLE);
mFooterForgotPattern.setVisibility(View.GONE);
break;
case ForgotLockPattern:
+ Log.d(TAG, "mode ForgotLockPattern");
mFooterNormal.setVisibility(View.GONE);
mFooterForgotPattern.setVisibility(View.VISIBLE);
mForgotPatternButton.setVisibility(View.VISIBLE);
break;
case VerifyUnlocked:
+ Log.d(TAG, "mode VerifyUnlocked");
mFooterNormal.setVisibility(View.GONE);
mFooterForgotPattern.setVisibility(View.GONE);
}
@@ -180,24 +159,16 @@
mCreationOrientation = configuration.orientation;
LayoutInflater inflater = LayoutInflater.from(context);
+
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
+ Log.d(TAG, "portrait mode");
inflater.inflate(R.layout.keyguard_screen_unlock_portrait, this, true);
} else {
+ Log.d(TAG, "landscape mode");
inflater.inflate(R.layout.keyguard_screen_unlock_landscape, this, true);
}
- mCarrier = (TextView) findViewById(R.id.carrier);
- mDate = (TextView) findViewById(R.id.date);
-
- mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
- refreshTimeAndDateDisplay();
-
- mStatus1 = (TextView) findViewById(R.id.status1);
- mStatusSep = (TextView) findViewById(R.id.statusSep);
- mStatus2 = (TextView) findViewById(R.id.status2);
-
- resetStatusInfo();
-
+ mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
@@ -249,15 +220,11 @@
updateMonitor.registerSimStateCallback(this);
setFocusableInTouchMode(true);
- // Required to get Marquee to work.
- mCarrier.setSelected(true);
- mCarrier.setTextColor(0xffffffff);
-
// until we get an update...
- mCarrier.setText(
- LockScreen.getCarrierString(
+ mStatusView.setCarrierText(LockScreen.getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
mUpdateMonitor.getTelephonySpn()));
+
}
private void refreshEmergencyButtonText() {
@@ -270,88 +237,6 @@
mEnableFallback = state;
}
- private void resetStatusInfo() {
- mInstructions = null;
- mShowingBatteryInfo = mUpdateMonitor.shouldShowBatteryInfo();
- mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
- mBatteryLevel = mUpdateMonitor.getBatteryLevel();
- mNextAlarm = mLockPatternUtils.getNextAlarm();
- updateStatusLines();
- }
-
- private void updateStatusLines() {
- if (mInstructions != null) {
- // instructions only
- mStatus1.setText(mInstructions);
- if (TextUtils.isEmpty(mInstructions)) {
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
- } else {
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(
- R.drawable.ic_lock_idle_lock, 0, 0, 0);
- }
-
- mStatus1.setVisibility(View.VISIBLE);
- mStatusSep.setVisibility(View.GONE);
- mStatus2.setVisibility(View.GONE);
- } else if (mShowingBatteryInfo && mNextAlarm == null) {
- // battery only
- if (mPluggedIn) {
- if (mBatteryLevel >= 100) {
- mStatus1.setText(getContext().getString(R.string.lockscreen_charged));
- } else {
- mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel));
- }
- } else {
- mStatus1.setText(getContext().getString(R.string.lockscreen_low_battery));
- }
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0);
-
- mStatus1.setVisibility(View.VISIBLE);
- mStatusSep.setVisibility(View.GONE);
- mStatus2.setVisibility(View.GONE);
-
- } else if (mNextAlarm != null && !mShowingBatteryInfo) {
- // alarm only
- mStatus1.setText(mNextAlarm);
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0);
-
- mStatus1.setVisibility(View.VISIBLE);
- mStatusSep.setVisibility(View.GONE);
- mStatus2.setVisibility(View.GONE);
- } else if (mNextAlarm != null && mShowingBatteryInfo) {
- // both battery and next alarm
- mStatus1.setText(mNextAlarm);
- mStatusSep.setText("|");
- mStatus2.setText(getContext().getString(
- R.string.lockscreen_battery_short,
- Math.min(100, mBatteryLevel)));
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0);
- if (mPluggedIn) {
- mStatus2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0);
- } else {
- mStatus2.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
- }
-
- mStatus1.setVisibility(View.VISIBLE);
- mStatusSep.setVisibility(View.VISIBLE);
- mStatus2.setVisibility(View.VISIBLE);
- } else {
- // nothing specific to show; show general instructions
- mStatus1.setText(R.string.lockscreen_pattern_instructions);
- mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
-
- mStatus1.setVisibility(View.VISIBLE);
- mStatusSep.setVisibility(View.GONE);
- mStatus2.setVisibility(View.GONE);
- }
- }
-
-
- private void refreshTimeAndDateDisplay() {
- mDate.setText(DateFormat.format(mDateFormatString, new Date()));
- }
-
-
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// as long as the user is entering a pattern (i.e sending a touch
@@ -366,25 +251,21 @@
return result;
}
-
// ---------- InfoCallback
/** {@inheritDoc} */
public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
- mShowingBatteryInfo = showBatteryInfo;
- mPluggedIn = pluggedIn;
- mBatteryLevel = batteryLevel;
- updateStatusLines();
+ mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel);
}
/** {@inheritDoc} */
public void onTimeChanged() {
- refreshTimeAndDateDisplay();
+ mStatusView.onTimeChanged();
}
/** {@inheritDoc} */
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
- mCarrier.setText(LockScreen.getCarrierString(plmn, spn));
+ mStatusView.onRefreshCarrierInfo(plmn, spn);
}
/** {@inheritDoc} */
@@ -444,8 +325,8 @@
/** {@inheritDoc} */
public void onResume() {
- // reset header
- resetStatusInfo();
+ // reset status
+ mStatusView.resetStatusInfo(mUpdateMonitor, mLockPatternUtils);
// reset lock pattern
mLockPatternView.enableInput();
@@ -514,8 +395,8 @@
if (mLockPatternUtils.checkPattern(pattern)) {
mLockPatternView
.setDisplayMode(LockPatternView.DisplayMode.Correct);
- mInstructions = "";
- updateStatusLines();
+ mStatusView.setInstructions("");
+ mStatusView.updateStatusLines();
mCallback.keyguardDone(true);
mCallback.reportSuccessfulUnlockAttempt();
} else {
@@ -533,8 +414,9 @@
handleAttemptLockout(deadline);
} else {
// TODO mUnlockIcon.setVisibility(View.VISIBLE);
- mInstructions = getContext().getString(R.string.lockscreen_pattern_wrong);
- updateStatusLines();
+ mStatusView.setInstructions(
+ getContext().getString(R.string.lockscreen_pattern_wrong));
+ mStatusView.updateStatusLines();
mLockPatternView.postDelayed(
mCancelPatternRunnable,
PATTERN_CLEAR_TIMEOUT_MS);
@@ -552,17 +434,18 @@
@Override
public void onTick(long millisUntilFinished) {
int secondsRemaining = (int) (millisUntilFinished / 1000);
- mInstructions = getContext().getString(
+ mStatusView.setInstructions(getContext().getString(
R.string.lockscreen_too_many_failed_attempts_countdown,
- secondsRemaining);
- updateStatusLines();
+ secondsRemaining));
+ mStatusView.updateStatusLines();
}
@Override
public void onFinish() {
mLockPatternView.setEnabled(true);
- mInstructions = getContext().getString(R.string.lockscreen_pattern_instructions);
- updateStatusLines();
+ mStatusView.setInstructions(getContext().getString(
+ R.string.lockscreen_pattern_instructions));
+ mStatusView.updateStatusLines();
// TODO mUnlockIcon.setVisibility(View.VISIBLE);
mFailedPatternAttemptsSinceLastTimeout = 0;
if (mEnableFallback) {
diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java
new file mode 100644
index 0000000..3f08cfd
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/StatusView.java
@@ -0,0 +1,255 @@
+// Copyright 2010 Google Inc. All Rights Reserved.
+
+package com.android.internal.policy.impl;
+
+import com.android.internal.R;
+import com.android.internal.widget.LockPatternUtils;
+
+import java.util.Date;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+class StatusView {
+ private String mDateFormatString;
+
+ private TextView mCarrier;
+ private TextView mDate;
+
+ // are we showing battery information?
+ private boolean mShowingBatteryInfo = false;
+
+ // last known plugged in state
+ private boolean mPluggedIn = false;
+
+ // last known battery level
+ private int mBatteryLevel = 100;
+
+ private String mNextAlarm = null;
+
+ private String mInstructions = null;
+ private TextView mStatus1;
+ private TextView mStatus2;
+ private TextView mPropertyOf;
+
+ private boolean mHasStatus2;
+ private boolean mHasCarrier;
+ private boolean mHasDate;
+ private boolean mHasProperty;
+
+ private View mView;
+
+ private View findViewById(int id) {
+ return mView.findViewById(id);
+ }
+
+ private Context getContext() {
+ return mView.getContext();
+ }
+
+ void setInstructions(String instructions) {
+ mInstructions = instructions;
+ }
+
+ void setCarrierText(CharSequence carrierText) {
+ if (mCarrier != null) {
+ mCarrier.setText(carrierText);
+ }
+ }
+
+ void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+ mShowingBatteryInfo = showBatteryInfo;
+ mPluggedIn = pluggedIn;
+ mBatteryLevel = batteryLevel;
+ updateStatusLines();
+ }
+
+ void onTimeChanged() {
+ refreshTimeAndDateDisplay();
+ }
+
+ public void onRingerModeChanged(int state) {
+ }
+
+ void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+ setCarrierText(LockScreen.getCarrierString(plmn, spn));
+ }
+
+ public StatusView(View view, KeyguardUpdateMonitor updateMonitor,
+ LockPatternUtils lockPatternUtils) {
+ mView = view;
+ mCarrier = (TextView) findViewById(R.id.carrier);
+ mHasCarrier = (mCarrier != null);
+ mDate = (TextView) findViewById(R.id.date);
+ mHasDate = (mDate != null);
+ mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
+
+ refreshTimeAndDateDisplay();
+
+ mStatus1 = (TextView) findViewById(R.id.status1);
+ mStatus2 = (TextView) findViewById(R.id.status2);
+ mHasStatus2 = (mStatus2 != null);
+ mPropertyOf = (TextView) findViewById(R.id.propertyOf);
+ mHasProperty = (mPropertyOf != null);
+
+ resetStatusInfo(updateMonitor, lockPatternUtils);
+
+ // Required to get Marquee to work.
+ if (mHasCarrier) {
+ mCarrier.setSelected(true);
+ mCarrier.setTextColor(0xffffffff);
+ }
+
+ }
+
+ void resetStatusInfo(KeyguardUpdateMonitor updateMonitor, LockPatternUtils lockPatternUtils) {
+ mInstructions = null;
+ mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo();
+ mPluggedIn = updateMonitor.isDevicePluggedIn();
+ mBatteryLevel = updateMonitor.getBatteryLevel();
+ mNextAlarm = lockPatternUtils.getNextAlarm();
+ updateStatusLines();
+ }
+
+ void setInstructionText(int stringId) {
+ mStatus1.setText(stringId);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
+ mStatus1.setVisibility(View.VISIBLE);
+ }
+
+ void setInstructionText(String string) {
+ mStatus1.setText(string);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0);
+ mStatus1.setVisibility(View.VISIBLE);
+ }
+
+ void setCarrierText(int stringId) {
+ mCarrier.setText(stringId);
+ }
+ void setCarrierText(String string) {
+ mCarrier.setText(string);
+ }
+
+ /** Originated from PatternUnlockScreen **/
+ void updateStatusLines() {
+ if (mHasProperty) {
+ // TODO Get actual name & email
+ String name = "John Smith";
+ String email = "jsmith@gmail.com";
+ mPropertyOf.setText("Property of:\n" + name + "\n" + email);
+ mPropertyOf.setVisibility(View.VISIBLE);
+ }
+
+ if (!mHasStatus2) return;
+
+ if (mInstructions != null) {
+ // instructions only
+ mStatus1.setText(mInstructions);
+ if (TextUtils.isEmpty(mInstructions)) {
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ } else {
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.ic_lock_idle_lock, 0, 0, 0);
+ }
+
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+ } else if (mShowingBatteryInfo && mNextAlarm == null) {
+ // battery only
+ if (mPluggedIn) {
+ if (mBatteryLevel >= 100) {
+ mStatus1.setText(getContext().getString(R.string.lockscreen_charged));
+ } else {
+ mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in,
+ mBatteryLevel));
+ }
+ } else {
+ mStatus1.setText(getContext().getString(R.string.lockscreen_low_battery));
+ }
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0,
+ 0, 0);
+
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+
+ } else if (mNextAlarm != null && !mShowingBatteryInfo) {
+ // alarm only
+ mStatus1.setText(mNextAlarm);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0,
+ 0, 0);
+
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+ } else if (mNextAlarm != null && mShowingBatteryInfo) {
+ // both battery and next alarm
+ mStatus1.setText(mNextAlarm);
+ mStatus2.setText(getContext().getString(
+ R.string.lockscreen_battery_short,
+ Math.min(100, mBatteryLevel)));
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0,
+ 0, 0);
+ if (mPluggedIn) {
+ mStatus2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging,
+ 0, 0, 0);
+ } else {
+ mStatus2.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.VISIBLE);
+ } else {
+ // nothing specific to show; show general instructions
+ mStatus1.setText(R.string.lockscreen_pattern_instructions);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
+ 0, 0);
+
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ /** Originated from LockScreen **/
+ // TODO Merge with function above
+ void updateStatusLines(boolean showStatusLines, String charging, Drawable chargingIcon,
+ Drawable alarmIcon) {
+ if (!showStatusLines || (charging == null && mNextAlarm == null)) {
+ mStatus1.setVisibility(View.INVISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+ } else if (charging != null && mNextAlarm == null) {
+ // charging only
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+
+ mStatus1.setText(charging);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(chargingIcon, null, null, null);
+ } else if (mNextAlarm != null && charging == null) {
+ // next alarm only
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.INVISIBLE);
+
+ mStatus1.setText(mNextAlarm);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(alarmIcon, null, null, null);
+ } else if (charging != null && mNextAlarm != null) {
+ // both charging and next alarm
+ mStatus1.setVisibility(View.VISIBLE);
+ mStatus2.setVisibility(View.VISIBLE);
+
+ mStatus1.setText(charging);
+ mStatus1.setCompoundDrawablesWithIntrinsicBounds(chargingIcon, null, null, null);
+ mStatus2.setText(mNextAlarm);
+ mStatus2.setCompoundDrawablesWithIntrinsicBounds(alarmIcon, null, null, null);
+ }
+ }
+
+ void refreshTimeAndDateDisplay() {
+ if (mHasDate) {
+ mDate.setText(DateFormat.format(mDateFormatString, new Date()));
+ }
+ }
+
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 1c7faa4..6e7633e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1675,6 +1675,9 @@
float masterVolume = mMasterVolume;
bool masterMute = mMasterMute;
+ if (masterMute) {
+ masterVolume = 0;
+ }
#ifdef LVMX
bool tracksConnectedChanged = false;
bool stateChanged = false;
@@ -1696,10 +1699,7 @@
// Delegate master volume control to effect in output mix effect chain if needed
sp<EffectChain> chain = getEffectChain_l(AudioSystem::SESSION_OUTPUT_MIX);
if (chain != 0) {
- uint32_t v = 0;
- if (!masterMute) {
- v = (uint32_t)(masterVolume * (1 << 24));
- }
+ uint32_t v = (uint32_t)(masterVolume * (1 << 24));
chain->setVolume_l(&v, &v);
masterVolume = (float)((v + (1 << 23)) >> 24);
chain.clear();
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8b0a9de..b0fa0f5 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1385,7 +1385,7 @@
* Normalize a phone number by removing the characters other than digits. If
* the given number has keypad letters, the letters will be converted to
* digits first.
- *
+ *
* @param phoneNumber
* the number to be normalized.
* @return the normalized number.
@@ -1397,9 +1397,9 @@
int len = phoneNumber.length();
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
- if (PhoneNumberUtils.isISODigit(c)) {
+ if ((i == 0 && c == '+') || PhoneNumberUtils.isISODigit(c)) {
sb.append(c);
- } else if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
+ } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
}
}
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index 5ef1c69..88aa78ef 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -524,6 +524,7 @@
assertEquals("6502910000", PhoneNumberUtils.normalizeNumber("650 2910000"));
assertEquals("1234567", PhoneNumberUtils.normalizeNumber("12,3#4*567"));
assertEquals("8004664114", PhoneNumberUtils.normalizeNumber("800-GOOG-114"));
+ assertEquals("+16502910000", PhoneNumberUtils.normalizeNumber("+1 650 2910000"));
}
}
diff --git a/tests/DumpRenderTree2/Android.mk b/tests/DumpRenderTree2/Android.mk
index eddbb4b..81fc633 100644
--- a/tests/DumpRenderTree2/Android.mk
+++ b/tests/DumpRenderTree2/Android.mk
@@ -1,3 +1,18 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
diff --git a/tests/DumpRenderTree2/assets/run-apache2.py b/tests/DumpRenderTree2/assets/run-apache2.py
index d7590ee..cffbe37 100644
--- a/tests/DumpRenderTree2/assets/run-apache2.py
+++ b/tests/DumpRenderTree2/assets/run-apache2.py
@@ -1,5 +1,19 @@
#!/usr/bin/python
-
+#
+# Copyright (C) 2010 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.
+#
"""Start, stop, or restart apache2 server.
Apache2 must be installed with mod_php!
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
index 59f665c..8af1b7b 100644
--- a/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/TextActivity.java
@@ -65,8 +65,16 @@
canvas.drawText("Hello OpenGL renderer!", 100, 60, mMediumPaint);
mMediumPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("Hello OpenGL renderer!", 100, 100, mMediumPaint);
+ mMediumPaint.setShadowLayer(2.5f, 0.0f, 0.0f, 0xff000000);
+ canvas.drawText("Hello OpenGL renderer!", 100, 150, mMediumPaint);
+ mMediumPaint.clearShadowLayer();
canvas.drawText("Hello OpenGL renderer!", 100, 200, mLargePaint);
-
+
+ mLargePaint.setShadowLayer(2.5f, 3.0f, 3.0f, 0xff000000);
+ canvas.drawText("Hello OpenGL renderer!", 100, 400, mLargePaint);
+ mLargePaint.setShadowLayer(3.0f, 3.0f, 3.0f, 0xff00ff00);
+ canvas.drawText("Hello OpenGL renderer!", 100, 500, mLargePaint);
+ mLargePaint.clearShadowLayer();
canvas.drawText("Hello OpenGL renderer!", 500, 40, mStrikePaint);
mStrikePaint.setStrikeThruText(true);
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index d6cfb12..e4f447e 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1830,6 +1830,16 @@
continue;
}
+ if (bundle->getMaxResVersion() != NULL && group.version.length() != 0) {
+ int maxResInt = atoi(bundle->getMaxResVersion());
+ const char *verString = group.version.string();
+ int dirVersionInt = atoi(verString + 1); // skip 'v' in version name
+ if (dirVersionInt > maxResInt) {
+ fprintf(stderr, "max res %d, skipping %s\n", maxResInt, entry->d_name);
+ continue;
+ }
+ }
+
FileType type = getFileType(subdirName.string());
if (type == kFileTypeDirectory) {
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 3308a35..6a1f2d5 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,6 +45,7 @@
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
+ mMaxResVersion(NULL),
mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -134,6 +135,8 @@
void setVersionName(const char* val) { mVersionName = val; }
const char* getCustomPackage() const { return mCustomPackage; }
void setCustomPackage(const char* val) { mCustomPackage = val; }
+ const char* getMaxResVersion() const { return mMaxResVersion; }
+ void setMaxResVersion(const char * val) { mMaxResVersion = val; }
/*
* Set and get the file specification.
@@ -230,6 +233,7 @@
const char* mVersionCode;
const char* mVersionName;
const char* mCustomPackage;
+ const char* mMaxResVersion;
/* file specification */
int mArgc;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index b0c6e39..f457cc8 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -62,6 +62,7 @@
" [--rename-manifest-package PACKAGE] \\\n"
" [--rename-instrumentation-target-package PACKAGE] \\\n"
" [--utf16] [--auto-add-overlay] \\\n"
+ " [--max-res-version VAL] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
" [-S resource-sources [-S resource-sources ...]] "
@@ -128,6 +129,8 @@
" higher, the default encoding for resources will be in UTF-8.\n"
" --target-sdk-version\n"
" inserts android:targetSdkVersion in to manifest.\n"
+ " --max-res-version\n"
+ " ignores versioned resource directories above the given value.\n"
" --values\n"
" when used with \"dump resources\" also includes resource values.\n"
" --version-code\n"
@@ -416,6 +419,15 @@
goto bail;
}
bundle.setMaxSdkVersion(argv[0]);
+ } else if (strcmp(cp, "-max-res-version") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--max-res-version' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setMaxResVersion(argv[0]);
} else if (strcmp(cp, "-version-code") == 0) {
argc--;
argv++;