Merge "Update variable to reflect its true value."
diff --git a/api/current.xml b/api/current.xml
index b0056d7..4356852 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"
@@ -21785,7 +21796,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="id" type="int">
@@ -21798,7 +21809,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="tag" type="java.lang.String">
@@ -22995,7 +23006,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</method>
@@ -23032,7 +23043,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</method>
@@ -23043,7 +23054,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="name" type="java.lang.String">
@@ -23058,7 +23069,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="id" type="int">
@@ -27845,6 +27856,28 @@
visibility="public"
>
</method>
+<method name="getTargetFragment"
+ return="android.app.Fragment"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTargetRequestCode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getView"
return="android.view.View"
abstract="false"
@@ -28147,8 +28180,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="activity" type="android.app.Activity">
-</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<parameter name="savedInstanceState" type="android.os.Bundle">
@@ -28280,7 +28311,7 @@
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -28313,6 +28344,21 @@
<parameter name="retain" type="boolean">
</parameter>
</method>
+<method name="setTargetFragment"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fragment" type="android.app.Fragment">
+</parameter>
+<parameter name="requestCode" type="int">
+</parameter>
+</method>
<method name="startActivity"
return="void"
abstract="false"
@@ -73982,7 +74028,7 @@
<method name="setShadowLayer"
return="void"
abstract="false"
- native="true"
+ native="false"
synchronized="false"
static="false"
final="false"
@@ -86983,6 +87029,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"
@@ -137623,6 +137687,17 @@
visibility="public"
>
</method>
+<method name="getExtras"
+ return="android.os.Bundle"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getFragment"
return="java.lang.String"
abstract="false"
@@ -138066,6 +138141,17 @@
<parameter name="defaultValue" type="java.lang.Object">
</parameter>
</method>
+<method name="peekExtras"
+ return="android.os.Bundle"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="persistBoolean"
return="boolean"
abstract="false"
@@ -147418,11 +147504,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 +147519,7 @@
type="int"
transient="false"
volatile="false"
- value="2"
+ value="1"
static="true"
final="true"
deprecated="not deprecated"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ec3cbc3..d40d7d8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1590,7 +1590,9 @@
/**
* Start a series of edit operations on the Fragments associated with
* this activity.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public FragmentTransaction openFragmentTransaction() {
return mFragments.openTransaction();
}
@@ -1782,7 +1784,9 @@
* from XML or as the container ID when added in a transaction. This only
* returns fragments that are currently added to the activity's content.
* @return The fragment if found or null otherwise.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public Fragment findFragmentById(int id) {
return mFragments.findFragmentById(id);
}
@@ -1792,7 +1796,9 @@
* from XML or as supplied when added in a transaction. This only
* returns fragments that are currently added to the activity's content.
* @return The fragment if found or null otherwise.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public Fragment findFragmentByTag(String tag) {
return mFragments.findFragmentByTag(tag);
}
@@ -2078,7 +2084,9 @@
/**
* Pop the top state off the back stack. Returns true if there was one
* to pop, else false.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public boolean popBackStack() {
return mFragments.popBackStack();
}
@@ -2091,7 +2099,9 @@
* {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
* the named state itself is popped. If null, only the top state is popped.
* @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public boolean popBackStack(String name, int flags) {
return mFragments.popBackStack(name, flags);
}
@@ -2105,7 +2115,9 @@
* {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
* the named state itself is popped.
* @param flags Either 0 or {@link #POP_BACK_STACK_INCLUSIVE}.
+ * @deprecated use {@link #getFragmentManager}.
*/
+ @Deprecated
public boolean popBackStack(int id, int flags) {
return mFragments.popBackStack(id, flags);
}
@@ -2116,7 +2128,7 @@
* but you can override this to do whatever you want.
*/
public void onBackPressed() {
- if (!popBackStack()) {
+ if (!mFragments.popBackStack()) {
finish();
}
}
@@ -3995,9 +4007,12 @@
return null;
}
+ String fname = attrs.getAttributeValue(null, "class");
TypedArray a =
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
- String fname = a.getString(com.android.internal.R.styleable.Fragment_name);
+ if (fname == null) {
+ fname = a.getString(com.android.internal.R.styleable.Fragment_name);
+ }
int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, 0);
String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
a.recycle();
@@ -4020,14 +4035,14 @@
fragment.mFragmentId = id;
fragment.mTag = tag;
fragment.mImmediateActivity = this;
+ // If this fragment is newly instantiated (either right now, or
+ // from last saved state), then give it the attributes to
+ // initialize itself.
+ if (!fragment.mRetaining) {
+ fragment.onInflate(attrs, fragment.mSavedFragmentState);
+ }
mFragments.addFragment(fragment, true);
}
- // If this fragment is newly instantiated (either right now, or
- // from last saved state), then give it the attributes to
- // initialize itself.
- if (!fragment.mRetaining) {
- fragment.onInflate(this, attrs, fragment.mSavedFragmentState);
- }
if (fragment.mView == null) {
throw new IllegalStateException("Fragment " + fname
+ " did not create a view.");
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index 3124f0d..50e7421 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -79,6 +79,7 @@
Dialog mDialog;
boolean mDestroyed;
+ boolean mRemoved;
public DialogFragment() {
}
@@ -136,6 +137,7 @@
*/
public int show(Activity activity, FragmentTransaction transaction, String tag) {
transaction.add(this, tag);
+ mRemoved = false;
mBackStackId = transaction.commit();
return mBackStackId;
}
@@ -149,12 +151,15 @@
public void dismiss() {
if (mDialog != null) {
mDialog.dismiss();
+ mDialog = null;
}
+ mRemoved = true;
if (mBackStackId >= 0) {
- getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE);
+ getFragmentManager().popBackStack(mBackStackId,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
mBackStackId = -1;
} else {
- FragmentTransaction ft = getActivity().openFragmentTransaction();
+ FragmentTransaction ft = getFragmentManager().openTransaction();
ft.remove(this);
ft.commit();
}
@@ -193,15 +198,12 @@
}
public void onCancel(DialogInterface dialog) {
- if (mBackStackId >= 0) {
- // If this fragment is part of the back stack, then cancelling
- // the dialog means popping off the back stack.
- getActivity().popBackStack(mBackStackId, Activity.POP_BACK_STACK_INCLUSIVE);
- mBackStackId = -1;
- }
}
public void onDismiss(DialogInterface dialog) {
+ if (!mRemoved) {
+ dismiss();
+ }
}
@Override
@@ -241,7 +243,10 @@
@Override
public void onStart() {
super.onStart();
- mDialog.show();
+ if (mDialog != null) {
+ mRemoved = false;
+ mDialog.show();
+ }
}
@Override
@@ -262,17 +267,25 @@
@Override
public void onStop() {
super.onStop();
- mDialog.hide();
+ if (mDialog != null) {
+ mDialog.hide();
+ }
}
/**
- * Detach from list view.
+ * Remove dialog.
*/
@Override
public void onDestroyView() {
super.onDestroyView();
mDestroyed = true;
- mDialog.dismiss();
- mDialog = null;
+ if (mDialog != null) {
+ // Set removed here because this dismissal is just to hide
+ // the dialog -- we don't want this to cause the fragment to
+ // actually be removed.
+ mRemoved = true;
+ mDialog.dismiss();
+ mDialog = null;
+ }
}
}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index bc839d7..6a1d527 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -42,8 +42,6 @@
import java.util.HashMap;
final class FragmentState implements Parcelable {
- static final String VIEW_STATE_TAG = "android:view_state";
-
final String mClassName;
final int mIndex;
final boolean mFromLayout;
@@ -90,8 +88,6 @@
if (mSavedFragmentState != null) {
mSavedFragmentState.setClassLoader(activity.getClassLoader());
mInstance.mSavedFragmentState = mSavedFragmentState;
- mInstance.mSavedViewState
- = mSavedFragmentState.getSparseParcelableArray(VIEW_STATE_TAG);
}
mInstance.setIndex(mIndex);
mInstance.mFromLayout = mFromLayout;
@@ -160,6 +156,12 @@
// Construction arguments;
Bundle mArguments;
+ // Target fragment.
+ Fragment mTarget;
+
+ // Target request code.
+ int mTargetRequestCode;
+
// True if the fragment is in the list of added fragments.
boolean mAdded;
@@ -375,7 +377,7 @@
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
- final public void setArguments(Bundle args) {
+ public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
@@ -391,6 +393,36 @@
}
/**
+ * Optional target for this fragment. This may be used, for example,
+ * if this fragment is being started by another, and when done wants to
+ * give a result back to the first. The target set here is retained
+ * across instances via {@link FragmentManager#putFragment
+ * FragmentManager.putFragment()}.
+ *
+ * @param fragment The fragment that is the target of this one.
+ * @param requestCode Optional request code, for convenience if you
+ * are going to call back with {@link #onActivityResult(int, int, Intent)}.
+ */
+ public void setTargetFragment(Fragment fragment, int requestCode) {
+ mTarget = fragment;
+ mTargetRequestCode = requestCode;
+ }
+
+ /**
+ * Return the target fragment set by {@link #setTargetFragment}.
+ */
+ final public Fragment getTargetFragment() {
+ return mTarget;
+ }
+
+ /**
+ * Return the target request code set by {@link #setTargetFragment}.
+ */
+ final public int getTargetRequestCode() {
+ return mTargetRequestCode;
+ }
+
+ /**
* Return the Activity this fragment is currently associated with.
*/
final public Activity getActivity() {
@@ -537,21 +569,30 @@
/**
* Called when a fragment is being created as part of a view layout
* inflation, typically from setting the content view of an activity. This
- * will be called both the first time the fragment is created, as well
- * later when it is being re-created from its saved state (which is also
- * given here).
+ * will be called immediately after the fragment is created from a <fragment>
+ * tag in a layout file. Note this is <em>before</em> the fragment's
+ * {@link #onAttach(Activity)} has been called; all you should do here is
+ * parse the attributes and save them away. A convenient thing to do is
+ * simply copy them into a Bundle that is given to {@link #setArguments(Bundle)}.
*
- * XXX This is kind-of yucky... maybe we could just supply the
- * AttributeSet to onCreate()?
+ * <p>This is called every time the fragment is inflated, even if it is
+ * being inflated into a new instance with saved state. Because a fragment's
+ * arguments are retained across instances, it may make no sense to re-parse
+ * the attributes into new arguments. You may want to first check
+ * {@link #getArguments()} and only parse the attributes if it returns null,
+ * the assumption being that if it is non-null those are the same arguments
+ * from the first time the fragment was inflated. (That said, you may want
+ * to have layouts change for different configurations such as landscape
+ * and portrait, which can have different attributes. If so, you will need
+ * to re-parse the attributes each time this is called to generate new
+ * arguments.)</p>
*
- * @param activity The Activity that is inflating the fragment.
* @param attrs The attributes at the tag where the fragment is
* being created.
* @param savedInstanceState If the fragment is being re-created from
* a previous saved state, this is the state.
*/
- public void onInflate(Activity activity, AttributeSet attrs,
- Bundle savedInstanceState) {
+ public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
mCalled = true;
}
@@ -693,8 +734,10 @@
* Called when the view previously created by {@link #onCreateView} has
* been detached from the fragment. The next time the fragment needs
* to be displayed, a new view will be created. This is called
- * after {@link #onStop()} and before {@link #onDestroy()}; it is only
- * called if {@link #onCreateView} returns a non-null View.
+ * after {@link #onStop()} and before {@link #onDestroy()}. It is called
+ * <em>regardless</em> of whether {@link #onCreateView} returned a
+ * non-null view. Internally it is called after the view's state has
+ * been saved but before it has been removed from its parent.
*/
public void onDestroyView() {
mCalled = true;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 0556f05..f190d0d 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -166,13 +166,16 @@
}
/**
- * @hide
* Container for fragments associated with an activity.
*/
-class FragmentManagerImpl implements FragmentManager {
+final class FragmentManagerImpl implements FragmentManager {
static final boolean DEBUG = true;
static final String TAG = "FragmentManager";
+ static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
+ static final String TARGET_STATE_TAG = "android:target_state";
+ static final String VIEW_STATE_TAG = "android:view_state";
+
ArrayList<Runnable> mPendingActions;
Runnable[] mTmpActions;
boolean mExecutingActions;
@@ -201,7 +204,6 @@
execPendingActions();
}
};
-
public FragmentTransaction openTransaction() {
return new BackStackEntry(this);
}
@@ -230,7 +232,10 @@
}
public Fragment getFragment(Bundle bundle, String key) {
- int index = bundle.getInt(key);
+ int index = bundle.getInt(key, -1);
+ if (index == -1) {
+ return null;
+ }
if (index >= mActive.size()) {
throw new IllegalStateException("Fragement no longer exists for key "
+ key + ": index " + index);
@@ -296,6 +301,16 @@
switch (f.mState) {
case Fragment.INITIALIZING:
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
+ if (f.mSavedFragmentState != null) {
+ f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
+ FragmentManagerImpl.VIEW_STATE_TAG);
+ f.mTarget = getFragment(f.mSavedFragmentState,
+ FragmentManagerImpl.TARGET_STATE_TAG);
+ if (f.mTarget != null) {
+ f.mTargetRequestCode = f.mSavedFragmentState.getInt(
+ FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
+ }
+ }
f.mActivity = mActivity;
f.mCalled = false;
f.onAttach(mActivity);
@@ -419,32 +434,32 @@
if (newState < Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "movefrom CONTENT: " + f);
if (f.mView != null) {
- f.mCalled = false;
- f.onDestroyView();
- if (!f.mCalled) {
- throw new SuperNotCalledException("Fragment " + f
- + " did not call through to super.onDestroyedView()");
- }
// Need to save the current view state if not
// done already.
if (!mActivity.isFinishing() && f.mSavedFragmentState == null) {
saveFragmentViewState(f);
}
- if (f.mContainer != null) {
- if (mCurState > Fragment.INITIALIZING) {
- Animatable anim = loadAnimatable(f, transit, true,
- transitionStyle);
- if (anim != null) {
- if (anim instanceof Sequencer) {
- ((Sequencer)anim).setTarget(f.mView);
- } else if (anim instanceof PropertyAnimator) {
- ((PropertyAnimator)anim).setTarget(f.mView);
- }
- anim.start();
+ }
+ f.mCalled = false;
+ f.onDestroyView();
+ if (!f.mCalled) {
+ throw new SuperNotCalledException("Fragment " + f
+ + " did not call through to super.onDestroyedView()");
+ }
+ if (f.mView != null && f.mContainer != null) {
+ if (mCurState > Fragment.INITIALIZING) {
+ Animatable anim = loadAnimatable(f, transit, true,
+ transitionStyle);
+ if (anim != null) {
+ if (anim instanceof Sequencer) {
+ ((Sequencer)anim).setTarget(f.mView);
+ } else if (anim instanceof PropertyAnimator) {
+ ((PropertyAnimator)anim).setTarget(f.mView);
}
+ anim.start();
}
- f.mContainer.removeView(f.mView);
}
+ f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
@@ -908,7 +923,20 @@
fs.mSavedFragmentState = new Bundle();
}
fs.mSavedFragmentState.putSparseParcelableArray(
- FragmentState.VIEW_STATE_TAG, f.mSavedViewState);
+ FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
+ }
+ }
+
+ if (f.mTarget != null) {
+ if (fs.mSavedFragmentState == null) {
+ fs.mSavedFragmentState = new Bundle();
+ }
+ putFragment(fs.mSavedFragmentState,
+ FragmentManagerImpl.TARGET_STATE_TAG, f.mTarget);
+ if (f.mTargetRequestCode != 0) {
+ fs.mSavedFragmentState.putInt(
+ FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG,
+ f.mTargetRequestCode);
}
}
@@ -976,7 +1004,7 @@
f.mAdded = false;
if (fs.mSavedFragmentState != null) {
f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
- FragmentState.VIEW_STATE_TAG);
+ FragmentManagerImpl.VIEW_STATE_TAG);
}
}
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index e1d431f..22bce05 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -802,7 +802,7 @@
* @param uri The data in the content provider being queried.
* @param mimeTypeFilter The type of data the client desires. May be
* a pattern, such as *\/* to retrieve all possible data types.
- * @returns Returns null if there are no possible data streams for the
+ * @return Returns null if there are no possible data streams for the
* given mimeTypeFilter. Otherwise returns an array of all available
* concrete MIME types.
*
@@ -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/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 812af5a..9b23c1e 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1559,7 +1559,7 @@
/**
* Parse a series of {@link android.R.styleable#Extra <extra>} tags from
* an XML file. You call this when you are at the parent tag of the
- * extra tags, and it return once all of the child tags have been parsed.
+ * extra tags, and it will return once all of the child tags have been parsed.
* This will call {@link #parseBundleExtra} for each extra tag encountered.
*
* @param parser The parser from which to retrieve the extras.
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/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index efbccd2..965af8b 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -67,15 +67,10 @@
/**
* Create a new MobileDataStateTracker
- * @param context the application context of the caller
- * @param target a message handler for getting callbacks about state changes
* @param netType the ConnectivityManager network type
- * @param apnType the Phone apnType
* @param tag the name of this network
*/
- public MobileDataStateTracker(Context context, Handler target, int netType, String tag) {
- mTarget = target;
- mContext = context;
+ public MobileDataStateTracker(int netType, String tag) {
mNetworkInfo = new NetworkInfo(netType,
TelephonyManager.getDefault().getNetworkType(), tag,
TelephonyManager.getDefault().getNetworkTypeName());
@@ -101,6 +96,25 @@
}
/**
+ * Begin monitoring data connectivity.
+ *
+ * @param context is the current Android context
+ * @param target is the Hander to which to return the events.
+ */
+ public void startMonitoring(Context context, Handler target) {
+ mTarget = target;
+ mContext = context;
+
+ IntentFilter filter =
+ new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
+ filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
+
+ mContext.registerReceiver(new MobileDataStateReceiver(), filter);
+ mMobileDataState = Phone.DataState.DISCONNECTED;
+ }
+
+ /**
* Return the IP addresses of the DNS servers available for the mobile data
* network interface.
* @return a list of DNS addresses, with no holes.
@@ -139,45 +153,6 @@
public void releaseWakeLock() {
}
- /**
- * Begin monitoring mobile data connectivity.
- */
- public void startMonitoring() {
- IntentFilter filter =
- new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
- filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
- filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
-
- mContext.registerReceiver(new MobileDataStateReceiver(), filter);
- mMobileDataState = Phone.DataState.DISCONNECTED;
- }
-
- /**
- * Record the roaming status of the device, and if it is a change from the previous
- * status, send a notification to any listeners.
- * @param isRoaming {@code true} if the device is now roaming, {@code false}
- * if it is no longer roaming.
- */
- private void setRoamingStatus(boolean isRoaming) {
- if (isRoaming != mNetworkInfo.isRoaming()) {
- mNetworkInfo.setRoaming(isRoaming);
- Message msg = mTarget.obtainMessage(EVENT_ROAMING_CHANGED, mNetworkInfo);
- msg.sendToTarget();
- }
- }
-
- private void setSubtype(int subtype, String subtypeName) {
- if (mNetworkInfo.isConnected()) {
- int oldSubtype = mNetworkInfo.getSubtype();
- if (subtype != oldSubtype) {
- mNetworkInfo.setSubtype(subtype, subtypeName);
- Message msg = mTarget.obtainMessage(
- EVENT_NETWORK_SUBTYPE_CHANGED, oldSubtype, 0, mNetworkInfo);
- msg.sendToTarget();
- }
- }
- }
-
private class MobileDataStateReceiver extends BroadcastReceiver {
IConnectivityManager mConnectivityManager;
@@ -279,8 +254,6 @@
setDetailedState(DetailedState.FAILED, reason, apnName);
}
TelephonyManager tm = TelephonyManager.getDefault();
- setRoamingStatus(tm.isNetworkRoaming());
- setSubtype(tm.getNetworkType(), tm.getNetworkTypeName());
}
}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 82735e5..0048a2e 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -16,30 +16,76 @@
package android.net;
+import android.content.Context;
+import android.os.Handler;
+
/**
- * Interface for connectivity service to act on a network interface.
- * All state information for a network should be kept in a Tracker class.
- * This interface defines network-type-independent functions that should
- * be implemented by the Tracker class.
+ * Interface provides the {@link com.android.server.ConnectivityService}
+ * with three services. Events to the ConnectivityService when
+ * changes occur, an API for controlling the network and storage
+ * for network specific information.
+ *
+ * The Connectivity will call startMonitoring before any other
+ * method is called.
*
* {@hide}
*/
public interface NetworkStateTracker {
- public static final int EVENT_STATE_CHANGED = 1;
/**
- * arg1: 1 to show, 0 to hide
- * arg2: ID of the notification
- * obj: Notification (if showing)
+ * -------------------------------------------------------------
+ * Event Interface back to ConnectivityService.
+ *
+ * The events that are to be sent back to the Handler passed
+ * to startMonitoring when the particular event occurs.
+ * -------------------------------------------------------------
*/
- public static final int EVENT_NOTIFICATION_CHANGED = 2;
+
+ /**
+ * The network state has changed and the NetworkInfo object
+ * contains the new state.
+ *
+ * msg.what = EVENT_STATE_CHANGED
+ * msg.obj = NetworkInfo object
+ */
+ public static final int EVENT_STATE_CHANGED = 1;
+
+ /**
+ * msg.what = EVENT_CONFIGURATION_CHANGED
+ * msg.obj = NetworkInfo object
+ */
public static final int EVENT_CONFIGURATION_CHANGED = 3;
- public static final int EVENT_ROAMING_CHANGED = 4;
- public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 5;
+
+ /**
+ * msg.what = EVENT_RESTORE_DEFAULT_NETWORK
+ * msg.obj = FeatureUser object
+ */
public static final int EVENT_RESTORE_DEFAULT_NETWORK = 6;
+
+ /**
+ * USED by ConnectivityService only
+ *
+ * msg.what = EVENT_CLEAR_NET_TRANSITION_WAKELOCK
+ * msg.arg1 = mNetTransitionWakeLockSerialNumber
+ */
public static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 7;
/**
+ * -------------------------------------------------------------
+ * Control Interface
+ * -------------------------------------------------------------
+ */
+ /**
+ * Begin monitoring data connectivity.
+ *
+ * This is the first method called when this interface is used.
+ *
+ * @param context is the current Android context
+ * @param target is the Hander to which to return the events.
+ */
+ public void startMonitoring(Context context, Handler target);
+
+ /**
* Fetch NetworkInfo for the network
*/
public NetworkInfo getNetworkInfo();
@@ -56,43 +102,6 @@
public String getTcpBufferSizesPropName();
/**
- * Check if private DNS route is set for the network
- */
- public boolean isPrivateDnsRouteSet();
-
- /**
- * Set a flag indicating private DNS route is set
- */
- public void privateDnsRouteSet(boolean enabled);
-
- /**
- * Fetch default gateway address for the network
- */
- public int getDefaultGatewayAddr();
-
- /**
- * Check if default route is set
- */
- public boolean isDefaultRouteSet();
-
- /**
- * Set a flag indicating default route is set for the network
- */
- public void defaultRouteSet(boolean enabled);
-
- /**
- * Indicate tear down requested from connectivity
- */
- public void setTeardownRequested(boolean isRequested);
-
- /**
- * Check if tear down was requested
- */
- public boolean isTeardownRequested();
-
- public void startMonitoring();
-
- /**
* Disable connectivity to a network
* @return {@code true} if a teardown occurred, {@code false} if the
* teardown did not occur.
@@ -119,6 +128,11 @@
public boolean isAvailable();
/**
+ * Fetch default gateway address for the network
+ */
+ public int getDefaultGatewayAddr();
+
+ /**
* Tells the underlying networking system that the caller wants to
* begin using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
@@ -146,4 +160,41 @@
*/
public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid);
+ /**
+ * -------------------------------------------------------------
+ * Storage API used by ConnectivityService for saving
+ * Network specific information.
+ * -------------------------------------------------------------
+ */
+
+ /**
+ * Check if private DNS route is set for the network
+ */
+ public boolean isPrivateDnsRouteSet();
+
+ /**
+ * Set a flag indicating private DNS route is set
+ */
+ public void privateDnsRouteSet(boolean enabled);
+
+ /**
+ * Check if default route is set
+ */
+ public boolean isDefaultRouteSet();
+
+ /**
+ * Set a flag indicating default route is set for the network
+ */
+ public void defaultRouteSet(boolean enabled);
+
+ /**
+ * Check if tear down was requested
+ */
+ public boolean isTeardownRequested();
+
+ /**
+ * Indicate tear down requested from connectivity
+ */
+ public void setTeardownRequested(boolean isRequested);
+
}
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 117e507..ffc2862 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -90,6 +90,7 @@
private String mKey;
private Intent mIntent;
private String mFragment;
+ private Bundle mExtras;
private boolean mEnabled = true;
private boolean mSelectable = true;
private boolean mRequiresKey;
@@ -339,6 +340,26 @@
}
/**
+ * Return the extras Bundle object associated with this preference, creating
+ * a new Bundle if there currently isn't one. You can use this to get and
+ * set individual extra key/value pairs.
+ */
+ public Bundle getExtras() {
+ if (mExtras == null) {
+ mExtras = new Bundle();
+ }
+ return mExtras;
+ }
+
+ /**
+ * Return the extras Bundle object associated with this preference,
+ * returning null if there is not currently one.
+ */
+ public Bundle peekExtras() {
+ return mExtras;
+ }
+
+ /**
* Sets the layout resource that is inflated as the {@link View} to be shown
* for this Preference. In most cases, the default layout is sufficient for
* custom Preference objects and only the widget layout needs to be changed.
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 32bf170..6b00690 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -313,7 +313,7 @@
setListAdapter(mAdapter);
if (!mSinglePane) {
mPrefsContainer.setVisibility(View.VISIBLE);
- if (initialFragment != null) {
+ if (initialFragment == null) {
Header h = onGetInitialHeader();
initialFragment = h.fragment;
initialArguments = h.fragmentArguments;
@@ -464,12 +464,14 @@
}
String nodeName = parser.getName();
- if (!"PreferenceHeaders".equals(nodeName)) {
+ if (!"preference-headers".equals(nodeName)) {
throw new RuntimeException(
- "XML document must start with <PreferenceHeaders> tag; found"
+ "XML document must start with <preference-headers> tag; found"
+ nodeName + " at " + parser.getPositionDescription());
}
+ Bundle curBundle = null;
+
int outerDepth = parser.getDepth();
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -478,7 +480,7 @@
}
nodeName = parser.getName();
- if ("Header".equals(nodeName)) {
+ if ("header".equals(nodeName)) {
Header header = new Header();
TypedArray sa = getResources().obtainAttributes(attrs,
@@ -493,9 +495,16 @@
com.android.internal.R.styleable.PreferenceHeader_fragment);
sa.recycle();
- target.add(header);
+ if (curBundle == null) {
+ curBundle = new Bundle();
+ }
+ getResources().parseBundleExtras(parser, curBundle);
+ if (curBundle.size() > 0) {
+ header.fragmentArguments = curBundle;
+ curBundle = null;
+ }
- XmlUtils.skipCurrentTag(parser);
+ target.add(header);
} else {
XmlUtils.skipCurrentTag(parser);
}
@@ -631,16 +640,17 @@
* @param args Optional arguments to supply to the fragment.
*/
public void switchToHeader(String fragmentName, Bundle args) {
- popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
+ getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
Fragment f = Fragment.instantiate(this, fragmentName, args);
- openFragmentTransaction().replace(com.android.internal.R.id.prefs, f).commit();
+ getFragmentManager().openTransaction().replace(
+ com.android.internal.R.id.prefs, f).commit();
}
@Override
public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
- Fragment f = Fragment.instantiate(this, pref.getFragment());
- openFragmentTransaction().replace(com.android.internal.R.id.prefs, f)
+ Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
+ getFragmentManager().openTransaction().replace(com.android.internal.R.id.prefs, f)
.addToBackStack(BACK_STACK_PREFS).commit();
return true;
}
diff --git a/core/java/android/preference/PreferenceInflater.java b/core/java/android/preference/PreferenceInflater.java
index 779e746..c21aa18 100644
--- a/core/java/android/preference/PreferenceInflater.java
+++ b/core/java/android/preference/PreferenceInflater.java
@@ -16,6 +16,8 @@
package android.preference;
+import com.android.internal.util.XmlUtils;
+
import java.io.IOException;
import java.util.Map;
@@ -39,6 +41,7 @@
class PreferenceInflater extends GenericInflater<Preference, PreferenceGroup> {
private static final String TAG = "PreferenceInflater";
private static final String INTENT_TAG_NAME = "intent";
+ private static final String EXTRA_TAG_NAME = "extra";
private PreferenceManager mPreferenceManager;
@@ -73,8 +76,10 @@
try {
intent = Intent.parseIntent(getContext().getResources(), parser, attrs);
} catch (IOException e) {
- Log.w(TAG, "Could not parse Intent.");
- Log.w(TAG, e);
+ XmlPullParserException ex = new XmlPullParserException(
+ "Error parsing preference");
+ ex.initCause(e);
+ throw ex;
}
if (intent != null) {
@@ -82,6 +87,18 @@
}
return true;
+ } else if (tag.equals(EXTRA_TAG_NAME)) {
+ getContext().getResources().parseBundleExtra(EXTRA_TAG_NAME, attrs,
+ parentPreference.getExtras());
+ try {
+ XmlUtils.skipCurrentTag(parser);
+ } catch (IOException e) {
+ XmlPullParserException ex = new XmlPullParserException(
+ "Error parsing preference");
+ ex.initCause(e);
+ throw ex;
+ }
+ return true;
}
return false;
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/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..30a7318 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/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/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/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 315a2a3..94b60a1 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -1409,7 +1409,9 @@
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->egl.eglGetProcAddress) {
found = true;
- cnx->hooks[i]->ext.extensions[slot] =
+ // Extensions are independent of the bound context
+ cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
+ cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
cnx->egl.eglGetProcAddress(procname);
}
}
@@ -1421,7 +1423,6 @@
}
pthread_mutex_unlock(&gInitDriverMutex);
-
return addr;
}
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/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index ae4e168..859353a 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -313,21 +313,21 @@
switch (mNetAttributes[netType].mRadio) {
case ConnectivityManager.TYPE_WIFI:
if (DBG) Slog.v(TAG, "Starting Wifi Service.");
- WifiStateTracker wst = new WifiStateTracker(context, mHandler);
+ WifiStateTracker wst = new WifiStateTracker();
WifiService wifiService = new WifiService(context);
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
wifiService.checkAndStartWifi();
mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
- wst.startMonitoring();
+ wst.startMonitoring(context, mHandler);
//TODO: as part of WWS refactor, create only when needed
mWifiWatchdogService = new WifiWatchdogService(context);
break;
case ConnectivityManager.TYPE_MOBILE:
- mNetTrackers[netType] = new MobileDataStateTracker(context, mHandler,
- netType, mNetAttributes[netType].mName);
- mNetTrackers[netType].startMonitoring();
+ mNetTrackers[netType] = new MobileDataStateTracker(netType,
+ mNetAttributes[netType].mName);
+ mNetTrackers[netType].startMonitoring(context, mHandler);
if (noMobileData) {
if (DBG) Slog.d(TAG, "tearing down Mobile networks due to setting");
mNetTrackers[netType].teardown();
@@ -1205,18 +1205,6 @@
sendConnectedBroadcast(info);
}
- private void handleNotificationChange(boolean visible, int id,
- Notification notification) {
- NotificationManager notificationManager = (NotificationManager) mContext
- .getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (visible) {
- notificationManager.notify(id, notification);
- } else {
- notificationManager.cancel(id);
- }
- }
-
/**
* After a change in the connectivity state of a network. We're mainly
* concerned with making sure that the list of DNS servers is set up
@@ -1608,25 +1596,12 @@
handleConnect(info);
}
break;
-
- case NetworkStateTracker.EVENT_NOTIFICATION_CHANGED:
- handleNotificationChange(msg.arg1 == 1, msg.arg2,
- (Notification) msg.obj);
- break;
-
case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
// TODO - make this handle ip/proxy/gateway/dns changes
info = (NetworkInfo) msg.obj;
type = info.getType();
handleDnsConfigurationChange(type);
break;
- case NetworkStateTracker.EVENT_ROAMING_CHANGED:
- // fill me in
- break;
-
- case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
- // fill me in
- break;
case NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK:
FeatureUser u = (FeatureUser)msg.obj;
u.expire();
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 164142e..c61baad 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1220,7 +1220,6 @@
if (mCurClient == null || client == null
|| mCurClient.client.asBinder() != client.asBinder()) {
Slog.w(TAG, "Ignoring showInputMethodDialogFromClient of: " + client);
- return;
}
mHandler.sendEmptyMessage(MSG_SHOW_IM_PICKER);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 3ab6553..064d47f 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1387,9 +1387,7 @@
}
if (mNotification == null) {
- // Cache the Notification mainly so we can remove the
- // EVENT_NOTIFICATION_CHANGED message with this Notification from
- // the queue later
+ // Cache the Notification object.
mNotification = new Notification();
mNotification.when = 0;
mNotification.icon = ICON_NETWORKS_AVAILABLE;
@@ -1408,30 +1406,10 @@
mNotificationRepeatTime = System.currentTimeMillis() + NOTIFICATION_REPEAT_DELAY_MS;
notificationManager.notify(ICON_NETWORKS_AVAILABLE, mNotification);
- /*
- * TODO: Clean up connectivity service & remove this
- */
- /* message = mCsHandler.obtainMessage(EVENT_NOTIFICATION_CHANGED, 1,
- ICON_NETWORKS_AVAILABLE, mNotification); */
-
-
} else {
-
notificationManager.cancel(ICON_NETWORKS_AVAILABLE);
- /*
- * TODO: Clean up connectivity service & remove this
- */
- /*
- // Remove any pending messages to show the notification
- mCsHandler.removeMessages(EVENT_NOTIFICATION_CHANGED, mNotification);
-
- message = mCsHandler.obtainMessage(EVENT_NOTIFICATION_CHANGED, 0,
- ICON_NETWORKS_AVAILABLE);
- */
}
- //mCsHandler.sendMessageDelayed(message, delay);
-
mNotificationShown = visible;
}
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/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
index 86c86bb..a45cad1 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -111,7 +111,7 @@
}
/**
- * Retrieves the compelete voice mail number.
+ * Retrieves the complete voice mail number.
*
* @hide
*/
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..88aa78e 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/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++;
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 452549b..cee8546 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -166,7 +166,7 @@
if (argCount > 1 && nonpositional) {
SourcePos(String8(fileName), inXml->getLineNumber()).error(
"Multiple substitutions specified in non-positional format; "
- "did you mean to add the formatted=\"true\" attribute?\n");
+ "did you mean to add the formatted=\"false\" attribute?\n");
return NOT_ENOUGH_DATA;
}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 8e1b236..a5f62c1 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -56,10 +56,7 @@
private BroadcastReceiver mWifiStateReceiver;
private WifiManager mWifiManager;
- public WifiStateTracker(Context context, Handler target) {
- mCsHandler = target;
- mContext = context;
-
+ public WifiStateTracker() {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
mNetworkProperties = new NetworkProperties();
@@ -80,7 +77,10 @@
/**
* Begin monitoring wifi connectivity
*/
- public void startMonitoring() {
+ public void startMonitoring(Context context, Handler target) {
+ mCsHandler = target;
+ mContext = context;
+
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);