Merge "Rename action to ACTION_INPUT_METHOD_SUBTYPE_SETTINGS" into honeycomb
diff --git a/Android.mk b/Android.mk
index 5d989d1..7728b02 100644
--- a/Android.mk
+++ b/Android.mk
@@ -384,10 +384,10 @@
-hdf android.hasSamples 1 \
-samplecode $(sample_dir)/AccessibilityService \
resources/samples/AccessibilityService "Accessibility Service" \
- -samplecode $(sample_dir)/ApiDemos \
- resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/AccelerometerPlay \
resources/samples/AccelerometerPlay "Accelerometer Play" \
+ -samplecode $(sample_dir)/ApiDemos \
+ resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/BackupRestore \
resources/samples/BackupRestore "Backup and Restore" \
-samplecode $(sample_dir)/BluetoothChat \
@@ -396,16 +396,20 @@
resources/samples/BusinessCard "Business Card" \
-samplecode $(sample_dir)/ContactManager \
resources/samples/ContactManager "Contact Manager" \
- -samplecode $(sample_dir)/CubeLiveWallpaper \
- resources/samples/CubeLiveWallpaper "Live Wallpaper" \
+ -samplecode $(sample_dir)/CubeLiveWallpaper \
+ resources/samples/CubeLiveWallpaper "Cube Live Wallpaper" \
-samplecode $(sample_dir)/Home \
resources/samples/Home "Home" \
+ -samplecode $(sample_dir)/Honeycomb-Gallery \
+ resources/samples/Honeycomb-Gallery "Honeycomb Gallery" \
-samplecode $(sample_dir)/JetBoy \
resources/samples/JetBoy "JetBoy" \
-samplecode $(sample_dir)/LunarLander \
resources/samples/LunarLander "Lunar Lander" \
-samplecode $(sample_dir)/MultiResolution \
resources/samples/MultiResolution "Multiple Resolutions" \
+ -samplecode $(sample_dir)/NFCDemo \
+ resources/samples/NFCDemo "NFC Demo" \
-samplecode $(sample_dir)/NotePad \
resources/samples/NotePad "Note Pad" \
-samplecode $(sample_dir)/SampleSyncAdapter \
diff --git a/api/11.xml b/api/11.xml
index 4653ab5..d668883 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -240630,6 +240630,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240885,17 +240896,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
diff --git a/api/current.xml b/api/current.xml
index 4e8acb6..a63a867 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -39712,6 +39712,16 @@
visibility="public"
>
</field>
+<field name="previewImage"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="provider"
type="android.content.ComponentName"
transient="false"
@@ -240641,6 +240651,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240896,17 +240917,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
@@ -260337,7 +260347,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/animation/package.html b/core/java/android/animation/package.html
index b66669b..ff43260 100644
--- a/core/java/android/animation/package.html
+++ b/core/java/android/animation/package.html
@@ -1,6 +1,21 @@
<html>
<body>
-Provides classes for animating values over time, and setting those values on target
-objects.
+<p>
+These classes provide functionality for the property animation system, which allows you
+to animate object properties of any type. <code>int</code>, <code>float</code>, and hexadecimal
+color values are supported by default. You can animate any other type by telling the system how
+to calculate the values for that given type with a custom {@link android.animation.TypeEvaluator}.
+</p>
+
+<p>
+You can set many different types of interpolators (contained in {@link android.view.animation}),
+specify {@link android.animation.Keyframe keyframes}, or group animations to play sequentially
+or simultaneously (with {@link android.animation.AnimatorSet}) to further control your animation
+behaviors.</p>
+
+<p>
+For a guide on how to use the property animation system, see the
+<a href="{@docRoot}guide/topics/media/index.html">Animation</a> developer guide.
+</p>
</body>
</html>
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index a3db01d..fe33782 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -121,8 +121,6 @@
*
* <p>This field corresponds to the <code>android:previewImage</code> attribute in
* the <code><receiver></code> element in the AndroidManifest.xml file.
- *
- * @hide Pending API approval
*/
public int previewImage;
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f480554..d82f051 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -635,9 +635,13 @@
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
- throw new UnsupportedOperationException();
+ boolean hasModifier = setupModifiers(paint);
+ nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
+
@Override
public void drawColor(int color) {
drawColor(color, PorterDuff.Mode.SRC_OVER);
@@ -773,9 +777,15 @@
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
- // TODO: Implement
+ boolean hasModifier = setupModifiers(paint);
+ nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
+ rx, ry, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawRoundRect(int renderer, float left, float top,
+ float right, float bottom, float rx, float y, int paint);
+
@Override
public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index c27082f..4c1279ff 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -981,11 +981,21 @@
// items from the Adapter.
}
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} in order to advance the current view when
+ * it is being used within an app widget.
+ */
public void advance() {
showNext();
}
- public void willBeAdvancedByHost() {
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewAnimator} by calling
+ * {@link AdapterViewAnimator#advance()} at some point in the future. This allows subclasses to
+ * perform any required setup, for example, to stop automatically advancing their children.
+ */
+ public void fyiWillBeAdvancedByHostKThx() {
}
@Override
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 7721688..273c258 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -258,8 +258,14 @@
}
};
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewFlipper} by calling
+ * {@link AdapterViewFlipper#advance()} at some point in the future. This allows
+ * {@link AdapterViewFlipper} to prepare by no longer Advancing its children.
+ */
@Override
- public void willBeAdvancedByHost() {
+ public void fyiWillBeAdvancedByHostKThx() {
mAdvancedByHost = true;
updateRunning(false);
}
diff --git a/core/java/android/widget/Advanceable.java b/core/java/android/widget/Advanceable.java
index bb162de..dc13ebb7 100644
--- a/core/java/android/widget/Advanceable.java
+++ b/core/java/android/widget/Advanceable.java
@@ -34,5 +34,5 @@
* Called by the AppWidgetHost once before it begins to call advance(), allowing the
* collection to do any required setup.
*/
- public void willBeAdvancedByHost();
+ public void fyiWillBeAdvancedByHostKThx();
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 79d6a81..439e0ca 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -28,7 +28,6 @@
import android.os.Build;
import android.os.IBinder;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -1087,7 +1086,14 @@
p.width = Math.min(p.width, displayFrameWidth);
}
- p.y = Math.max(p.y, displayFrame.top);
+ if (onTop) {
+ int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
+ if (popupTop < 0) {
+ p.y += popupTop;
+ }
+ } else {
+ p.y = Math.max(p.y, displayFrame.top);
+ }
}
p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 16126aa..e5a3de2 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -42,7 +42,7 @@
/**
* An interface for an adapter between a remote collection view (ListView, GridView, etc) and
* the underlying data for that view. The implementor is responsible for making a RemoteView
- * for each item in the data set.
+ * for each item in the data set. This interface is a thin wrapper around {@link Adapter}.
*
* @see android.widget.Adapter
* @see android.appwidget.AppWidgetManager
@@ -53,24 +53,72 @@
* multiple RemoteViewAdapters depending on the intent passed.
*/
public void onCreate();
+
/**
* Called when notifyDataSetChanged() is triggered on the remote adapter. This allows a
* RemoteViewsFactory to respond to data changes by updating any internal references.
*
+ * Note: expensive tasks can be safely performed synchronously within this method. In the
+ * interim, the old data will be displayed within the widget.
+ *
* @see android.appwidget.AppWidgetManager#notifyAppWidgetViewDataChanged(int[], int)
*/
public void onDataSetChanged();
+
/**
* Called when the last RemoteViewsAdapter that is associated with this factory is
* unbound.
*/
public void onDestroy();
+ /**
+ * See {@link Adapter#getCount()}
+ *
+ * @return Count of items.
+ */
public int getCount();
+
+ /**
+ * See {@link Adapter#getView(int, android.view.View, android.view.ViewGroup)}.
+ *
+ * Note: expensive tasks can be safely performed synchronously within this method, and a
+ * loading view will be displayed in the interim. See {@link #getLoadingView()}.
+ *
+ * @param position The position of the item within the Factory's data set of the item whose
+ * view we want.
+ * @return A RemoteViews object corresponding to the data at the specified position.
+ */
public RemoteViews getViewAt(int position);
+
+ /**
+ * This allows for the use of a custom loading view which appears between the time that
+ * {@link #getViewAt(int)} is called and returns. If null is returned, a default loading
+ * view will be used.
+ *
+ * @return The RemoteViews representing the desired loading view.
+ */
public RemoteViews getLoadingView();
+
+ /**
+ * See {@link Adapter#getViewTypeCount()}.
+ *
+ * @return The number of types of Views that will be returned by this factory.
+ */
public int getViewTypeCount();
+
+ /**
+ * See {@link Adapter#getItemId(int)}.
+ *
+ * @param position The position of the item within the data set whose row id we want.
+ * @return The id of the item at the specified position.
+ */
public long getItemId(int position);
+
+ /**
+ * See {@link Adapter#hasStableIds()}.
+ *
+ * @return True if the same id always refers to the same object.
+ */
public boolean hasStableIds();
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index e38a69f..0baddcb 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -23,14 +23,13 @@
import android.content.DialogInterface.OnClickListener;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
/**
@@ -70,8 +69,6 @@
private int mGravity;
- private LayoutObserver mLayoutObserver;
-
/**
* Construct a new spinner with the given context's theme.
*
@@ -172,7 +169,6 @@
com.android.internal.R.styleable.Spinner_dropDownHorizontalOffset, 0));
mPopup = popup;
- mLayoutObserver = new LayoutObserver();
break;
}
}
@@ -425,11 +421,6 @@
handled = true;
if (!mPopup.isShowing()) {
- if (mLayoutObserver != null) {
- final ViewTreeObserver vto = getViewTreeObserver();
- vto.addOnGlobalLayoutListener(mLayoutObserver);
- vto.addOnScrollChangedListener(mLayoutObserver);
- }
mPopup.show();
}
}
@@ -677,7 +668,6 @@
super.show();
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
setSelection(Spinner.this.getSelectedItemPosition());
- setOnDismissListener(mLayoutObserver);
}
@Override
@@ -728,28 +718,4 @@
ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
-
- private class LayoutObserver implements ViewTreeObserver.OnGlobalLayoutListener,
- ViewTreeObserver.OnScrollChangedListener, PopupWindow.OnDismissListener {
- @Override
- public void onScrollChanged() {
- if (mPopup != null && mPopup.isShowing()) {
- mPopup.show();
- }
- }
-
- @Override
- public void onGlobalLayout() {
- if (mPopup != null && mPopup.isShowing()) {
- mPopup.show();
- }
- }
-
- @Override
- public void onDismiss() {
- ViewTreeObserver vto = getViewTreeObserver();
- vto.removeGlobalOnLayoutListener(mLayoutObserver);
- vto.removeOnScrollChangedListener(mLayoutObserver);
- }
- }
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 2c10077..22edf6d 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -347,6 +347,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showNext() {
@@ -362,6 +365,9 @@
super.showNext();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showPrevious() {
@@ -474,6 +480,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -561,6 +570,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
@@ -939,6 +951,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void onRemoteAdapterConnected() {
super.onRemoteAdapterConnected();
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index ac491ea..bfd2b58e 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -299,6 +299,17 @@
renderer->drawRect(left, top, right, bottom, paint);
}
+static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
+ jfloat rx, jfloat ry, SkPaint* paint) {
+ renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
+}
+
+static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
+ renderer->drawCircle(x, y, radius, paint);
+}
+
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
SkRegion::Iterator it(*region);
@@ -570,6 +581,8 @@
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
+ { "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect },
+ { "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-hdpi/vpn_connected.png
similarity index 100%
rename from packages/VpnServices/res/drawable/vpn_connected.png
rename to core/res/res/drawable-hdpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-hdpi/vpn_disconnected.png
similarity index 100%
rename from packages/VpnServices/res/drawable/vpn_disconnected.png
rename to core/res/res/drawable-hdpi/vpn_disconnected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-ldpi/vpn_connected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_connected.png
copy to core/res/res/drawable-ldpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-ldpi/vpn_disconnected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_disconnected.png
copy to core/res/res/drawable-ldpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
new file mode 100644
index 0000000..137923b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
new file mode 100644
index 0000000..62b1deb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..ab30a77
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..9274bc7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..e46155e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-mdpi/vpn_connected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_connected.png
copy to core/res/res/drawable-mdpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-mdpi/vpn_disconnected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_disconnected.png
copy to core/res/res/drawable-mdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 0000000..0fbdbfa
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 0000000..ae97453
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 0000000..4127d1e
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 0000000..525ab8a
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 0000000..eb05820
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 0000000..416b2c7
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml
new file mode 100644
index 0000000..92ceb79
--- /dev/null
+++ b/core/res/res/drawable/lockscreen_password_field_dark.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" />
+ <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" />
+ <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" />
+ <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+</selector>
+
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
index 4bc7292..5ea43dc 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
@@ -20,76 +20,88 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal"
- >
+ android:orientation="vertical">
- <!-- left side: status -->
- <RelativeLayout
- android:layout_height="match_parent"
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
android:layout_weight="1"
- android:layout_width="0dip">
+ />
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!-- left side: status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="102dip"
- android:layout_marginTop="320dip"
- android:layout_alignParentTop="true"
+ android:paddingTop="50dip"
+ android:layout_centerVertical="true"
android:layout_alignParentLeft="true"/>
+ <!-- right side: password -->
+ <LinearLayout
+ android:layout_width="330dip"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:layout_marginRight="155dip">
+
+ <!-- Password entry field -->
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:gravity="center"
+ android:textSize="24sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/lockscreen_password_field_dark"
+ android:textColor="#ffffffff"
+ />
+
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="330dip"
+ android:layout_height="330dip"
+ android:background="#00000000"
+ android:layout_marginTop="5dip"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+
</RelativeLayout>
- <!-- right side: password -->
- <LinearLayout
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:orientation="vertical"
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
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"
- />
+ <!-- Alphanumeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
+ />
- <!-- 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 NOT CURRENTLY USED -->
+ <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"
+ />
- <!-- 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
index e63fb9b..8a059f5 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -56,7 +56,7 @@
android:layout_marginTop="120dip"
android:layout_marginBottom="5dip"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/password_field_default"
+ android:background="@drawable/lockscreen_password_field_dark"
android:textColor="#ffffffff"
/>
@@ -69,7 +69,7 @@
/>
<!-- Alphanumeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
- android:layout_width="450dip"
+ android:layout_width="match_parent"
android:layout_height="230dip"
android:background="#00000000"
android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
diff --git a/core/res/res/values-xlarge-land/dimens.xml b/core/res/res/values-xlarge-land/dimens.xml
index 6a2b93f..0b43a42 100644
--- a/core/res/res/values-xlarge-land/dimens.xml
+++ b/core/res/res/values-xlarge-land/dimens.xml
@@ -17,6 +17,9 @@
*/
-->
<resources>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">100dip</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
<!-- Minimum width of the search view text entry area. -->
<dimen name="search_view_text_min_width">256dip</dimen>
</resources>
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index 5b0ea30..63d3619 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -24,15 +24,17 @@
<dimen name="status_bar_icon_size">32dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
-
+
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<!-- Margin for permanent screen decorations at the bottom. -->
<dimen name="screen_margin_bottom">48dip</dimen>
-
+
<!-- Default height of a key in the password keyboard for alpha -->
- <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
+ <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
<!-- Default height of a key in the password keyboard for numeric -->
- <dimen name="password_keyboard_key_height_numeric">0.47in</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <dimen name="password_keyboard_height">48.0mm</dimen>
<!-- The width that is used when creating thumbnails of applications. -->
<dimen name="thumbnail_width">230dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9a1b42d..46e45db 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2677,4 +2677,11 @@
<string name="sync_undo_deletes">Undo the deletes.</string>
<!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
<string name="sync_do_nothing">Do nothing for now.</string>
+
+ <!-- Title of the VPN service notification: VPN connected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_connected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN connected</string>
+ <!-- Title of the VPN service notification: VPN disconnected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_disconnected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN disconnected</string>
+ <!-- Message of the VPN service notification: Hint to reconnect VPN [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
</resources>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
index 0a35040..fd1d5f1 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2011, 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.
@@ -19,26 +19,15 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <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>
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
<Key android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:keyLabel="w"/>
<Key android:keyLabel="e"/>
@@ -48,12 +37,21 @@
<Key android:keyLabel="u"/>
<Key android:keyLabel="i"/>
<Key android:keyLabel="o"/>
- <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="p"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:keyLabel="a" android:horizontalGap="5%p"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="a"/>
<Key android:keyLabel="s"/>
<Key android:keyLabel="d"/>
<Key android:keyLabel="f"/>
@@ -61,14 +59,22 @@
<Key android:keyLabel="h"/>
<Key android:keyLabel="j"/>
<Key android:keyLabel="k"/>
- <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="l"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
- android:keyWidth="15%p" android:isModifier="true"
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
android:iconPreview="@drawable/sym_keyboard_feedback_shift"
- android:isSticky="true" android:keyEdgeFlags="left"/>
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
<Key android:keyLabel="z"/>
<Key android:keyLabel="x"/>
<Key android:keyLabel="c"/>
@@ -76,26 +82,26 @@
<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"/>
+ <Key android:keyLabel="," />
+ <Key android:keyLabel="." />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
</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"
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="/" android:horizontalGap="24.126%p"/>
+ <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"/>
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="'" />
+ <Key android:keyLabel="-" />
</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
index 9e9db81..671d87f 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2011, 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.
@@ -19,82 +19,89 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <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"
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <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"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true"/>
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</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"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="A"/>
+ <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"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
android:iconPreview="@drawable/sym_keyboard_feedback_ok"
- android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%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:keyLabel="!" />
+ <Key android:keyLabel="\?" />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="\@" android:horizontalGap="24.126%p"/>
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel=""" />
+ <Key android:keyLabel="_" />
</Row>
</Keyboard>
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols.xml b/core/res/res/xml-xlarge/password_kbd_symbols.xml
new file mode 100755
index 0000000..5ae5577
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
+
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <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"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ 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=")"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ 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="\?" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:keyLabel="\@" android:horizontalGap="16.084%p"/>
+ <Key android:keyLabel="/" />
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="\'" />
+ <Key android:keyLabel="-" />
+ </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
new file mode 100755
index 0000000..26ade76
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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:keyWidth="8.272%p"
+ android:rowEdgeFlags="top">
+ <Key android:keyLabel="Tab" android:codes="9"/>
+ <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="§" />
+ <Key android:keyLabel="Δ" />
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ 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="}" />
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ 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="¿" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <!-- This row is intentionally not marked as a bottom row -->
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="32" android:horizontalGap="32.168%p"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ </Row>
+</Keyboard>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 67f1fec..270d153 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -213,6 +213,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Animation</span>
+ </a><span class="new">new!</span></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 05f4023..6594568 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -17,8 +17,6 @@
<li><a href="#shape-drawable">Shape Drawable</a></li>
<!-- <li><a href="#state-list">StateListDrawable</a></li> -->
<li><a href="#nine-patch">Nine-patch</a></li>
- <li><a href="#tween-animation">Tween Animation</a></li>
- <li><a href="#frame-animation">Frame Animation</a></li>
</ol>
</div>
</div>
@@ -328,172 +326,4 @@
stretches to accommodate it.
</p>
-<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
-
-
-<h2 id="tween-animation">Tween Animation</h2>
-
-<p>A tween animation can perform a series of simple transformations (position, size, rotation, and transparency) on
-the contents of a View object. So, if you have a TextView object, you can move, rotate, grow, or shrink the text.
-If it has a background image, the background image will be transformed along with the text.
-The {@link android.view.animation animation package} provides all the classes used in a tween animation.</p>
-
-<p>A sequence of animation instructions defines the tween animation, defined by either XML or Android code.
-Like defining a layout, an XML file is recommended because it's more readable, reusable, and swappable
-than hard-coding the animation. In the example below, we use XML. (To learn more about defining an animation
-in your application code, instead of XML, refer to the
-{@link android.view.animation.AnimationSet} class and other {@link android.view.animation.Animation} subclasses.)</p>
-
-<p>The animation instructions define the transformations that you want to occur, when they will occur,
-and how long they should take to apply. Transformations can be sequential or simultaneous —
-for example, you can have the contents of a TextView move from left to right, and then
-rotate 180 degrees, or you can have the text move and rotate simultaneously. Each transformation
-takes a set of parameters specific for that transformation (starting size and ending size
-for size change, starting angle and ending angle for rotation, and so on), and
-also a set of common parameters (for instance, start time and duration). To make
-several transformations happen simultaneously, give them the same start time;
-to make them sequential, calculate the start time plus the duration of the preceding transformation.
-</p>
-
-<p>The animation XML file belongs in the <code>res/anim/</code> directory of your Android project.
-The file must have a single root element: this will be either a single <code><alpha></code>,
-<code><scale></code>, <code><translate></code>, <code><rotate></code>, interpolator element,
-or <code><set></code> element that holds groups of these elements (which may include another
-<code><set></code>). By default, all animation instructions are applied simultaneously.
-To make them occur sequentially, you must specify the <code>startOffset</code> attribute, as shown in the example below.
-</p>
-
-<p>The following XML from one of the ApiDemos is used to stretch,
-then simultaneously spin and rotate a View object.
-</p>
-<pre>
-<set android:shareInterpolator="false">
- <scale
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromXScale="1.0"
- android:toXScale="1.4"
- android:fromYScale="1.0"
- android:toYScale="0.6"
- android:pivotX="50%"
- android:pivotY="50%"
- android:fillAfter="false"
- android:duration="700" />
- <set android:interpolator="@android:anim/decelerate_interpolator">
- <scale
- android:fromXScale="1.4"
- android:toXScale="0.0"
- android:fromYScale="0.6"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400"
- android:fillBefore="false" />
- <rotate
- android:fromDegrees="0"
- android:toDegrees="-45"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400" />
- </set>
-</set>
-</pre>
-<p>Screen coordinates (not used in this example) are (0,0) at the upper left hand corner,
-and increase as you go down and to the right.</p>
-
-<p>Some values, such as pivotX, can be specified relative to the object itself or relative to the parent.
-Be sure to use the proper format for what you want ("50" for 50% relative to the parent, or "50%" for 50%
-relative to itself).</p>
-
-<p>You can determine how a transformation is applied over time by assigning an
-{@link android.view.animation.Interpolator}. Android includes
-several Interpolator subclasses that specify various speed curves: for instance,
-{@link android.view.animation.AccelerateInterpolator} tells
-a transformation to start slow and speed up. Each one has an attribute value that can be applied in the XML.</p>
-
-<p>With this XML saved as <code>hyperspace_jump.xml</code> in the <code>res/anim/</code> directory of the
-project, the following Java code will reference it and apply it to an {@link android.widget.ImageView} object
-from the layout.
-</p>
-<pre>
-ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
-Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
-spaceshipImage.startAnimation(hyperspaceJumpAnimation);
-</pre>
-
-<p>As an alternative to <code>startAnimation()</code>, you can define a starting time for the animation with
-<code>{@link android.view.animation.Animation#setStartTime(long) Animation.setStartTime()}</code>,
-then assign the animation to the View with
-<code>{@link android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}</code>.
-</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
-<p class="note"><strong>Note:</strong> Regardless of how your animation may move or resize, the bounds of the
-View that holds your animation will not automatically adjust to accommodate it. Even so, the animation will still
-be drawn beyond the bounds of its View and will not be clipped. However, clipping <em>will occur</em>
-if the animation exceeds the bounds of the parent View.</p>
-
-
-<h2 id="frame-animation">Frame Animation</h2>
-
-<p>This is a traditional animation in the sense that it is created with a sequence of different
-images, played in order, like a roll of film. The {@link android.graphics.drawable.AnimationDrawable}
-class is the basis for frame animations.</p>
-
-<p>While you can define the frames of an animation in your code, using the
-{@link android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a single XML
-file that lists the frames that compose the animation. Like the tween animation above, the XML file for this kind
-of animation belongs in the <code>res/drawable/</code> directory of your Android project. In this case,
-the instructions are the order and duration for each frame of the animation.</p>
-
-<p>The XML file consists of an <code><animation-list></code> element as the root node and a series
-of child <code><item></code> nodes that each define a frame: a drawable resource for the frame and the frame duration.
-Here's an example XML file for a frame-by-frame animation:</p>
-<pre>
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
-</animation-list>
-</pre>
-
-<p>This animation runs for just three frames. By setting the <code>android:oneshot</code> attribute of the
-list to <var>true</var>, it will cycle just once then stop and hold on the last frame. If it is set <var>false</var> then
-the animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory
-of the project, it can be added as the background image to a View and then called to play. Here's an example Activity,
-in which the animation is added to an {@link android.widget.ImageView} and then animated when the screen is touched:</p>
-<pre>
-AnimationDrawable rocketAnimation;
-
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
- rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
- rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
-}
-
-public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- rocketAnimation.start();
- return true;
- }
- return super.onTouchEvent(event);
-}
-</pre>
-<p>It's important to note that the <code>start()</code> method called on the AnimationDrawable cannot be
-called during the <code>onCreate()</code> method of your Activity, because the AnimationDrawable is not yet fully attached
-to the window. If you want to play the animation immediately, without
-requiring interaction, then you might want to call it from the
-<code>{@link android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in
-your Activity, which will get called when Android brings your window into focus.</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
+<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
\ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
new file mode 100644
index 0000000..c977d51
--- /dev/null
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -0,0 +1,839 @@
+page.title=Animation
+@jd:body
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li>
+ <a href="#property-animation">Property Animation</a>
+
+ <ol>
+ <li><a href="#value-animator">Animating with ValueAnimator</a></li>
+
+ <li><a href="#object-animator">Animating with ObjectAnimator</a></li>
+
+ <li><a href="#type-evaluator">Using the TypeEvaluator</a></li>
+
+ <li><a href="#interpolators">Using interpolators</a></li>
+
+ <li><a href="#keyframes">Specifying keyframes</a></li>
+
+ <li><a href="#choreography">Choreographing multiple animations with AnimatorSet</a></li>
+
+ <li><a href="#declaring-xml">Declaring animations in XML</a></li>
+ </ol>
+ </li>
+
+ <li>
+ <a href="#view-animation">View Animation</a>
+
+ <ol>
+ <li><a href="#tween-animation">Tween animation</a></li>
+
+ <li><a href="#frame-animation">Frame animation</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key classes</h2>
+
+ <ol>
+ <li><code><a href=
+ "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
+ </ol>
+
+ <h2>Related samples</h2>
+
+ <ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API Demos</a></li>
+ </ol>
+
+ </div>
+ </div>
+
+ <p>The Android system provides a flexible animation system that allows you to animate
+ almost anything, either programmatically or declaratively with XML. There are two
+ animation systems that you can choose from: <a href="property-animation">property
+ animation</a> and <a href="#view-animation">view animation</a>. You can use whichever
+ system that matches your needs, but use only one system for each object that you
+ are animating.</p>
+
+ <h2 id="property-animation">Property Animation</h2>
+
+ <p>Introduced in Android 3.0, the property animation system allows you to animate
+ object properties of any type. <code>int</code>, <code>float</code>,
+ and hexadecimal color values are supported by default. You can animate any other type by telling the
+ system how to calculate the values for that given type.</p>
+
+ <p>The property animation system allows you to define many aspects of an animation,
+ such as:</p>
+
+ <ul>
+ <li>Duration</li>
+
+ <li>Repeat amount and behavior</li>
+
+ <li>Type of time interpolation</li>
+
+ <li>Animator sets to play animations together, sequentially, or after specified
+ delays</li>
+
+ <li>Frame refresh delay</li>
+
+ </ul>
+
+ <p>Most of the property animation system's features can be found in
+ {@link android.animation android.animation}. Because the
+ <a href="#view-animation>view animation</a> system already
+ defines many interpolators in {@link android.view.animation android.view.animation},
+ you will use those to define your animation's interpolation in the property animation
+ system as well.
+ </p>
+
+ <p>The following items are the main components of the property animation system:</p>
+
+ <dl>
+ <dt><strong>Animators</strong></dt>
+
+ <dd>
+ The {@link android.animation.Animator} class provides the basic structure for
+ creating animations. You normally do not use this class directly as it only provides
+ minimal functionality that must be extended to fully support animating values.
+ The following subclasses extend {@link android.animation.Animator}, which you might find more useful:
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} is the main timing engine for
+ property animation and computes the values for the property to be animated.
+ {@link android.animation.ValueAnimator} only computes the animation values and is
+ not aware of the specific object and property that is being animated or what the
+ values might be used for. You must listen for updates to values calculated by the
+ {@link android.animation.ValueAnimator} and process the data with your own logic.
+ See the section about <a href="#value-animator">Animating with ValueAnimator</a>
+ for more information.</li>
+
+ <li>{@link android.animation.ObjectAnimator} is a subclass of {@link
+ android.animation.ValueAnimator} and allows you to set a target object and object
+ property to animate. This class is aware of the object and property to be
+ animated, and updates the property accordingly when it computes a new value for
+ the animation. See the section about <a href="#object-animator">
+ Animating with ObjectAnimator</a> for more information.</li>
+
+ <li>{@link android.animation.AnimatorSet} provides a mechanism to group
+ animations together so that they are rendered in relation to one another. You can
+ set animations to play together, sequentially, or after a specified delay.
+ See the section about <a href="#choreography">
+ Choreographing multiple animations with Animator Sets</a> for more information.</li>
+ </ul>
+ </dd>
+
+ <dt><strong>Evaluators</strong></dt>
+
+ <dd>
+ <p>If you are animating an object property that is <em>not</em> an <code>int</code>,
+ <code>float</code>, or color, implement the {@link android.animation.TypeEvaluator}
+ interface to specify how to compute the object property's animated values. You give
+ a {@link android.animation.TypeEvaluator} the timing data that is provided by an
+ {@link android.animation.Animator} class, the animation's start and end value, and
+ provide logic that computes the animated values of the property based on this data.</p>
+
+ <p>You can also specify a custom {@link android.animation.TypeEvaluator} for
+ <code>int</code>, <code>float</code>, and color values as well, if you want to
+ process those types differently than the default behavior.</p>
+
+ <p>See <a href="#type-evaluator">Using a TypeEvaluator</a> for more information on
+ how to write a custom evaluator.</p>
+ </dd>
+
+ <dt><strong>Interpolators</strong></dt>
+
+ <dd>
+ <p>A time interpolator defines how specific values in an animation are calculated
+ as a function of time. For example, you can specify animations to happen linearly
+ across the whole animation, meaning the animation moves evenly the entire time, or
+ you can specify animations to use non-linear time, for example, using acceleration
+ or deceleration at the beginning or end of the animation.</p>
+
+ <p>The Android system provides a set of common interpolators in
+ {@link android.view.animation android.view.animation}. If none of these suits your needs, you
+ can implement the {@link android.animation.TimeInterpolator} interface and create
+ your own. See <a href="#interpolators">Interpolators</a> for more information on
+ how to write a custom interpolator.</p>
+ </dd>
+ </dl>
+
+
+ <p>The <code>com.example.android.apis.animation</code> package in the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
+ API Demos</a> sample project also provides a good overview and many examples on how to
+ use the property animation system.</p>
+
+
+ <h3>How the property animation system calculates animated values</h3>
+
+ <p>When you call {@link android.animation.ValueAnimator#start start()} to begin an animation,
+ the {@link android.animation.ValueAnimator} calculates
+ an <em>elapsed fraction</em> between 0 and 1, based on the duration of the animation
+ and how much time has elapsed. The elapsed fraction represents the percentage of time
+ that the animation has completed, 0 meaning 0% and 1 meaning 100%. The Animator then
+ calls the {@link android.animation.TimeInterpolator} that is currently set,
+ to calculate an <em>eased fraction</em>,
+ which is a modified value of the elapsed fraction that takes into account the interpolator that
+ is set (time interpolation is often referred to as <em>easing</em>). The eased fraction
+ is the final value that is used to animate the property.</p>
+
+ <p>Once the eased fraction is calculated, {@link android.animation.ValueAnimator} calls
+ the appropriate {@link android.animation.TypeEvaluator} to calculate the final value of
+ the property that you are animating, based on the eased fraction, the starting value,
+ and ending value of the animation.</p>
+
+ <h3 id="value-animator">Animating with ValueAnimator</h3>
+
+ <p>The {@link android.animation.ValueAnimator} class lets you animate values of some
+ type for the duration of an animation by specifying a set of <code>int</code>,
+ <code>float</code>, or color values to animate over and the duration of the animation.
+ You obtain a {@link android.animation.ValueAnimator} by calling one of its factory
+ methods: {@link android.animation.ValueAnimator#ofInt ofInt()},
+ {@link android.animation.ValueAnimator#ofFloat ofFloat()},
+ or {@link android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between 0 and 1, for
+ a duration of 1000 ms, when the <code>start()</code> method runs.</p>
+
+ <p>You can also specify a custom type to animate by doing the following:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between <code>startPropertyValue</code> and
+ <code>endPropertyValue</code> using the logic supplied by <code>MyTypeEvaluator</code>
+ for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()}
+ method runs.</p>
+
+ <p>The previous code snippets, however, do not affect an object, because the {@link
+ android.animation.ValueAnimator} does not operate on objects or properties directly. To
+ use the results of a {@link android.animation.ValueAnimator}, you must define listeners
+ in the {@link android.animation.ValueAnimator} to appropriately handle important events
+ during the animation's lifespan, such as frame updates. You can implement the following
+ interfaces to create listeners for {@link android.animation.ValueAnimator}:</p>
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener}
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart
+ onAnimationStart()} - Called when the animation starts</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd
+ onAnimationEnd()} - Called when the animation ends.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
+ onAnimationRepeat()} - Called when the animation repeats itself.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
+ onAnimationCancel()} - Called when the animation is canceled.</li>
+ </ul>
+ </li>
+
+ <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
+
+ <ul>
+ <li>
+ <p>{@link
+ android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} - called on every frame of the animation.
+ Listen to this event to use the calculated values generated by
+ {@link android.animation.ValueAnimator} during an animation. To use the value,
+ query the {@link android.animation.ValueAnimator} object passed into the event
+ to get the current animated value with the
+ {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method.</p>
+
+ <p>If you are animating your own custom object (not View objects), this
+ callback must also call the {@link android.view.View#invalidate invalidate()}
+ method to force a redraw of the screen. If you are animating View objects,
+ {@link android.view.View#invalidate invalidate()} is automatically called when
+ a property of the View is changed.</p>
+ </li>
+ </ul>
+
+ <p>You can extend the {@link android.animation.AnimatorListenerAdapter} class
+ instead of implementing the {@link android.animation.Animator.AnimatorListener}
+ interface, if you do not want to implement all of the methods of the {@link
+ android.animation.Animator.AnimatorListener} interface. The {@link
+ android.animation.AnimatorListenerAdapter} class provides empty implementations of the
+ methods that you can choose to override.</p>
+ </li>
+ </ul>
+
+ <p>For example, the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in the API demos creates an {@link
+ android.animation.AnimatorListenerAdapter} for just the {@link
+ android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
+ callback:</p>
+ <pre>ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+fadeAnim.addListener(new AnimatorListenerAdapter() {
+public void onAnimationEnd(Animator animation) {
+ balls.remove(((ObjectAnimator)animation).getTarget());
+}
+
+</pre>
+
+ <h3 id="object-animator">Animating with ObjectAnimator</h3>
+
+ <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
+ android.animation.ValueAnimator} (discussed in the previous section)
+ and combines the timing engine and value computation
+ of {@link android.animation.ValueAnimator} with the ability to animate a named property
+ of a target object. This makes animating any object much easier, as you no longer need
+ to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, because
+ the animated property updates automatically.</p>
+
+ <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
+ android.animation.ValueAnimator}, but you also specify the object and that object's
+ property (as a String) that you want to animate:</p>
+ <pre>
+ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+</pre>
+
+ <p>To have the {@link android.animation.ObjectAnimator} update properties correctly,
+ you must do the following:</p>
+
+ <ul>
+ <li>The object property that you are animating must have a setter function in the
+ form of <code>set<propertyName>()</code>. Because the {@link
+ android.animation.ObjectAnimator} automatically updates the property during
+ animation, it must be able to access the property with this setter method. For
+ example, if the property name is <code>foo</code>, you need to have a
+ <code>setFoo()</code> method. If this setter method does not exist, you have three
+ options:
+
+ <ul>
+ <li>Add the setter method to the class if you have the rights to do so.</li>
+
+ <li>Use a wrapper class that you have rights to change and have that wrapper
+ receive the value with a valid setter method and forward it to the original
+ object.</li>
+
+ <li>Use {@link android.animation.ValueAnimator} instead.</li>
+ </ul>
+ </li>
+
+ <li>If you specify only one value for the <code>values...</code> parameter,
+ in one of the {@link android.animation.ObjectAnimator} factory methods, it is assumed to be
+ the ending value of the animation. Therefore, the object property that you are
+ animating must have a getter function that is used to obtain the starting value of
+ the animation. The getter function must be in the form of
+ <code>get<propertyName>()</code>. For example, if the property name is
+ <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
+
+ <li>The getter (if needed) and setter methods of the property that you are animating must
+ return the same type as the starting and ending values that you specify to {@link
+ android.animation.ObjectAnimator}. For example, you must have
+ <code>targetObject.setPropName(float)</code> and
+ <code>targetObject.getPropName(float)</code> if you construct the following {@link
+ android.animation.ObjectAnimator}:
+ <pre>ObjectAnimator.ofFloat(targetObject, "propName", 1f)</pre>
+ </li>
+ </ul>
+
+ <h3 id="type-evaluator">Using the TypeEvaluator</h3>
+
+ <p>If you want to animate a type that is unknown to the Android system,
+ you can create your own evaluator by implementing the {@link
+ android.animation.TypeEvaluator} interface. The types that are known by the Android
+ system are <code>int</code>, <code>float</code>, or a color, which are supported by the
+ {@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and
+ {@link android.animation.ArgbEvaluator} type evaluators.</p>
+
+ <p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
+ interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method.
+ This allows the animator that you are using to return an
+ appropriate value for your animated property at the current point of the animation. The
+ {@link android.animation.FloatEvaluator} class demonstrates how to do this:</p>
+ <pre>
+public class FloatEvaluator implements TypeEvaluator {
+
+ public Object evaluate(float fraction, Object startValue, Object endValue) {
+ float startFloat = ((Number) startValue).floatValue();
+ return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
+ }
+}
+</pre>
+
+ <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or
+ {@link android.animation.ObjectAnimator}) runs, it calculates a current elapsed
+ fraction of the animation (a value between 0 and 1) and then calculates an eased
+ version of that depending on what interpolator that you are using. The eased fraction
+ is what your {@link android.animation.TypeEvaluator} receives through the <code>fraction</code>
+ parameter, so you do not have to take into account the interpolator
+ when calculating animated values.</p>
+
+ <h3 id="interpolators">Using Interpolators</h3>
+
+ <p>An interpolator define how specific values in an animation are
+ calculated as a function of time. For example, you can specify animations to happen
+ linearly across the whole animation, meaning the animation moves evenly the entire
+ time, or you can specify animations to use non-linear time, for example, using
+ acceleration or deceleration at the beginning or end of the animation.</p>
+
+ <p>Interpolators in the animation system receive a fraction from Animators that represent the elapsed time
+ of the animation. Interpolators modify this fraction to coincide with the type of
+ animation that it aims to provide. The Android system provides a set of common
+ interpolators in the {@link android.view.animation android.view.animation package}. If
+ none of these suit your needs, you can implement the {@link
+ android.animation.TimeInterpolator} interface and create your own.</p>
+
+ <p>As an example, how the default interpolator {@link
+ android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.view.animation.LinearInterpolator} calculate eased fractions are compared below. The {@link
+ android.view.animation.LinearInterpolator} has no effect on the elapsed fraction,
+ because a linear interpolation is calculated the same way as the elapsed fraction. The
+ {@link android.view.animation.AccelerateDecelerateInterpolator} accelerates into the
+ animation and decelerates out of it. The following methods define the logic for these
+ interpolators:</p>
+
+ <p><strong>AccelerateDecelerateInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
+ }</pre>
+
+ <p><strong>LinearInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return input;
+ }</pre>
+
+ <p>The following table represents the approximate values that are calculated by these
+ interpolators for an animation that lasts 1000ms:</p>
+
+ <table>
+ <tr>
+ <th>ms elapsed</th>
+
+ <th>Elapsed fraction/Eased fraction (Linear)</th>
+
+ <th>Eased fraction (Accelerate/Decelerate)</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+
+ <td>0</td>
+
+ <td>0</td>
+ </tr>
+
+ <tr>
+ <td>200</td>
+
+ <td>.2</td>
+
+ <td>.1</td>
+ </tr>
+
+ <tr>
+ <td>400</td>
+
+ <td>.4</td>
+
+ <td>.345</td>
+ </tr>
+
+ <tr>
+ <td>600</td>
+
+ <td>.6</td>
+
+ <td>.8</td>
+ </tr>
+
+ <tr>
+ <td>800</td>
+
+ <td>.8</td>
+
+ <td>.9</td>
+ </tr>
+
+ <tr>
+ <td>1000</td>
+
+ <td>1</td>
+
+ <td>1</td>
+ </tr>
+ </table>
+
+ <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes
+ the values at the same speed, .2 for every 200ms that passes. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than
+ {@link android.view.animation.LinearInterpolator} between 200ms and 600ms and slower
+ between 600ms and 1000ms.</p>
+
+ <h3 id="keyframes">Specifying Keyframes</h3>
+
+ <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets
+ you define a specific state at a specific time of an animation. Each keyframe can also
+ have its own interpolator to control the behavior of the animation in the interval
+ between the previous keyframe's time and the time of this keyframe.</p>
+
+ <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the
+ factory methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
+ android.animation.Keyframe#ofFloat ofFloat()}, or {@link
+ android.animation.Keyframe#ofObject ofObject()} to obtain the appropriate type of
+ {@link android.animation.Keyframe}. You then call the {@link
+ android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
+ obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the
+ object, you can obtain an animator by passing in the {@link
+ android.animation.PropertyValuesHolder} object and the object to animate. The following
+ code snippet demonstrates how to do this:</p>
+ <pre>
+ Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+ Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+ Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+ PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+ ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
+ rotationAnim.setDuration(5000ms);
+
+</pre>For a more complete example on how to use keyframes, see the <a href=
+"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
+ MultiPropertyAnimation</a> sample in APIDemos.
+
+ <h3 id="choreography">Choreographing multiple animations with Animator Sets</h3>
+
+ <p>In many cases, you want to play an animation that depends on when another animation
+ starts or finishes. The Android system lets you bundle animations together into an
+ {@link android.animation.AnimatorSet}, so that you can specify whether to start animations
+ simultaneously, sequentially, or after a specified delay. You can also nest {@link
+ android.animation.AnimatorSet} objects within each other.</p>
+
+ <p>The following sample code taken from the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample (modified for simplicity) plays the following
+ {@link android.animation.Animator} objects in the following manner:</p>
+
+ <ol>
+ <li>Plays <code>bounceAnim</code>.</li>
+
+ <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>,
+ <code>stretchAnim1</code>, and <code>stretchAnim2</code> at the same time.</li>
+
+ <li>Plays <code>bounceBackAnim</code>.</li>
+
+ <li>Plays <code>fadeAnim</code>.</li>
+ </ol>
+ <pre>AnimatorSet bouncer = new AnimatorSet();
+bouncer.play(bounceAnim).before(squashAnim1);
+bouncer.play(squashAnim1).with(squashAnim2);
+bouncer.play(squashAnim1).with(stretchAnim1);
+bouncer.play(squashAnim1).with(stretchAnim2);
+bouncer.play(bounceBackAnim).after(stretchAnim2);
+ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+AnimatorSet animatorSet = new AnimatorSet();
+animatorSet.play(bouncer).before(fadeAnim);
+animatorSet.start();
+</pre>
+
+ <p>For a more complete example on how to use animator sets, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in APIDemos.</p>
+
+ <h3 id="declaring-xml">Declaring animations in XML</h3>
+
+ <p>As with <a href="view-animation">view animation</a>, you can declare property animations with
+ XML instead of doing it programmatically. The following Android classes also have XML
+ declaration support with the following XML tags:</p>
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} - <code><animator></code></li>
+
+ <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li>
+
+ <li>{@link android.animation.AnimatorSet} - <code><AnimatorSet></code></li>
+ </ul>
+
+ <p>Both <code><animator></code> ({@link android.animation.ValueAnimator}) and
+ <code><objectAnimator></code> ({@link android.animation.ObjectAnimator}) have the
+ following attributes:</p>
+
+ <dl>
+ <dt><code>android:duration</code></dt>
+ <dd>The number of milliseconds that the animation runs.</dd>
+
+ <dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
+ <dd>The values being animated
+ between. These are restricted to numbers (<code>float</code> or <code>int</code>) in
+ XML. They can be <code>float</code>, <code>int</code>, or any kind of
+ <code>Object</code> when creating animations programmatically.</dd>
+
+ <dt><code>android:valueType</code></dt>
+ <dd>Set to either <code>"floatType"</code> or <code>"intType"</code>.</dd>
+
+ <dt><code>android:startDelay</code></dt>
+ <dd>The delay, in milliseconds, before the animation begins
+ playing (after calling {@link android.animation.ValueAnimator#start start()}).</dd>
+
+ <dt><code>android:repeatCount</code></dt>
+ <dd>How many times to repeat an animation. Set to
+ <code>"-1"</code> for infinite repeating or to a positive integer. For example, a value of
+ <code>"1"</code> means that the animation is repeated once after the initial run of the
+ animation, so the animation plays a total of two times. The default value is
+ <code>"0"</code>.</dd>
+
+ <dt><code>android:repeatMode</code></dt>
+ <dd>How an animation behaves when it reaches the end of the
+ animation. <code>android:repeatCount</code> must be set to a positive integer or
+ <code>"-1"</code> for this attribute to have an effect. Set to <code>"reverse"</code> to
+ have the animation reverse direction with each iteration or <code>"repeat"</code> to
+ have the animation loop from the beginning each time.</dd>
+ </dl>
+
+ <p>The <code>objectAnimator</code> ({@link android.animation.ObjectAnimator}) element has the
+ additional attribute <code>propertyName</code>, that lets you specify the name of the
+ property being animated. The <code>objectAnimator</code> element does not expose a
+ <code>target</code> attribute, however, so you cannot set the object to animate in the
+ XML declaration. You have to inflate the XML resource by calling
+ {@link android.animation.AnimatorInflater#loadAnimator loadAnimator()} and call
+ {@link android.animation.ObjectAnimator#setTarget setTarget()} to set the target object, before calling
+ {@link android.animation.ObjectAnimator#start start()}.</p>
+
+ <p>The <code>set</code> element ({@link android.animation.AnimatorSet}) exposes a single
+ attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default)
+ to play all the animations in this set at once. Set this attribute to
+ <code>sequentially</code> to play the animations in the order they are declared.</p>
+
+ <p>You can specify nested <code>set</code> tags to further group animations together.
+ The animations that you want to group together should be children of the
+ <code>set</code> tag and can define their own <code>ordering</code> attribute.</p>
+
+ <p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object
+ that animates x and y at the same time (<code>together</code> is the default ordering
+ when nothing is specified), then runs an animation that fades an object out:</p>
+ <pre><set android:ordering="sequentially">
+ <set>
+ <objectAnimator
+ android:propertyName="x"
+ android:duration="500"
+ android:valueTo="400"
+ android:valueType="int"/>
+ <objectAnimator
+ android:propertyName="y"
+ android:duration="500"
+ android:valueTo="300"
+ android:valueType="int" >
+ </set>
+ <objectAnimator
+ android:propertyName="alpha"
+ android:duration="500"
+ android:valueTo="0f"/>
+ </set>
+</pre>
+
+ <p>In order to run this animation, you must inflate the XML resources in your code to
+ an {@link android.animation.AnimatorSet} object, and then set the target objects for all of
+ the animations before starting the animation set. Calling {@link
+ android.animation.AnimatorSet#setTarget setTarget()} sets a single target object for
+ all children of the {@link android.animation.AnimatorSet}.</p>
+
+ <h2 id="view-animation">View Animation</h2>You can use View Animation in any View
+ object to perform tweened animation and frame by frame animation. Tween animation
+ calculates the animation given information such as the start point, end point, size,
+ rotation, and other common aspects of an animation. Frame by frame animation lets you
+ load a series of Drawable resources one after another to create an animation.
+
+ <h3 id="tween-animation">Tween Animation</h3>
+
+ <p>A tween animation can perform a series of simple transformations (position, size,
+ rotation, and transparency) on the contents of a View object. So, if you have a
+ {@link android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a background
+ image, the background image will be transformed along with the text. The {@link
+ android.view.animation animation package} provides all the classes used in a tween
+ animation.</p>
+
+ <p>A sequence of animation instructions defines the tween animation, defined by either
+ XML or Android code. As with defining a layout, an XML file is recommended because it's
+ more readable, reusable, and swappable than hard-coding the animation. In the example
+ below, we use XML. (To learn more about defining an animation in your application code,
+ instead of XML, refer to the {@link android.view.animation.AnimationSet} class and
+ other {@link android.view.animation.Animation} subclasses.)</p>
+
+ <p>The animation instructions define the transformations that you want to occur, when
+ they will occur, and how long they should take to apply. Transformations can be
+ sequential or simultaneous — for example, you can have the contents of a TextView
+ move from left to right, and then rotate 180 degrees, or you can have the text move and
+ rotate simultaneously. Each transformation takes a set of parameters specific for that
+ transformation (starting size and ending size for size change, starting angle and
+ ending angle for rotation, and so on), and also a set of common parameters (for
+ instance, start time and duration). To make several transformations happen
+ simultaneously, give them the same start time; to make them sequential, calculate the
+ start time plus the duration of the preceding transformation.</p>
+
+ <p>The animation XML file belongs in the <code>res/anim/</code> directory of your
+ Android project. The file must have a single root element: this will be either a single
+ <code><alpha></code>, <code><scale></code>, <code><translate></code>,
+ <code><rotate></code>, interpolator element, or <code><set></code> element
+ that holds groups of these elements (which may include another
+ <code><set></code>). By default, all animation instructions are applied
+ simultaneously. To make them occur sequentially, you must specify the
+ <code>startOffset</code> attribute, as shown in the example below.</p>
+
+ <p>The following XML from one of the ApiDemos is used to stretch, then simultaneously
+ spin and rotate a View object.</p>
+ <pre>
+<set android:shareInterpolator="false">
+ <scale
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:fromXScale="1.0"
+ android:toXScale="1.4"
+ android:fromYScale="1.0"
+ android:toYScale="0.6"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillAfter="false"
+ android:duration="700" />
+ <set android:interpolator="@android:anim/decelerate_interpolator">
+ <scale
+ android:fromXScale="1.4"
+ android:toXScale="0.0"
+ android:fromYScale="0.6"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400"
+ android:fillBefore="false" />
+ <rotate
+ android:fromDegrees="0"
+ android:toDegrees="-45"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400" />
+ </set>
+</set>
+</pre>
+
+ <p>Screen coordinates (not used in this example) are (0,0) at the upper left hand
+ corner, and increase as you go down and to the right.</p>
+
+ <p>Some values, such as pivotX, can be specified relative to the object itself or
+ relative to the parent. Be sure to use the proper format for what you want ("50" for
+ 50% relative to the parent, or "50%" for 50% relative to itself).</p>
+
+ <p>You can determine how a transformation is applied over time by assigning an {@link
+ android.view.animation.Interpolator}. Android includes several Interpolator subclasses
+ that specify various speed curves: for instance, {@link
+ android.view.animation.AccelerateInterpolator} tells a transformation to start slow and
+ speed up. Each one has an attribute value that can be applied in the XML.</p>
+
+ <p>With this XML saved as <code>hyperspace_jump.xml</code> in the
+ <code>res/anim/</code> directory of the project, the following code will reference
+ it and apply it to an {@link android.widget.ImageView} object from the layout.</p>
+ <pre>
+ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
+Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
+spaceshipImage.startAnimation(hyperspaceJumpAnimation);
+</pre>
+
+ <p>As an alternative to <code>startAnimation()</code>, you can define a starting time
+ for the animation with <code>{@link android.view.animation.Animation#setStartTime(long)
+ Animation.setStartTime()}</code>, then assign the animation to the View with
+ <code>{@link android.view.View#setAnimation(android.view.animation.Animation)
+ View.setAnimation()}</code>.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+
+ <p class="note"><strong>Note:</strong> Regardless of how your animation may move or
+ resize, the bounds of the View that holds your animation will not automatically adjust
+ to accommodate it. Even so, the animation will still be drawn beyond the bounds of its
+ View and will not be clipped. However, clipping <em>will occur</em> if the animation
+ exceeds the bounds of the parent View.</p>
+
+ <h3 id="frame-animation">Frame Animation</h3>
+
+ <p>This is a traditional animation in the sense that it is created with a sequence of
+ different images, played in order, like a roll of film. The {@link
+ android.graphics.drawable.AnimationDrawable} class is the basis for frame
+ animations.</p>
+
+ <p>While you can define the frames of an animation in your code, using the {@link
+ android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished
+ with a single XML file that lists the frames that compose the animation. Like the tween
+ animation above, the XML file for this kind of animation belongs in the
+ <code>res/drawable/</code> directory of your Android project. In this case, the
+ instructions are the order and duration for each frame of the animation.</p>
+
+ <p>The XML file consists of an <code><animation-list></code> element as the root
+ node and a series of child <code><item></code> nodes that each define a frame: a
+ drawable resource for the frame and the frame duration. Here's an example XML file for
+ a frame-by-frame animation:</p>
+ <pre>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="true">
+ <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
+</animation-list>
+</pre>
+
+ <p>This animation runs for just three frames. By setting the
+ <code>android:oneshot</code> attribute of the list to <var>true</var>, it will cycle
+ just once then stop and hold on the last frame. If it is set <var>false</var> then the
+ animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the
+ <code>res/drawable/</code> directory of the project, it can be added as the background
+ image to a View and then called to play. Here's an example Activity, in which the
+ animation is added to an {@link android.widget.ImageView} and then animated when the
+ screen is touched:</p>
+ <pre>
+AnimationDrawable rocketAnimation;
+
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
+ rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
+ rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
+}
+
+public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ rocketAnimation.start();
+ return true;
+ }
+ return super.onTouchEvent(event);
+}
+</pre>
+
+ <p>It's important to note that the <code>start()</code> method called on the
+ AnimationDrawable cannot be called during the <code>onCreate()</code> method of your
+ Activity, because the AnimationDrawable is not yet fully attached to the window. If you
+ want to play the animation immediately, without requiring interaction, then you might
+ want to call it from the <code>{@link
+ android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code>
+ method in your Activity, which will get called when Android brings your window into
+ focus.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
\ No newline at end of file
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 221406c..11964da 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -343,7 +343,27 @@
///////////////////
/// SAMPLE CODE ///
///////////////////
-
+
+ {
+ tags: ['sample'],
+ path: 'samples/AccelerometerPlay/index.html',
+ title: {
+ en: 'Accelerometer Play'
+ },
+ description: {
+ en: ''
+ }
+ },
+ {
+ tags: ['sample'],
+ path: 'samples/AccessibilityService/index.html',
+ title: {
+ en: 'Accessibility Service'
+ },
+ description: {
+ en: 'Illustrates an accessibility service that provides custom feedback for the Clock application which comes by default with Android devices'
+ }
+ },
{
tags: ['sample', 'layout', 'ui'],
path: 'samples/ApiDemos/index.html',
@@ -355,7 +375,7 @@
}
},
{
- tags: ['sample', 'data', 'newfeature', 'accountsync', 'new'],
+ tags: ['sample', 'data', 'newfeature', 'accountsync'],
path: 'samples/BackupRestore/index.html',
title: {
en: 'Backup and Restore'
@@ -395,6 +415,16 @@
}
},
{
+ tags: ['sample', 'ui'],
+ path: 'samples/CubeLiveWallpaper/index.html',
+ title: {
+ en: 'Cube Live Wallpaper'
+ },
+ description: {
+ en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
+ }
+ },
+ {
tags: ['sample'],
path: 'samples/Home/index.html',
title: {
@@ -405,6 +435,16 @@
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/Honeycomb-Gallery/index.html',
+ title: {
+ en: 'Honeycomb Gallery'
+ },
+ description: {
+ en: 'An image gallery application using Honeycomb-specific APIs.'
+ }
+ },
+ {
tags: ['sample', 'gamedev', 'media'],
path: 'samples/JetBoy/index.html',
title: {
@@ -415,16 +455,6 @@
}
},
{
- tags: ['sample', 'ui', 'newfeature'],
- path: 'samples/CubeLiveWallpaper/index.html',
- title: {
- en: 'Live Wallpaper'
- },
- description: {
- en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
- }
- },
- {
tags: ['sample', 'gamedev', 'media'],
path: 'samples/LunarLander/index.html',
title: {
@@ -446,6 +476,16 @@
},
{
tags: ['sample', 'data'],
+ path: 'samples/NFCDemo/index.html',
+ title: {
+ en: 'NFC Demo'
+ },
+ description: {
+ en: 'An application for reading NFC Forum Type 2 Tags using the NFC APIs'
+ }
+ },
+ {
+ tags: ['sample', 'data'],
path: 'samples/NotePad/index.html',
title: {
en: 'Note Pad'
@@ -475,6 +515,16 @@
}
},
{
+ tags: ['sample'],
+ path: 'samples/SipDemo/index.html',
+ title: {
+ en: 'SIP Demo'
+ },
+ description: {
+ en: 'A demo application highlighting how to make internet-based calls with the SIP API.'
+ }
+ },
+ {
tags: ['sample', 'layout', 'ui'],
path: 'samples/Snake/index.html',
title: {
@@ -485,6 +535,16 @@
}
},
{
+ tags: ['sample', 'input'],
+ path: 'samples/SoftKeyboard/index.html',
+ title: {
+ en: 'Soft Keyboard'
+ },
+ description: {
+ en: 'An example of writing an input method for a software keyboard.'
+ }
+ },
+ {
tags: ['sample', 'testing'],
path: 'samples/Spinner/index.html',
title: {
@@ -525,16 +585,6 @@
}
},
{
- tags: ['sample', 'input'],
- path: 'samples/SoftKeyboard/index.html',
- title: {
- en: 'Soft Keyboard'
- },
- description: {
- en: 'An example of writing an input method for a software keyboard.'
- }
- },
- {
tags: ['sample', 'ui'],
path: 'samples/Wiktionary/index.html',
title: {
@@ -555,7 +605,7 @@
}
},
{
- tags: ['sample', 'layout', 'new'],
+ tags: ['sample', 'layout'],
path: 'samples/XmlAdapters/index.html',
title: {
en: 'XML Adapters'
diff --git a/docs/html/resources/samples/images/NfcDemo.png b/docs/html/resources/samples/images/NfcDemo.png
new file mode 100644
index 0000000..c175d12
--- /dev/null
+++ b/docs/html/resources/samples/images/NfcDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/images/hcgallery.png b/docs/html/resources/samples/images/hcgallery.png
new file mode 100644
index 0000000..9a80fd7
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery.png
Binary files differ
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 27f65bc..30b45f7 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -38,6 +38,15 @@
AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
};
+enum {
+ /*
+ * Indicates that an input device has switches.
+ * This input source flag is hidden from the API because switches are only used by the system
+ * and applications have no way to interact with them.
+ */
+ AINPUT_SOURCE_SWITCH = 0x80000000,
+};
+
/*
* Maximum number of pointers supported per motion event.
* Smallest number of pointers is 1.
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index ef19579..c650141 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -29,12 +29,8 @@
public class Credentials {
private static final String LOGTAG = "Credentials";
- public static final String UNLOCK_ACTION = "android.credentials.UNLOCK";
-
public static final String INSTALL_ACTION = "android.credentials.INSTALL";
- public static final String SYSTEM_INSTALL_ACTION = "android.credentials.SYSTEM_INSTALL";
-
/** Key prefix for CA certificates. */
public static final String CA_CERTIFICATE = "CACERT_";
@@ -73,7 +69,7 @@
public void unlock(Context context) {
try {
- Intent intent = new Intent(UNLOCK_ACTION);
+ Intent intent = new Intent("com.android.credentials.UNLOCK");
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(LOGTAG, e.toString());
@@ -107,12 +103,4 @@
Log.w(LOGTAG, e.toString());
}
}
-
- public void installFromSdCard(Context context) {
- try {
- context.startActivity(createInstallIntent());
- } catch (ActivityNotFoundException e) {
- Log.w(LOGTAG, e.toString());
- }
- }
}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index c49be93..38e0848 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -23,6 +23,7 @@
Program.cpp \
ProgramCache.cpp \
ResourceCache.cpp \
+ ShapeCache.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
TextureCache.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index fde4f96..bffab95 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -73,6 +73,10 @@
LOGD(" LayerCache %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
LOGD(" GradientCache %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
+ LOGD(" CircleShapeCache %8d / %8d",
+ circleShapeCache.getSize(), circleShapeCache.getMaxSize());
+ LOGD(" RoundRectShapeCache %8d / %8d",
+ roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
dropShadowCache.getMaxSize());
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index a11b6bc..c03c347 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -32,6 +32,7 @@
#include "PatchCache.h"
#include "ProgramCache.h"
#include "PathCache.h"
+#include "ShapeCache.h"
#include "TextDropShadowCache.h"
#include "FboCache.h"
#include "ResourceCache.h"
@@ -159,6 +160,8 @@
GradientCache gradientCache;
ProgramCache programCache;
PathCache pathCache;
+ RoundRectShapeCache roundRectShapeCache;
+ CircleShapeCache circleShapeCache;
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
FboCache fboCache;
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 71ec760..014519e 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -45,6 +45,9 @@
// Turn on to display debug info about paths
#define DEBUG_PATHS 0
+// Turn on to display debug info about shapes
+#define DEBUG_SHAPES 0
+
// Turn on to display debug info about textures
#define DEBUG_TEXTURES 0
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ade85e5..a74a95f 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -103,6 +103,8 @@
"DrawPatch",
"DrawColor",
"DrawRect",
+ "DrawRoundRect",
+ "DrawCircle",
"DrawPath",
"DrawLines",
"DrawText",
@@ -332,6 +334,15 @@
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
}
break;
+ case DrawRoundRect: {
+ renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
+ getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawCircle: {
+ renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
case DrawPath: {
renderer.drawPath(getPath(), getPaint());
}
@@ -601,6 +612,21 @@
addPaint(paint);
}
+void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ addOp(DisplayList::DrawRoundRect);
+ addBounds(left, top, right, bottom);
+ addPoint(rx, ry);
+ addPaint(paint);
+}
+
+void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ addOp(DisplayList::DrawCircle);
+ addPoint(x, y);
+ addFloat(radius);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
addOp(DisplayList::DrawPath);
addPath(path);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 05864ec..4b727f6 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -110,6 +110,8 @@
DrawPatch,
DrawColor,
DrawRect,
+ DrawRoundRect,
+ DrawCircle,
DrawPath,
DrawLines,
DrawText,
@@ -270,6 +272,9 @@
float left, float top, float right, float bottom, SkPaint* paint);
void drawColor(int color, SkXfermode::Mode mode);
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ void drawCircle(float x, float y, float radius, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 6477eb0..9528dbb 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1305,6 +1305,38 @@
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
+void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
+ right - left, bottom - top, rx, ry, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float x = left + texture->left - texture->offset;
+ const float y = top + texture->top - texture->offset;
+
+ drawPathTexture(texture, x, y, paint);
+}
+
+void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float left = (x - radius) + texture->left - texture->offset;
+ const float top = (y - radius) + texture->top - texture->offset;
+
+ drawPathTexture(texture, left, top, paint);
+}
+
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
if (quickReject(left, top, right, bottom)) {
return;
@@ -1453,8 +1485,7 @@
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
- GLuint textureUnit = 0;
- glActiveTexture(gTextureUnits[textureUnit]);
+ glActiveTexture(gTextureUnits[0]);
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return;
@@ -1463,31 +1494,7 @@
const float x = texture->left - texture->offset;
const float y = texture->top - texture->offset;
- if (quickReject(x, y, x + texture->width, y + texture->height)) {
- return;
- }
-
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
-
- setupDraw();
- setupDrawWithTexture(true);
- setupDrawAlpha8Color(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(true, mode);
- setupDrawProgram();
- setupDrawModelView(x, y, x + texture->width, y + texture->height);
- setupDrawTexture(texture->id);
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawShaderUniforms();
- setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
- finishDrawTexture();
+ drawPathTexture(texture, x, y, paint);
}
void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
@@ -1583,6 +1590,35 @@
// Drawing implementation
///////////////////////////////////////////////////////////////////////////////
+void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
+ float x, float y, SkPaint* paint) {
+ if (quickReject(x, y, x + texture->width, y + texture->height)) {
+ return;
+ }
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ setupDraw();
+ setupDrawWithTexture(true);
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x + texture->width, y + texture->height);
+ setupDrawTexture(texture->id);
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms();
+ setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ finishDrawTexture();
+}
+
// Same values used by Skia
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
#define kStdUnderline_Offset (1.0f / 9.0f)
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4150ddc..a43660b 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -107,6 +107,9 @@
float left, float top, float right, float bottom, SkPaint* paint);
virtual void drawColor(int color, SkXfermode::Mode mode);
virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
@@ -343,6 +346,8 @@
void drawTextDecorations(const char* text, int bytesCount, float length,
float x, float y, SkPaint* paint);
+ void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
+
/**
* Resets the texture coordinates stored in mMeshVertices. Setting the values
* back to default is achieved by calling:
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 6a0d7ea..2f230b5 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -48,6 +48,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_SHAPE_CACHE_SIZE "ro.hwui.shape_cache_size"
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
@@ -66,6 +67,7 @@
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
#define DEFAULT_LAYER_CACHE_SIZE 8.0f
#define DEFAULT_PATH_CACHE_SIZE 4.0f
+#define DEFAULT_SHAPE_CACHE_SIZE 1.0f
#define DEFAULT_PATCH_CACHE_SIZE 512
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp
new file mode 100644
index 0000000..ffa18e3
--- /dev/null
+++ b/libs/hwui/ShapeCache.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 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 "ShapeCache.h"
+
+namespace android {
+namespace uirenderer {
+
+RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>() {
+}
+
+PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
+ float rx, float ry, SkPaint* paint) {
+ RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ SkRect r;
+ r.set(0.0f, 0.0f, width, height);
+ path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>() {
+}
+
+PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
+ CircleShapeCacheEntry entry(radius, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
new file mode 100644
index 0000000..910d01d
--- /dev/null
+++ b/libs/hwui/ShapeCache.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2011 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_HWUI_SHAPE_CACHE_H
+#define ANDROID_HWUI_SHAPE_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <SkCanvas.h>
+#include <SkRect.h>
+
+#include "PathCache.h"
+#include "Properties.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+// Debug
+#if DEBUG_SHAPES
+ #define SHAPE_LOGD(...) LOGD(__VA_ARGS__)
+#else
+ #define SHAPE_LOGD(...)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Describe a shape in the shape cache.
+ */
+struct ShapeCacheEntry {
+ enum ShapeType {
+ kShapeNone,
+ kShapeRoundRect,
+ kShapeCircle,
+ kShapeOval,
+ kShapeArc
+ };
+
+ ShapeCacheEntry() {
+ shapeType = kShapeNone;
+ join = SkPaint::kDefault_Join;
+ cap = SkPaint::kDefault_Cap;
+ style = SkPaint::kFill_Style;
+ miter = 4.0f;
+ strokeWidth = 1.0f;
+ }
+
+ ShapeCacheEntry(const ShapeCacheEntry& entry):
+ shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
+ style(entry.style), miter(entry.miter),
+ strokeWidth(entry.strokeWidth) {
+ }
+
+ ShapeCacheEntry(ShapeType type, SkPaint* paint) {
+ shapeType = type;
+ join = paint->getStrokeJoin();
+ cap = paint->getStrokeCap();
+ float v = paint->getStrokeMiter();
+ miter = *(uint32_t*) &v;
+ v = paint->getStrokeWidth();
+ strokeWidth = *(uint32_t*) &v;
+ style = paint->getStyle();
+ }
+
+ virtual ~ShapeCacheEntry() {
+ }
+
+ // shapeType must be checked in subclasses operator<
+ ShapeType shapeType;
+ SkPaint::Join join;
+ SkPaint::Cap cap;
+ SkPaint::Style style;
+ uint32_t miter;
+ uint32_t strokeWidth;
+
+ bool operator<(const ShapeCacheEntry& rhs) const {
+ LTE_INT(shapeType) {
+ LTE_INT(join) {
+ LTE_INT(cap) {
+ LTE_INT(style) {
+ LTE_INT(miter) {
+ LTE_INT(strokeWidth) {
+ return lessThan(rhs);
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+protected:
+ virtual bool lessThan(const ShapeCacheEntry& rhs) const {
+ return false;
+ }
+}; // struct ShapeCacheEntry
+
+
+struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
+ RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ mRx = *(uint32_t*) ℞
+ mRy = *(uint32_t*) &ry;
+ }
+
+ RoundRectShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = 0;
+ mHeight = 0;
+ mRx = 0;
+ mRy = 0;
+ }
+
+ RoundRectShapeCacheEntry(const RoundRectShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ mRx = entry.mRx;
+ mRy = entry.mRy;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ LTE_INT(mRx) {
+ LTE_INT(mRy) {
+ return false;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mRx;
+ uint32_t mRy;
+}; // RoundRectShapeCacheEntry
+
+struct CircleShapeCacheEntry: public ShapeCacheEntry {
+ CircleShapeCacheEntry(float radius, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) {
+ mRadius = *(uint32_t*) &radius;
+ }
+
+ CircleShapeCacheEntry(): ShapeCacheEntry() {
+ mRadius = 0;
+ }
+
+ CircleShapeCacheEntry(const CircleShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mRadius = entry.mRadius;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
+ LTE_INT(mRadius) {
+ return false;
+ }
+ return false;
+ }
+
+private:
+ uint32_t mRadius;
+}; // CircleShapeCacheEntry
+
+/**
+ * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
+ * Any texture added to the cache causing the cache to grow beyond the maximum
+ * allowed size will also cause the oldest texture to be kicked out.
+ */
+template<typename Entry>
+class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
+public:
+ ShapeCache();
+ ShapeCache(uint32_t maxByteSize);
+ ~ShapeCache();
+
+ /**
+ * Used as a callback when an entry is removed from the cache.
+ * Do not invoke directly.
+ */
+ void operator()(Entry& path, PathTexture*& texture);
+
+ /**
+ * Clears the cache. This causes all textures to be deleted.
+ */
+ void clear();
+
+ /**
+ * 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();
+
+protected:
+ PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint);
+
+ PathTexture* get(Entry entry) {
+ return mCache.get(entry);
+ }
+
+private:
+ /**
+ * Generates the texture from a bitmap into the specified texture structure.
+ */
+ void generateTexture(SkBitmap& bitmap, Texture* texture);
+
+ void removeTexture(PathTexture* texture);
+
+ void init();
+
+ GenerationCache<Entry, PathTexture*> mCache;
+ uint32_t mSize;
+ uint32_t mMaxSize;
+ GLuint mMaxTextureSize;
+
+ bool mDebugEnabled;
+}; // class ShapeCache
+
+class RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> {
+public:
+ RoundRectShapeCache();
+
+ PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+class CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> {
+public:
+ CircleShapeCache();
+
+ PathTexture* getCircle(float radius, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+ShapeCache<Entry>::ShapeCache():
+ mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
+ mSize(0), mMaxSize(MB(DEFAULT_SHAPE_CACHE_SIZE)) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(PROPERTY_SHAPE_CACHE_SIZE, property, NULL) > 0) {
+ LOGD(" Setting shape cache size to %sMB", property);
+ setMaxSize(MB(atof(property)));
+ } else {
+ LOGD(" Using default shape cache size of %.2fMB", DEFAULT_SHAPE_CACHE_SIZE);
+ }
+ init();
+}
+
+template<class Entry>
+ShapeCache<Entry>::ShapeCache(uint32_t maxByteSize):
+ mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
+ mSize(0), mMaxSize(maxByteSize) {
+ init();
+}
+
+template<class Entry>
+ShapeCache<Entry>::~ShapeCache() {
+ mCache.clear();
+}
+
+template<class Entry>
+void ShapeCache<Entry>::init() {
+ mCache.setOnEntryRemovedListener(this);
+
+ GLint maxTextureSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ mMaxTextureSize = maxTextureSize;
+
+ mDebugEnabled = readDebugLevel() & kDebugCaches;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getSize() {
+ return mSize;
+}
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getMaxSize() {
+ return mMaxSize;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::setMaxSize(uint32_t maxSize) {
+ mMaxSize = maxSize;
+ while (mSize > mMaxSize) {
+ mCache.removeOldest();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Callbacks
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) {
+ removeTexture(texture);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
+ if (texture) {
+ const uint32_t size = texture->width * texture->height;
+ mSize -= size;
+
+ SHAPE_LOGD("ShapeCache::callback: delete path: name, size, mSize = %d, %d, %d",
+ texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Path deleted, size = %d", size);
+ }
+
+ glDeleteTextures(1, &texture->id);
+ delete texture;
+ }
+}
+
+template<class Entry>
+PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
+ const SkPaint* paint) {
+ const SkRect& bounds = path->getBounds();
+
+ const float pathWidth = fmax(bounds.width(), 1.0f);
+ const float pathHeight = fmax(bounds.height(), 1.0f);
+
+ if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
+ LOGW("Shape too large to be rendered into a texture");
+ return NULL;
+ }
+
+ const float offset = paint->getStrokeWidth() * 1.5f;
+ const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
+ const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
+
+ const uint32_t size = width * height;
+ // Don't even try to cache a bitmap that's bigger than the cache
+ if (size < mMaxSize) {
+ while (mSize + size > mMaxSize) {
+ mCache.removeOldest();
+ }
+ }
+
+ PathTexture* texture = new PathTexture;
+ texture->left = bounds.fLeft;
+ texture->top = bounds.fTop;
+ texture->offset = offset;
+ texture->width = width;
+ texture->height = height;
+ texture->generation = path->getGenerationID();
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kA8_Config, width, height);
+ bitmap.allocPixels();
+ bitmap.eraseColor(0);
+
+ SkPaint pathPaint(*paint);
+
+ // Make sure the paint is opaque, color, alpha, filter, etc.
+ // will be applied later when compositing the alpha8 texture
+ pathPaint.setColor(0xff000000);
+ pathPaint.setAlpha(255);
+ pathPaint.setColorFilter(NULL);
+ pathPaint.setMaskFilter(NULL);
+ pathPaint.setShader(NULL);
+ SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
+ pathPaint.setXfermode(mode)->safeUnref();
+
+ SkCanvas canvas(bitmap);
+ canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
+ canvas.drawPath(*path, pathPaint);
+
+ generateTexture(bitmap, texture);
+
+ if (size < mMaxSize) {
+ mSize += size;
+ SHAPE_LOGD("ShapeCache::get: create path: name, size, mSize = %d, %d, %d",
+ texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Shape created, size = %d", size);
+ }
+ mCache.put(entry, texture);
+ } else {
+ texture->cleanup = true;
+ }
+
+ return texture;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::clear() {
+ mCache.clear();
+}
+
+template<class Entry>
+void ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) {
+ SkAutoLockPixels alp(bitmap);
+ if (!bitmap.readyToDraw()) {
+ LOGE("Cannot generate texture from bitmap");
+ return;
+ }
+
+ glGenTextures(1, &texture->id);
+
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ // Textures are Alpha8
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ texture->blend = true;
+ 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);
+ 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);
+}
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_SHAPE_CACHE_H
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 1663313..f24a71d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -66,12 +66,6 @@
if (outConfig == NULL)
return BAD_VALUE;
- int err;
- PixelFormatInfo fbFormatInfo;
- if ((err = getPixelFormatInfo(PixelFormat(format), &fbFormatInfo)) < 0) {
- return err;
- }
-
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
@@ -81,23 +75,14 @@
free(configs);
return BAD_VALUE;
}
-
- const int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
- const int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
- const int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
- const int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE);
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
- EGLint r,g,b,a;
- EGLConfig curr = configs[i];
- eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
- if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
- config = curr;
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
+ config = configs[i];
break;
}
}
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
index 72e2c0b..5a41421 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
@@ -53,7 +53,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:paddingTop="5dp"
android:layout_marginLeft="8dp"
/>
</com.android.systemui.statusbar.tablet.NotificationIconArea>
@@ -63,23 +62,25 @@
android:id="@+id/notificationTrigger"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:gravity="center"
>
<com.android.systemui.statusbar.tablet.HoloClock
android:id="@+id/clock"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
>
<TextView android:id="@+id/time_bg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#1f1f1f" />
<TextView android:id="@+id/time_fg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#2e2e2e" />
</com.android.systemui.statusbar.tablet.HoloClock>
@@ -101,14 +102,13 @@
android:id="@+id/signal_battery_cluster"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:gravity="center"
>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
android:layout_marginRight="4dp"
>
<ImageView
@@ -126,10 +126,6 @@
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
- android:layout_marginLeft="2dp"
- android:layout_marginRight="2dp"
/>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
index 992995c..40f2247 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -23,7 +23,6 @@
android:orientation="vertical"
android:background="@drawable/notify_panel_clock_bg"
>
-
<ImageView
android:id="@+id/network_signal"
android:layout_height="32dp"
@@ -128,14 +127,14 @@
android:layout_height="wrap_content"
android:gravity="right"
android:singleLine="true"
- android:textSize="80sp"
+ android:textSize="72sp"
android:textColor="#999999" />
<TextView android:id="@+id/time_fg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:singleLine="true"
- android:textSize="80sp"
+ android:textSize="72sp"
android:textColor="#666666" />
</com.android.systemui.statusbar.tablet.HoloClock>
@@ -143,11 +142,17 @@
android:id="@+id/date"
style="@style/StatusBarNotificationText"
android:layout_height="wrap_content"
- android:layout_width="142dp"
+ android:layout_width="120dp"
android:layout_alignBottom="@id/clock"
android:layout_alignParentLeft="true"
android:gravity="left"
android:layout_marginLeft="32dp"
/>
+ <Button
+ android:id="@+id/mode_toggle"
+ android:background="@null"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
</RelativeLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 692d41c..973bff9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -47,6 +47,7 @@
boolean mShowing;
View mTitleArea;
+ View mModeToggle;
View mSettingsButton;
View mNotificationButton;
View mNotificationScroller;
@@ -75,7 +76,8 @@
mContentParent = (ViewGroup)findViewById(R.id.content_parent);
mContentParent.bringToFront();
mTitleArea = findViewById(R.id.title_area);
- mTitleArea.setOnClickListener(this);
+ mModeToggle = findViewById(R.id.mode_toggle);
+ mModeToggle.setOnClickListener(this);
mScrim = findViewById(R.id.scrim);
mGlow = findViewById(R.id.glow);
@@ -138,7 +140,7 @@
}
public void onClick(View v) {
- if (v == mTitleArea) {
+ if (v == mModeToggle) {
if (mSettingsView == null) {
switchToSettingsMode();
} else {
@@ -163,10 +165,10 @@
}
public boolean isInContentArea(int x, int y) {
- mContentArea.left = mContentFrame.getLeft();
- mContentArea.top = mTitleArea.getTop();
- mContentArea.right = mContentFrame.getRight();
- mContentArea.bottom = mContentFrame.getBottom();
+ mContentArea.left = mContentFrame.getLeft() + mContentFrame.getPaddingLeft();
+ mContentArea.top = mTitleArea.getTop() + mTitleArea.getPaddingTop();
+ mContentArea.right = mContentFrame.getRight() - mContentFrame.getPaddingRight();
+ mContentArea.bottom = mContentFrame.getBottom() - mContentFrame.getPaddingBottom();
offsetDescendantRectToMyCoords(mContentParent, mContentArea);
return mContentArea.contains(x, y);
}
diff --git a/packages/VpnServices/Android.mk b/packages/VpnServices/Android.mk
deleted file mode 100644
index 6cdf674..0000000
--- a/packages/VpnServices/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES :=
-
-LOCAL_PACKAGE_NAME := VpnServices
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
-########################
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/VpnServices/AndroidManifest.xml b/packages/VpnServices/AndroidManifest.xml
deleted file mode 100644
index 6092e30..0000000
--- a/packages/VpnServices/AndroidManifest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.vpn"
- android:sharedUserId="android.uid.system"
- >
- <application android:label="@string/app_label">
-
- <service android:name=".VpnServiceBinder" android:process=":remote">
- <intent-filter>
- <!-- These are the interfaces supported by the service, which
- you can bind to. -->
- <action android:name="android.net.vpn.IVpnService" />
- <!-- This is an action code you can use to select the service
- without explicitly supplying the implementation class. -->
- <action android:name="android.net.vpn.SERVICE" />
- </intent-filter>
- </service>
-
- </application>
-
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
-</manifest>
diff --git a/packages/VpnServices/MODULE_LICENSE_APACHE2 b/packages/VpnServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/packages/VpnServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/VpnServices/NOTICE b/packages/VpnServices/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/packages/VpnServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/packages/VpnServices/res/values-ar/strings.xml b/packages/VpnServices/res/values-ar/strings.xml
deleted file mode 100644
index 6bac120..0000000
--- a/packages/VpnServices/res/values-ar/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"خدمات الشبكة الظاهرية الخاصة (VPN)"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"تم توصيل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"تم فصل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"يمكنك اللمس لإعادة الاتصال بالشبكة الظاهرية الخاصة (VPN)."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-bg/strings.xml b/packages/VpnServices/res/values-bg/strings.xml
deleted file mode 100644
index fdcbf64..0000000
--- a/packages/VpnServices/res/values-bg/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN услуги"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе установена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе прекъсната"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Докоснете за повторно свързване с VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ca/strings.xml b/packages/VpnServices/res/values-ca/strings.xml
deleted file mode 100644
index b37790a..0000000
--- a/packages/VpnServices/res/values-ca/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serveis VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconnectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toqueu-ho per tornar-vos a connectar a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-cs/strings.xml b/packages/VpnServices/res/values-cs/strings.xml
deleted file mode 100644
index 96d4cc5..0000000
--- a/packages/VpnServices/res/values-cs/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je připojena"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojena"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykem se znovu připojíte k síti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-da/strings.xml b/packages/VpnServices/res/values-da/strings.xml
deleted file mode 100644
index 0f05bbc..0000000
--- a/packages/VpnServices/res/values-da/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN forbundet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN afbrudt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryk for at oprette forbindelse til et VPN igen."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-de/strings.xml b/packages/VpnServices/res/values-de/strings.xml
deleted file mode 100644
index b907be8b..0000000
--- a/packages/VpnServices/res/values-de/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-Dienste"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> mit VPN verbunden"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> von VPN getrennt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Zur Wiederherstellung der Verbindung mit einem VPN berühren"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-el/strings.xml b/packages/VpnServices/res/values-el/strings.xml
deleted file mode 100644
index d96f3e0..0000000
--- a/packages/VpnServices/res/values-el/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Υπηρεσίες VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> συνδέθηκε"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> αποσυνδέθηκε"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Πατήστε για να επανασυνδεθείτε σε ένα VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-en-rGB/strings.xml b/packages/VpnServices/res/values-en-rGB/strings.xml
deleted file mode 100644
index 905c265..0000000
--- a/packages/VpnServices/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN Services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN connected"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN disconnected"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touch to reconnect to a VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es-rUS/strings.xml b/packages/VpnServices/res/values-es-rUS/strings.xml
deleted file mode 100644
index 8f5053c..0000000
--- a/packages/VpnServices/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN conectados"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocar para volver a conectarse a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es/strings.xml b/packages/VpnServices/res/values-es/strings.xml
deleted file mode 100644
index 9182459..0000000
--- a/packages/VpnServices/res/values-es/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toca para volver a conectarte a una red VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fa/strings.xml b/packages/VpnServices/res/values-fa/strings.xml
deleted file mode 100644
index 7cee16d..0000000
--- a/packages/VpnServices/res/values-fa/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"سرویس های VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN وصل شد"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN قطع شد"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"برای اتصال مجدد به VPN لمس کنید."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fi/strings.xml b/packages/VpnServices/res/values-fi/strings.xml
deleted file mode 100644
index b15202a..0000000
--- a/packages/VpnServices/res/values-fi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-palvelut"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys muodostettu"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys katkaistu"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Yhdistä VPN-verkkoon uudelleen koskettamalla."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fr/strings.xml b/packages/VpnServices/res/values-fr/strings.xml
deleted file mode 100644
index 4a93e0a..0000000
--- a/packages/VpnServices/res/values-fr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Services VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connecté"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> déconnecté"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touchez l\'écran pour vous reconnecter à un VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hr/strings.xml b/packages/VpnServices/res/values-hr/strings.xml
deleted file mode 100644
index aedb536..0000000
--- a/packages/VpnServices/res/values-hr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN usluge"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN priključen"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN je isključen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite za ponovno povezivanje s VPN-om."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hu/strings.xml b/packages/VpnServices/res/values-hu/strings.xml
deleted file mode 100644
index 44f5427..0000000
--- a/packages/VpnServices/res/values-hu/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-szolgáltatások"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Kapcsolódva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózathoz"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Kapcsolat bontva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózattal"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Érintse meg az újracsatlakozáshoz."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-in/strings.xml b/packages/VpnServices/res/values-in/strings.xml
deleted file mode 100644
index 8b6b4c2..0000000
--- a/packages/VpnServices/res/values-in/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Layanan VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terhubung"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terputus"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Sentuh untuk terhubung kembali ke suatu VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-it/strings.xml b/packages/VpnServices/res/values-it/strings.xml
deleted file mode 100644
index 1c7a588..0000000
--- a/packages/VpnServices/res/values-it/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servizi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> collegata"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> scollegata"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocca per riconnetterti a una rete VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-iw/strings.xml b/packages/VpnServices/res/values-iw/strings.xml
deleted file mode 100644
index 74971d6..0000000
--- a/packages/VpnServices/res/values-iw/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"שירותי VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> מחובר"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> נותק"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"גע כדי להתחבר שוב ל-VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ja/strings.xml b/packages/VpnServices/res/values-ja/strings.xml
deleted file mode 100644
index 548d8a9..0000000
--- a/packages/VpnServices/res/values-ja/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPNサービス"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが接続されました"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが切断されました"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"タップしてVPNに再接続してください。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ko/strings.xml b/packages/VpnServices/res/values-ko/strings.xml
deleted file mode 100644
index 4185291..0000000
--- a/packages/VpnServices/res/values-ko/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN 서비스"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결됨"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결 끊김"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"VPN에 다시 연결하려면 터치하세요."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lt/strings.xml b/packages/VpnServices/res/values-lt/strings.xml
deleted file mode 100644
index 58f1f58..0000000
--- a/packages/VpnServices/res/values-lt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPT paslaugos"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT prijungtas"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT atjungtas"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Palieskite, kad būtų iš naujo sujungta su VPT."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lv/strings.xml b/packages/VpnServices/res/values-lv/strings.xml
deleted file mode 100644
index cb80908..0000000
--- a/packages/VpnServices/res/values-lv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN pakalpojumi"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir savienots"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir atvienots"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Pieskarieties, lai atkārtoti izveidotu savienojumu ar VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml
deleted file mode 100644
index 4790600..0000000
--- a/packages/VpnServices/res/values-nb/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Koblet til VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Koblet fra VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Trykk for å koble til et VPN på nytt"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nl/strings.xml b/packages/VpnServices/res/values-nl/strings.xml
deleted file mode 100644
index 175c7dd..0000000
--- a/packages/VpnServices/res/values-nl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> verbonden via VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN-verbinding met <xliff:g id="PROFILENAME">%s</xliff:g> verbroken"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Raak aan om opnieuw verbinding te maken met een VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pl/strings.xml b/packages/VpnServices/res/values-pl/strings.xml
deleted file mode 100644
index 565d249..0000000
--- a/packages/VpnServices/res/values-pl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Usługi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Połączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Rozłączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotknij, aby ponownie połączyć się z siecią VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt-rPT/strings.xml b/packages/VpnServices/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 020188f..0000000
--- a/packages/VpnServices/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serviços VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> ligado"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desligado"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para voltar a ligar a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt/strings.xml b/packages/VpnServices/res/values-pt/strings.xml
deleted file mode 100644
index f47652a..0000000
--- a/packages/VpnServices/res/values-pt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serviços de VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para reconectar-se a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-rm/strings.xml b/packages/VpnServices/res/values-rm/strings.xml
deleted file mode 100644
index 80f2817..0000000
--- a/packages/VpnServices/res/values-rm/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servetschs VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectà"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconnectà"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tutgar per reconnectar ad in VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ro/strings.xml b/packages/VpnServices/res/values-ro/strings.xml
deleted file mode 100644
index a22792c..0000000
--- a/packages/VpnServices/res/values-ro/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicii VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectat"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconectat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Atingeţi pentru a vă reconecta la o reţea VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ru/strings.xml b/packages/VpnServices/res/values-ru/strings.xml
deleted file mode 100644
index 8a839c3..0000000
--- a/packages/VpnServices/res/values-ru/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Службы VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) подключена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) отключена"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Нажмите, чтобы повторно подключиться к VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sk/strings.xml b/packages/VpnServices/res/values-sk/strings.xml
deleted file mode 100644
index 167b6f3..0000000
--- a/packages/VpnServices/res/values-sk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je pripojená"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojená"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykom sa znova pripojíte k sieti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sl/strings.xml b/packages/VpnServices/res/values-sl/strings.xml
deleted file mode 100644
index c5b72c4..0000000
--- a/packages/VpnServices/res/values-sl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Storitve VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je povezan"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je izklopljen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite se, če želite preklopiti v navidezno zasebno omrežje."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sr/strings.xml b/packages/VpnServices/res/values-sr/strings.xml
deleted file mode 100644
index bfe6cc8..0000000
--- a/packages/VpnServices/res/values-sr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN услуге"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је успостављена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је прекинута"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Додирните да бисте се поново повезали са VPN-ом."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sv/strings.xml b/packages/VpnServices/res/values-sv/strings.xml
deleted file mode 100644
index 24f9f58..0000000
--- a/packages/VpnServices/res/values-sv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjänster"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN anslutet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN frånkopplat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryck här om du vill återansluta till ett VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-th/strings.xml b/packages/VpnServices/res/values-th/strings.xml
deleted file mode 100644
index 3aa9c6e..0000000
--- a/packages/VpnServices/res/values-th/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"บริการ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> เชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> ตัดการเชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"แตะเพื่อเชื่อมต่อกับ VPN อีกครั้ง"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tl/strings.xml b/packages/VpnServices/res/values-tl/strings.xml
deleted file mode 100644
index bd988a1..0000000
--- a/packages/VpnServices/res/values-tl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Mga serbisyo ng VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Galawin upang muling kumonekta sa VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tr/strings.xml b/packages/VpnServices/res/values-tr/strings.xml
deleted file mode 100644
index 8666b35..0000000
--- a/packages/VpnServices/res/values-tr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN Hizmetleri"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlandı"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlantısı kesildi"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Bir VPN\'ye tekrar bağlanmak için dokunun."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-uk/strings.xml b/packages/VpnServices/res/values-uk/strings.xml
deleted file mode 100644
index 208659a..0000000
--- a/packages/VpnServices/res/values-uk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Служби VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> підключ. ч-з VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> роз\'єднано"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Натисн. для повт. з\'єдн. з VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-vi/strings.xml b/packages/VpnServices/res/values-vi/strings.xml
deleted file mode 100644
index 3022c9c..0000000
--- a/packages/VpnServices/res/values-vi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Dịch vụ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Đã kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Đã ngắt kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Chạm để kết nối lại với VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rCN/strings.xml b/packages/VpnServices/res/values-zh-rCN/strings.xml
deleted file mode 100644
index cad08e1..0000000
--- a/packages/VpnServices/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"虚拟专用网服务"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”已连接"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”连接已断开"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"轻触可重新连接到虚拟专用网。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rTW/strings.xml b/packages/VpnServices/res/values-zh-rTW/strings.xml
deleted file mode 100644
index ee5a42b..0000000
--- a/packages/VpnServices/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN 服務"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已連線"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已中斷連線"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"輕觸即可重新連線至 VPN。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values/strings.xml b/packages/VpnServices/res/values/strings.xml
deleted file mode 100755
index d82f52a..0000000
--- a/packages/VpnServices/res/values/strings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Title for the VPN Services activity. -->
- <string name="app_label">VPN Services</string>
-
- <string name="vpn_notification_title_connected"><xliff:g id="profilename">%s</xliff:g> VPN connected</string>
- <string name="vpn_notification_title_disconnected"><xliff:g id="profilename">%s</xliff:g> VPN disconnected</string>
- <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
-</resources>
-
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
deleted file mode 100644
index eeafd5a..0000000
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.vpn;
-
-import android.app.Service;
-import android.content.Intent;
-import android.net.vpn.IVpnService;
-import android.net.vpn.L2tpIpsecProfile;
-import android.net.vpn.L2tpIpsecPskProfile;
-import android.net.vpn.L2tpProfile;
-import android.net.vpn.PptpProfile;
-import android.net.vpn.VpnManager;
-import android.net.vpn.VpnProfile;
-import android.net.vpn.VpnState;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * The service class for managing a VPN connection. It implements the
- * {@link IVpnService} binder interface.
- */
-public class VpnServiceBinder extends Service {
- private static final String TAG = VpnServiceBinder.class.getSimpleName();
- private static final boolean DBG = true;
-
- private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states";
-
- // The actual implementation is delegated to the VpnService class.
- private VpnService<? extends VpnProfile> mService;
-
- // TODO(oam): Test VPN when EFS is enabled (will do later)...
- private static String getStateFilePath() {
- // This call will return the correcu directory whether Encrypted FS is enabled or not
- // Disabled: /data/misc/vpn/.states Enabled: /data/secure/misc/vpn/.states
- return Environment.getSecureDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
- }
-
- private final IBinder mBinder = new IVpnService.Stub() {
- public boolean connect(VpnProfile p, String username, String password) {
- return VpnServiceBinder.this.connect(p, username, password);
- }
-
- public void disconnect() {
- VpnServiceBinder.this.disconnect();
- }
-
- public void checkStatus(VpnProfile p) {
- VpnServiceBinder.this.checkStatus(p);
- }
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
- checkSavedStates();
- }
-
-
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- void saveStates() throws IOException {
- if (DBG) Log.d("VpnServiceBinder", " saving states");
- ObjectOutputStream oos =
- new ObjectOutputStream(new FileOutputStream(getStateFilePath()));
- oos.writeObject(mService);
- oos.close();
- }
-
- void removeStates() {
- try {
- File f = new File(getStateFilePath());
- if (f.exists()) f.delete();
- } catch (Throwable e) {
- if (DBG) Log.d("VpnServiceBinder", " remove states: " + e);
- }
- }
-
- private synchronized boolean connect(final VpnProfile p,
- final String username, final String password) {
- if (mService != null) return false;
- final VpnService s = mService = createService(p);
-
- new Thread(new Runnable() {
- public void run() {
- s.onConnect(username, password);
- }
- }).start();
- return true;
- }
-
- private synchronized void disconnect() {
- if (mService == null) return;
- final VpnService s = mService;
-
- new Thread(new Runnable() {
- public void run() {
- s.onDisconnect();
- }
- }).start();
- }
-
- private synchronized void checkStatus(VpnProfile p) {
- if ((mService == null)
- || (!p.getName().equals(mService.mProfile.getName()))) {
- broadcastConnectivity(p.getName(), VpnState.IDLE);
- } else {
- broadcastConnectivity(p.getName(), mService.getState());
- }
- }
-
- private void checkSavedStates() {
- try {
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
- getStateFilePath()));
- mService = (VpnService<? extends VpnProfile>) ois.readObject();
- mService.recover(this);
- ois.close();
- } catch (FileNotFoundException e) {
- // do nothing
- } catch (Throwable e) {
- Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
- removeStates();
- }
- }
-
- private VpnService<? extends VpnProfile> createService(VpnProfile p) {
- switch (p.getType()) {
- case L2TP:
- L2tpService l2tp = new L2tpService();
- l2tp.setContext(this, (L2tpProfile) p);
- return l2tp;
-
- case PPTP:
- PptpService pptp = new PptpService();
- pptp.setContext(this, (PptpProfile) p);
- return pptp;
-
- case L2TP_IPSEC_PSK:
- L2tpIpsecPskService psk = new L2tpIpsecPskService();
- psk.setContext(this, (L2tpIpsecPskProfile) p);
- return psk;
-
- case L2TP_IPSEC:
- L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
- l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
- return l2tpIpsec;
-
- default:
- return null;
- }
- }
-
- private void broadcastConnectivity(String name, VpnState s) {
- new VpnManager(this).broadcastConnectivity(name, s);
- }
-}
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index eb4d930..5b80a93 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -100,17 +100,27 @@
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
+ // TODO: re-enable on phones with keyboards
+ final boolean isPhysicalKbShowing = false;
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mKeyboardViewAlpha = (PasswordEntryKeyboardView) findViewById(R.id.keyboardAlpha);
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ if (mIsAlpha && !isPhysicalKbShowing) {
+ mKeyboardViewAlpha.setVisibility(
+ mKeyboardViewAlpha.getVisibility() == View.VISIBLE
+ ? View.GONE : View.VISIBLE);
+ mCallback.pokeWakelock();
+ }
+ }
+ });
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
mEmergencyCallButton.setOnClickListener(this);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
- // TODO: re-enable on phones with keyboards
- boolean isPhysicalKbShowing = false;
//mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
if (mKeyboardViewAlpha == null || !mIsAlpha) {
mKeyboardHelper.setKeyboardMode(mIsAlpha ?
@@ -123,24 +133,21 @@
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
mKeyboardView.setVisibility(View.GONE);
- mKeyboardViewAlpha.setVisibility(isPhysicalKbShowing ? View.INVISIBLE : View.VISIBLE);
mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width);
}
- 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
// numeric keys.
if (mIsAlpha) {
mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
- StatusView.LOCK_ICON);
+ // mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
+ // StatusView.LOCK_ICON);
} else {
mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
- StatusView.LOCK_ICON);
+ //mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
+ // StatusView.LOCK_ICON);
}
mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 8e9a5a4..2e83256 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -744,7 +744,7 @@
}
uint32_t SwitchInputMapper::getSources() {
- return 0;
+ return AINPUT_SOURCE_SWITCH;
}
void SwitchInputMapper::process(const RawEvent* rawEvent) {
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 775747c..98d627d 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -1484,7 +1484,7 @@
SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
addMapperAndConfigure(mapper);
- ASSERT_EQ(uint32_t(0), mapper->getSources());
+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
}
TEST_F(SwitchInputMapperTest, GetSwitchState) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 2321e30..bd3c554 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -32,6 +32,7 @@
import android.net.NetworkUtils;
import android.net.Proxy;
import android.net.ProxyProperties;
+import android.net.vpn.VpnManager;
import android.net.wifi.WifiStateTracker;
import android.os.Binder;
import android.os.Handler;
@@ -442,6 +443,8 @@
mSettingsObserver.observe(mContext);
loadGlobalProxy();
+
+ VpnManager.startVpnService(context);
}
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index 418e7f8..3abfc12 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -34,9 +34,9 @@
RotationVectorSensor::RotationVectorSensor(sensor_t const* list, size_t count)
: mSensorDevice(SensorDevice::getInstance()),
- mALowPass(M_SQRT1_2, 5.0f),
+ mALowPass(M_SQRT1_2, 1.5f),
mAX(mALowPass), mAY(mALowPass), mAZ(mALowPass),
- mMLowPass(M_SQRT1_2, 2.5f),
+ mMLowPass(M_SQRT1_2, 1.5f),
mMX(mMLowPass), mMY(mMLowPass), mMZ(mMLowPass)
{
for (size_t i=0 ; i<count ; i++) {
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index b7c9512..17699f8 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -38,9 +38,9 @@
double mAccTime;
double mMagTime;
SecondOrderLowPassFilter mALowPass;
- BiquadFilter mAX, mAY, mAZ;
+ CascadedBiquadFilter mAX, mAY, mAZ;
SecondOrderLowPassFilter mMLowPass;
- BiquadFilter mMX, mMY, mMZ;
+ CascadedBiquadFilter mMX, mMY, mMZ;
public:
RotationVectorSensor(sensor_t const* list, size_t count);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index b2d2a98..39a4614 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -122,6 +122,8 @@
ignoreResultList.add("storage/indexeddb"); // indexeddb not supported
ignoreResultList.add("storage/private-browsing-readonly.html"); // private browsing not supported
ignoreResultList.add("websocket/tests/workers"); // workers not supported
+ ignoreResultList.add("dom/xhtml/level2/html/htmldocument04.xhtml"); // /mnt/sdcard on SR uses lowercase filesystem, this test checks filename and is case senstive.
+ ignoreResultList.add("dom/html/level2/html/htmldocument04.html"); // ditto
// Expected failures due to missing expected results
ignoreResultList.add("dom/xhtml/level3/core/canonicalform08.xhtml");
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index a3466e2..9c4fa97 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -37,6 +37,7 @@
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.ConsoleMessage;
+import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
@@ -827,6 +828,7 @@
setDefaultWebSettings(mWebView);
mIsGeolocationPermissionSet = false;
mPendingGeolocationPermissionCallbacks = null;
+ CookieManager.getInstance().removeAllCookie();
}
private long[] getDrawWebViewTime(WebView view, int count) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 7a61b3c..1d67964 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -25,6 +25,15 @@
android:hardwareAccelerated="true">
<activity
+ android:name="ShapesActivity"
+ android:label="_Shapes">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="SimplePatchActivity"
android:label="_SimplePatch"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
new file mode 100644
index 0000000..536a669
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ShapesActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(new ShapesView(this));
+ }
+
+ static class ShapesView extends View {
+ private Paint mNormalPaint;
+ private Paint mStrokePaint;
+ private Paint mFillPaint;
+ private RectF mRect;
+
+ ShapesView(Context c) {
+ super(c);
+
+ mRect = new RectF(0.0f, 0.0f, 160.0f, 90.0f);
+
+ mNormalPaint = new Paint();
+ mNormalPaint.setAntiAlias(true);
+ mNormalPaint.setColor(0xff0000ff);
+ mNormalPaint.setStrokeWidth(6.0f);
+ mNormalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+
+ mStrokePaint = new Paint();
+ mStrokePaint.setAntiAlias(true);
+ mStrokePaint.setColor(0xff0000ff);
+ mStrokePaint.setStrokeWidth(6.0f);
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+
+ mFillPaint = new Paint();
+ mFillPaint.setAntiAlias(true);
+ mFillPaint.setColor(0xff0000ff);
+ mFillPaint.setStyle(Paint.Style.FILL);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.translate(50.0f, 50.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mFillPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(250.0f, 50.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mFillPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
index fedccb0..6bf3edd 100644
--- a/vpn/java/android/net/vpn/IVpnService.aidl
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -24,10 +24,11 @@
*/
interface IVpnService {
/**
- * Sets up the VPN connection.
+ * Sets up a VPN connection.
* @param profile the profile object
* @param username the username for authentication
* @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
*/
boolean connect(in VpnProfile profile, String username, String password);
@@ -37,7 +38,13 @@
void disconnect();
/**
- * Makes the service broadcast the connectivity state.
+ * Gets the the current connection state.
*/
- void checkStatus(in VpnProfile profile);
+ String getState(in VpnProfile profile);
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ boolean isIdle();
}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce40b5d..02486bb 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -16,17 +16,19 @@
package android.net.vpn;
-import java.io.File;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.os.Environment;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.util.Log;
+import com.android.server.vpn.VpnServiceBinder;
+
/**
* The class provides interface to manage all VPN-related tasks, including:
* <ul>
@@ -40,8 +42,6 @@
* {@hide}
*/
public class VpnManager {
- // Action for broadcasting a connectivity state.
- private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
/** Key to the profile name of a connectivity broadcast event. */
public static final String BROADCAST_PROFILE_NAME = "profile_name";
/** Key to the connectivity state of a connectivity broadcast event. */
@@ -74,8 +74,10 @@
private static final String PACKAGE_PREFIX =
VpnManager.class.getPackage().getName() + ".";
- // Action to start VPN service
- private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
+ // Action for broadcasting a connectivity state.
+ private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+
+ private static final String VPN_SERVICE_NAME = "vpn";
// Action to start VPN settings
private static final String ACTION_VPN_SETTINGS =
@@ -96,13 +98,76 @@
return VpnType.values();
}
+ public static void startVpnService(Context c) {
+ ServiceManager.addService(VPN_SERVICE_NAME, new VpnServiceBinder(c));
+ }
+
private Context mContext;
+ private IVpnService mVpnService;
/**
* Creates a manager object with the specified context.
*/
public VpnManager(Context c) {
mContext = c;
+ createVpnServiceClient();
+ }
+
+ private void createVpnServiceClient() {
+ IBinder b = ServiceManager.getService(VPN_SERVICE_NAME);
+ mVpnService = IVpnService.Stub.asInterface(b);
+ }
+
+ /**
+ * Sets up a VPN connection.
+ * @param profile the profile object
+ * @param username the username for authentication
+ * @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
+ */
+ public boolean connect(VpnProfile p, String username, String password) {
+ try {
+ return mVpnService.connect(p, username, password);
+ } catch (RemoteException e) {
+ Log.e(TAG, "connect()", e);
+ return false;
+ }
+ }
+
+ /**
+ * Tears down the VPN connection.
+ */
+ public void disconnect() {
+ try {
+ mVpnService.disconnect();
+ } catch (RemoteException e) {
+ Log.e(TAG, "disconnect()", e);
+ }
+ }
+
+ /**
+ * Gets the the current connection state.
+ */
+ public VpnState getState(VpnProfile p) {
+ try {
+ return Enum.valueOf(VpnState.class, mVpnService.getState(p));
+ } catch (RemoteException e) {
+ Log.e(TAG, "getState()", e);
+ return VpnState.IDLE;
+ }
+ }
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ public boolean isIdle() {
+ try {
+ return mVpnService.isIdle();
+ } catch (RemoteException e) {
+ Log.e(TAG, "isIdle()", e);
+ return true;
+ }
}
/**
@@ -134,33 +199,6 @@
}
}
- /**
- * Starts the VPN service to establish VPN connection.
- */
- public void startVpnService() {
- mContext.startService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Stops the VPN service.
- */
- public void stopVpnService() {
- mContext.stopService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Binds the specified ServiceConnection with the VPN service.
- */
- public boolean bindVpnService(ServiceConnection c) {
- if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
- Log.w(TAG, "failed to connect to VPN service");
- return false;
- } else {
- Log.d(TAG, "succeeded to connect to VPN service");
- return true;
- }
- }
-
/** Broadcasts the connectivity state of the specified profile. */
public void broadcastConnectivity(String profileName, VpnState s) {
broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR);
diff --git a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java b/vpn/java/com/android/server/vpn/DaemonProxy.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
rename to vpn/java/com/android/server/vpn/DaemonProxy.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
rename to vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
rename to vpn/java/com/android/server/vpn/L2tpIpsecService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java b/vpn/java/com/android/server/vpn/L2tpService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpService.java
rename to vpn/java/com/android/server/vpn/L2tpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/PptpService.java b/vpn/java/com/android/server/vpn/PptpService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/PptpService.java
rename to vpn/java/com/android/server/vpn/PptpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java b/vpn/java/com/android/server/vpn/VpnConnectingError.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java
rename to vpn/java/com/android/server/vpn/VpnConnectingError.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java b/vpn/java/com/android/server/vpn/VpnDaemons.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java
rename to vpn/java/com/android/server/vpn/VpnDaemons.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/vpn/java/com/android/server/vpn/VpnService.java
similarity index 94%
rename from packages/VpnServices/src/com/android/server/vpn/VpnService.java
rename to vpn/java/com/android/server/vpn/VpnService.java
index a618423..4966c06 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/vpn/java/com/android/server/vpn/VpnService.java
@@ -27,8 +27,9 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
+
import java.io.IOException;
-import java.io.Serializable;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -37,8 +38,7 @@
/**
* The service base class for managing a type of VPN connection.
*/
-abstract class VpnService<E extends VpnProfile> implements Serializable {
- static final long serialVersionUID = 1L;
+abstract class VpnService<E extends VpnProfile> {
private static final boolean DBG = true;
private static final int NOTIFICATION_ID = 1;
@@ -55,10 +55,8 @@
private final String TAG = VpnService.class.getSimpleName();
- // FIXME: profile is only needed in connecting phase, so we can just save
- // the profile name and service class name for recovery
E mProfile;
- transient VpnServiceBinder mContext;
+ transient Context mContext;
private VpnState mState = VpnState.IDLE;
private Throwable mError;
@@ -105,12 +103,8 @@
return InetAddress.getByName(hostName).getHostAddress();
}
- void setContext(VpnServiceBinder context, E profile) {
+ void setContext(Context context, E profile) {
mProfile = profile;
- recover(context);
- }
-
- void recover(VpnServiceBinder context) {
mContext = context;
mNotification = new NotificationHelper();
@@ -124,6 +118,10 @@
return mState;
}
+ boolean isIdle() {
+ return (mState == VpnState.IDLE);
+ }
+
synchronized boolean onConnect(String username, String password) {
try {
setState(VpnState.CONNECTING);
@@ -216,21 +214,12 @@
mStartTime = System.currentTimeMillis();
- // Correct order to make sure VpnService doesn't break when killed:
- // (1) set state to CONNECTED
- // (2) save states
- // (3) set DNS
setState(VpnState.CONNECTED);
- saveSelf();
setVpnDns();
startConnectivityMonitor();
}
- private void saveSelf() throws IOException {
- mContext.saveStates();
- }
-
private synchronized void onFinalCleanUp() {
if (DBG) Log.d(TAG, "onFinalCleanUp()");
@@ -243,10 +232,7 @@
restoreOriginalDomainSuffices();
setState(VpnState.IDLE);
- // stop the service itself
SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
- mContext.removeStates();
- mContext.stopSelf();
}
private boolean anyError() {
@@ -413,9 +399,6 @@
}
}
- private class DaemonHelper implements Serializable {
- }
-
// Helper class for showing, updating notification.
private class NotificationHelper {
private NotificationManager mNotificationManager = (NotificationManager)
diff --git a/vpn/java/com/android/server/vpn/VpnServiceBinder.java b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
new file mode 100644
index 0000000..c474ff9
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.IVpnService;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.util.Log;
+
+/**
+ * The service class for managing a VPN connection. It implements the
+ * {@link IVpnService} binder interface.
+ */
+public class VpnServiceBinder extends IVpnService.Stub {
+ private static final String TAG = VpnServiceBinder.class.getSimpleName();
+ private static final boolean DBG = true;
+
+ // The actual implementation is delegated to the VpnService class.
+ private VpnService<? extends VpnProfile> mService;
+
+ private Context mContext;
+
+ public VpnServiceBinder(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public synchronized boolean connect(VpnProfile p, final String username,
+ final String password) {
+ if ((mService != null) && !mService.isIdle()) return false;
+ final VpnService s = mService = createService(p);
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onConnect(username, password);
+ }
+ }).start();
+ return true;
+ }
+
+ @Override
+ public synchronized void disconnect() {
+ if (mService == null) return;
+ final VpnService s = mService;
+ mService = null;
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onDisconnect();
+ }
+ }).start();
+ }
+
+ @Override
+ public synchronized String getState(VpnProfile p) {
+ if ((mService == null)
+ || (!p.getName().equals(mService.mProfile.getName()))) {
+ return VpnState.IDLE.toString();
+ } else {
+ return mService.getState().toString();
+ }
+ }
+
+ @Override
+ public synchronized boolean isIdle() {
+ return (mService == null || mService.isIdle());
+ }
+
+ private VpnService<? extends VpnProfile> createService(VpnProfile p) {
+ switch (p.getType()) {
+ case L2TP:
+ L2tpService l2tp = new L2tpService();
+ l2tp.setContext(mContext, (L2tpProfile) p);
+ return l2tp;
+
+ case PPTP:
+ PptpService pptp = new PptpService();
+ pptp.setContext(mContext, (PptpProfile) p);
+ return pptp;
+
+ case L2TP_IPSEC_PSK:
+ L2tpIpsecPskService psk = new L2tpIpsecPskService();
+ psk.setContext(mContext, (L2tpIpsecPskProfile) p);
+ return psk;
+
+ case L2TP_IPSEC:
+ L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
+ l2tpIpsec.setContext(mContext, (L2tpIpsecProfile) p);
+ return l2tpIpsec;
+
+ default:
+ return null;
+ }
+ }
+}