summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/Process.java6
-rw-r--r--core/java/android/provider/CalendarContract.java4
-rw-r--r--core/java/android/text/SpannableStringBuilder.java20
-rw-r--r--core/java/android/view/Surface.java9
-rw-r--r--core/java/android/view/WindowManager.java6
-rw-r--r--core/java/android/widget/RemoteViews.java33
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java6
-rw-r--r--core/jni/android_view_Surface.cpp14
-rw-r--r--core/res/res/anim/activity_close_enter.xml9
-rw-r--r--core/res/res/anim/activity_close_exit.xml10
-rw-r--r--core/res/res/anim/activity_open_enter.xml10
-rw-r--r--core/res/res/anim/activity_open_exit.xml11
-rw-r--r--core/res/res/anim/lock_screen_behind_enter.xml8
-rw-r--r--core/res/res/anim/lock_screen_exit.xml4
-rw-r--r--core/res/res/anim/lock_screen_wallpaper_behind_enter.xml8
-rw-r--r--core/res/res/anim/task_close_enter.xml21
-rw-r--r--core/res/res/anim/task_close_exit.xml27
-rw-r--r--core/res/res/anim/task_open_enter.xml10
-rw-r--r--core/res/res/anim/task_open_exit.xml17
-rw-r--r--core/res/res/anim/wallpaper_close_enter.xml12
-rw-r--r--core/res/res/anim/wallpaper_close_exit.xml13
-rw-r--r--core/res/res/anim/wallpaper_open_enter.xml11
-rw-r--r--core/res/res/anim/wallpaper_open_exit.xml13
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_activated.pngbin0 -> 12152 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_focused.pngbin0 -> 22219 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_normal.pngbin0 -> 12262 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_activated.pngbin0 -> 7057 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_focused.pngbin0 -> 11446 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_normal.pngbin0 -> 6519 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.pngbin0 -> 17254 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.pngbin0 -> 31637 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.pngbin0 -> 18528 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.pngbin3053 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.pngbin3053 -> 0 bytes
-rw-r--r--core/res/res/drawable/ic_lockscreen_search.xml4
-rwxr-xr-xcore/res/res/values/attrs.xml3
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_french.kcm336
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm339
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_german.kcm6
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_russian.kcm396
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm407
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_spanish.kcm329
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_swiss_french.kcm334
-rw-r--r--packages/InputDevices/res/raw/keyboard_layout_swiss_german.kcm334
-rw-r--r--packages/InputDevices/res/values/strings.xml21
-rw-r--r--packages/InputDevices/res/xml/keyboard_layouts.xml28
-rw-r--r--packages/SystemUI/res/drawable/navbar_search_bg_scrim.pngbin0 -> 7955 bytes
-rw-r--r--packages/SystemUI/res/drawable/navbar_search_handle.xml30
-rw-r--r--packages/SystemUI/res/drawable/navbar_search_outerring.xml23
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_search_panel.xml67
-rw-r--r--packages/SystemUI/res/layout-port/status_bar_search_panel.xml67
-rw-r--r--packages/SystemUI/res/values-land/arrays.xml43
-rw-r--r--packages/SystemUI/res/values-port/arrays.xml43
-rw-r--r--packages/SystemUI/res/values/dimens.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java226
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java90
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java97
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java19
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java25
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java29
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java14
66 files changed, 3583 insertions, 184 deletions
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 0ba7b88535c9..1df53e88ca71 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -92,6 +92,12 @@ public class Process {
public static final int MEDIA_UID = 1013;
/**
+ * Defines the UID/GID for the DRM process.
+ * @hide
+ */
+ public static final int DRM_UID = 1019;
+
+ /**
* Defines the GID for the group that allows write access to the SD card.
* @hide
*/
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 593762a61b1f..09bf42bb9170 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -1354,6 +1354,8 @@ public final class CalendarContract {
GUESTS_CAN_INVITE_OTHERS);
DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_MODIFY);
DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, GUESTS_CAN_SEE_GUESTS);
+ DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_PACKAGE);
+ DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, CUSTOM_APP_URI);
DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, ORGANIZER);
DatabaseUtils.cursorStringToContentValuesIfPresent(cursor, cv, _SYNC_ID);
DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DIRTY);
@@ -1556,6 +1558,8 @@ public final class CalendarContract {
* <li>{@link #GUESTS_CAN_MODIFY}</li>
* <li>{@link #GUESTS_CAN_INVITE_OTHERS}</li>
* <li>{@link #GUESTS_CAN_SEE_GUESTS}</li>
+ * <li>{@link #CUSTOM_APP_PACKAGE}</li>
+ * <li>{@link #CUSTOM_APP_URI}</li>
* </ul>
* The following Events columns are writable only by a sync adapter
* <ul>
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index ea9f650009cc..c5e2c42aabb6 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -428,6 +428,12 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
final int origLen = end - start;
final int newLen = tbend - tbstart;
+ if (origLen == 0 && newLen == 0 && !hasNonExclusiveExclusiveSpanAt(tb, tbstart)) {
+ // This is a no-op iif there are no spans in tb that would be added (with a 0-length)
+ // Early exit so that the text watchers do not get notified
+ return this;
+ }
+
TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
sendBeforeTextChanged(textWatchers, start, origLen, newLen);
@@ -470,6 +476,20 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
return this;
}
+ private static boolean hasNonExclusiveExclusiveSpanAt(CharSequence text, int offset) {
+ if (text instanceof Spanned) {
+ Spanned spanned = (Spanned) text;
+ Object[] spans = spanned.getSpans(offset, offset, Object.class);
+ final int length = spans.length;
+ for (int i = 0; i < length; i++) {
+ Object span = spans[i];
+ int flags = spanned.getSpanFlags(span);
+ if (flags != Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) return true;
+ }
+ }
+ return false;
+ }
+
private void sendToSpanWatchers(int replaceStart, int replaceEnd, int nbNewChars) {
for (int i = 0; i < mSpanCountBeforeAdd; i++) {
int spanStart = mSpanStarts[i];
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index eb80290d5991..53af3c56bf21 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -323,6 +323,15 @@ public class Surface implements Parcelable {
return mSurfaceGenerationId;
}
+
+ /**
+ * Whether the consumer of this Surface is running behind the producer;
+ * that is, isConsumerRunningBehind() returns true if the consumer is more
+ * than one buffer ahead of the producer.
+ * @hide
+ */
+ public native boolean isConsumerRunningBehind();
+
/**
* A Canvas class that can handle the compatibility mode. This does two
* things differently.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bc310b02212f..d62f513755f1 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -429,6 +429,12 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23;
/**
+ * Window type: Navigation bar panel (when navigation bar is distinct from status bar)
+ * @hide
+ */
+ public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 2f72e4a727e1..214775ac98f9 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -16,13 +16,7 @@
package android.widget;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
+import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
@@ -40,13 +34,20 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.LayoutInflater.Filter;
import android.view.RemotableViewMethod;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.LayoutInflater.Filter;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
/**
* A class that describes a view hierarchy that can be displayed in
@@ -140,14 +141,18 @@ public class RemoteViews implements Parcelable, Filter {
return;
}
- protected boolean startIntentSafely(Context context, PendingIntent pendingIntent,
+ protected boolean startIntentSafely(View view, PendingIntent pendingIntent,
Intent fillInIntent) {
try {
// TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
+ Context context = view.getContext();
+ ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
+ 0, 0,
+ view.getMeasuredWidth(), view.getMeasuredHeight());
context.startIntentSender(
pendingIntent.getIntentSender(), fillInIntent,
Intent.FLAG_ACTIVITY_NEW_TASK,
- Intent.FLAG_ACTIVITY_NEW_TASK, 0);
+ Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
} catch (IntentSender.SendIntentException e) {
android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e);
return false;
@@ -263,7 +268,7 @@ public class RemoteViews implements Parcelable, Filter {
rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
fillInIntent.setSourceBounds(rect);
- startIntentSafely(v.getContext(), pendingIntent, fillInIntent);
+ startIntentSafely(v, pendingIntent, fillInIntent);
}
};
@@ -341,7 +346,7 @@ public class RemoteViews implements Parcelable, Filter {
final Intent intent = new Intent();
intent.setSourceBounds(rect);
- startIntentSafely(view.getContext(), pendingIntentTemplate, fillInIntent);
+ startIntentSafely(view, pendingIntentTemplate, fillInIntent);
}
}
};
@@ -479,7 +484,7 @@ public class RemoteViews implements Parcelable, Filter {
final Intent intent = new Intent();
intent.setSourceBounds(rect);
- startIntentSafely(v.getContext(), pendingIntent, intent);
+ startIntentSafely(v, pendingIntent, intent);
}
};
}
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index f2b6e45c67a5..624dea80b3db 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -27,7 +27,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -142,6 +141,7 @@ public class MultiWaveView extends View {
private int mTargetResourceId;
private int mTargetDescriptionsResourceId;
private int mDirectionDescriptionsResourceId;
+ private boolean mAlwaysTrackFinger;
public MultiWaveView(Context context) {
this(context, null);
@@ -168,6 +168,7 @@ public class MultiWaveView extends View {
mTapRadius = mHandleDrawable.getWidth()/2;
mOuterRing = new TargetDrawable(res,
a.peekValue(R.styleable.MultiWaveView_waveDrawable).resourceId);
+ mAlwaysTrackFinger = a.getBoolean(R.styleable.MultiWaveView_alwaysTrackFinger, false);
// Read chevron animation drawables
final int chevrons[] = { R.styleable.MultiWaveView_leftChevronDrawable,
@@ -634,7 +635,6 @@ public class MultiWaveView extends View {
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
-
boolean handled = false;
switch (action) {
case MotionEvent.ACTION_DOWN:
@@ -805,7 +805,7 @@ public class MultiWaveView extends View {
final float y = event.getY();
final float dx = x - mWaveCenterX;
final float dy = y - mWaveCenterY;
- if (dist2(dx,dy) <= getScaledTapRadiusSquared()) {
+ if (mAlwaysTrackFinger || dist2(dx,dy) <= getScaledTapRadiusSquared()) {
if (DEBUG) Log.v(TAG, "** Handle HIT");
switchToState(STATE_FIRST_TOUCH, x, y);
moveHandleTo(x, y, false);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 31b914a30ba8..a60467ba9b3b 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -316,6 +316,19 @@ static jboolean Surface_isValid(JNIEnv* env, jobject clazz)
return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE;
}
+static jboolean Surface_isConsumerRunningBehind(JNIEnv* env, jobject clazz)
+{
+ int value = 0;
+ const sp<Surface>& surface(getSurface(env, clazz));
+ if (!Surface::isValid(surface)) {
+ doThrowIAE(env);
+ return 0;
+ }
+ ANativeWindow* anw = static_cast<ANativeWindow *>(surface.get());
+ anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value);
+ return (jboolean)value;
+}
+
static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
{
/* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
@@ -875,6 +888,7 @@ static JNINativeMethod gSurfaceMethods[] = {
{"setFreezeTint", "(I)V", (void*)Surface_setFreezeTint },
{"readFromParcel", "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },
{"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
+ {"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind },
};
void nativeClassInit(JNIEnv* env, jclass clazz)
diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml
index c759a831cf76..84e4a19a23c7 100644
--- a/core/res/res/anim/activity_close_enter.xml
+++ b/core/res/res/anim/activity_close_enter.xml
@@ -20,12 +20,5 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" android:zAdjustment="normal">
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_shortAnimTime"/>
- <scale android:fromXScale=".95" android:toXScale="1.0"
- android:fromYScale=".95" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@interpolator/accelerate_quint"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_shortAnimTime"/>
-
+ android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml
index 384810f2ade3..32f6d3845edf 100644
--- a/core/res/res/anim/activity_close_exit.xml
+++ b/core/res/res/anim/activity_close_exit.xml
@@ -22,11 +22,11 @@
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_shortAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale="1.1"
- android:fromYScale="1.0" android:toYScale="1.1"
+ android:duration="300"/>
+ <scale android:fromXScale="1.0" android:toXScale=".8"
+ android:fromYScale="1.0" android:toYScale=".8"
android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@interpolator/decelerate_quint"
+ android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="@android:integer/config_shortAnimTime"/>
+ android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml
index 744153d97875..c92f00021e6d 100644
--- a/core/res/res/anim/activity_open_enter.xml
+++ b/core/res/res/anim/activity_open_enter.xml
@@ -24,12 +24,12 @@
android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true"
android:fillBefore="false" android:fillAfter="false"
- android:duration="@android:integer/config_shortAnimTime"/>
- <scale android:fromXScale="1.1" android:toXScale="1.0"
- android:fromYScale="1.1" android:toYScale="1.0"
+ android:duration="300"/>
+ <scale android:fromXScale=".8" android:toXScale="1.0"
+ android:fromYScale=".8" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@interpolator/decelerate_quint"
+ android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true"
android:fillBefore="false" android:fillAfter="false"
- android:duration="@android:integer/config_shortAnimTime"/>
+ android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml
index 58e8816a95b9..d7bfe8252193 100644
--- a/core/res/res/anim/activity_open_exit.xml
+++ b/core/res/res/anim/activity_open_exit.xml
@@ -18,15 +18,8 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android" android:zAdjustment="normal">
- <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="false"
- android:duration="@android:integer/config_shortAnimTime"/>
- <scale android:fromXScale="1.0" android:toXScale=".95"
- android:fromYScale="1.0" android:toYScale=".95"
- android:pivotX="50%p" android:pivotY="50%p"
android:interpolator="@interpolator/decelerate_quint"
- android:fillEnabled="true"
- android:fillBefore="false" android:fillAfter="false"
- android:duration="@android:integer/config_shortAnimTime"/>
-
+ android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
index 78b7d29de1ff..cb47b3cd8815 100644
--- a/core/res/res/anim/lock_screen_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -19,14 +19,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false">
- <scale
- android:fromXScale="0.90" android:toXScale="1.0"
- android:fromYScale="0.90" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
- android:fillEnabled="true" android:fillBefore="true"
- android:interpolator="@interpolator/decelerate_cubic"
- android:startOffset="@android:integer/config_shortAnimTime"
- android:duration="@android:integer/config_shortAnimTime" />
<alpha
android:fromAlpha="0.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
diff --git a/core/res/res/anim/lock_screen_exit.xml b/core/res/res/anim/lock_screen_exit.xml
index a186126e5ab6..37383d9d7d17 100644
--- a/core/res/res/anim/lock_screen_exit.xml
+++ b/core/res/res/anim/lock_screen_exit.xml
@@ -22,8 +22,8 @@
android:zAdjustment="top"
android:shareInterpolator="false">
<scale
- android:fromXScale="1.0" android:toXScale="1.15"
- android:fromYScale="1.0" android:toYScale="1.15"
+ android:fromXScale="1.0" android:toXScale="1.10"
+ android:fromYScale="1.0" android:toYScale="1.10"
android:pivotX="50%p" android:pivotY="50%p"
android:fillEnabled="true" android:fillAfter="true"
android:interpolator="@interpolator/accelerate_quint"
diff --git a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
index a354fae2d98b..c29fd1a057ba 100644
--- a/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
+++ b/core/res/res/anim/lock_screen_wallpaper_behind_enter.xml
@@ -19,14 +19,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:detachWallpaper="true" android:shareInterpolator="false">
- <scale
- android:fromXScale="0.95" android:toXScale="1.0"
- android:fromYScale="0.95" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
- android:fillEnabled="true" android:fillBefore="true"
- android:interpolator="@interpolator/decelerate_cubic"
- android:startOffset="@android:integer/config_shortAnimTime"
- android:duration="@android:integer/config_shortAnimTime" />
<alpha
android:fromAlpha="0.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true"
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index b39d551a80ea..dad8c1f05172 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -19,16 +19,21 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
- <scale android:fromXScale="0.95" android:toXScale="1.0"
- android:fromYScale="0.95" android:toYScale="1.0"
+ <alpha android:fromAlpha="0" android:toAlpha="1"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:startOffset="600"
+ android:duration="200"/>
+ <scale android:fromXScale="0.6" android:toXScale="1.0"
+ android:fromYScale="0.6" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="200"
- android:duration="300" />
- <alpha android:fromAlpha="0" android:toAlpha="1.0"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:startOffset="350"
+ android:duration="400" />
+ <translate android:fromYDelta="-100%" android:toYDelta="0"
android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:startOffset="200"
- android:duration="300"/>
+ android:startOffset="350"
+ android:duration="400"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index ffbd38a54534..485c91d6f95f 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -19,17 +19,18 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
- android:interpolator="@interpolator/accelerate_cubic"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="200" />
- <scale android:fromXScale="1.0" android:toXScale="1.2"
- android:fromYScale="1.0" android:toYScale="0.8"
- android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@interpolator/accelerate_quint"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="200" />
- <!-- This is needed to keep the animation running while task_close_enter completes -->
- <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="500" />
+ <scale android:fromXScale="1.0" android:toXScale=".8"
+ android:fromYScale="1.0" android:toYScale=".8"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="300" />
+ <alpha android:fromAlpha="1.0" android:toAlpha="0"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="300"/>
+
+ <!-- This is needed to keep the animation running while task_close_enter completes -->
+ <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+ android:duration="600" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index d64f856895c3..8341806d1f76 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -19,16 +19,16 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
- <scale android:fromXScale="1.2" android:toXScale="1.0"
+ <scale android:fromXScale=".8" android:toXScale="1.0"
android:fromYScale=".8" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="300"
- android:duration="240" />
+ android:interpolator="@interpolator/decelerate_quad"
+ android:startOffset="400"
+ android:duration="300" />
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:startOffset="400"
android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index 19f92c03a665..af1a4a99b114 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -22,14 +22,19 @@
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_cubic"
- android:duration="200"/>
- <scale android:fromXScale="1.0" android:toXScale="0.95"
- android:fromYScale="1.0" android:toYScale="0.95"
+ android:duration="300"/>
+ <scale android:fromXScale="1.0" android:toXScale="0.6"
+ android:fromYScale="1.0" android:toYScale="0.6"
android:pivotX="50%p" android:pivotY="50%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="300" />
+ android:interpolator="@interpolator/accelerate_quad"
+ android:duration="500" />
+ <translate android:fromYDelta="0" android:toYDelta="-100%"
+ android:interpolator="@interpolator/accelerate_quad"
+ android:duration="500"/>
+
<!-- This is needed to keep the animation running while task_open_enter completes -->
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="540" />
+ android:interpolator="@interpolator/accelerate_quad"
+ android:duration="700" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index 1ca5c0cbe784..981923ac4723 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -19,16 +19,14 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" android:zAdjustment="top">
- <scale android:fromXScale="1.2" android:toXScale="1.0"
- android:fromYScale=".8" android:toYScale="1.0"
+ <scale android:fromXScale=".2" android:toXScale="1.0"
+ android:fromYScale=".2" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="300"
- android:duration="240" />
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="300" />
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:interpolator="@interpolator/decelerate_cubic"
android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index 987fd8995d8b..a91eb49c0e61 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -19,17 +19,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:detachWallpaper="true" android:shareInterpolator="false" android:zAdjustment="normal">
- <alpha android:fromAlpha="1.0" android:toAlpha="0"
- android:fillEnabled="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_cubic"
- android:duration="200"/>
- <scale android:fromXScale="1.0" android:toXScale="0.95"
- android:fromYScale="1.0" android:toYScale="0.95"
- android:pivotX="50%p" android:pivotY="50%p"
- android:fillEnabled="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="300" />
- <!-- This is needed to keep the animation running while wallpaper_close_enter completes -->
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="600" />
+ android:duration="300" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index 6fdbd40db848..ee7ab603889a 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -19,16 +19,7 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:detachWallpaper="true" android:shareInterpolator="false" android:zAdjustment="normal">
- <scale android:fromXScale="0.95" android:toXScale="1.0"
- android:fromYScale="0.95" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
+ <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="200"
- android:duration="300" />
- <alpha android:fromAlpha="0" android:toAlpha="1.0"
- android:interpolator="@interpolator/decelerate_cubic"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:startOffset="200"
android:duration="300"/>
</set> \ No newline at end of file
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index 1804fa894a99..8a2582e8eeed 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -20,16 +20,13 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" android:zAdjustment="top">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
- android:interpolator="@interpolator/accelerate_cubic"
+ android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:duration="200" />
- <scale android:fromXScale="1.0" android:toXScale="1.2"
- android:fromYScale="1.0" android:toYScale="0.8"
+ <scale android:fromXScale="1.0" android:toXScale="0.4"
+ android:fromYScale="1.0" android:toYScale="0.4"
android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@interpolator/accelerate_quint"
+ android:interpolator="@interpolator/decelerate_cubic"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="200" />
- <!-- This is needed to keep the animation running while wallpaper_open_enter completes -->
- <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="500" />
+ android:duration="300" />
</set> \ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 000000000000..2c4847c53179
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 000000000000..d98557d5e692
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 000000000000..656f3ba17e0d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 000000000000..32a68e0f28c1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 000000000000..3f96d0379d3d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 000000000000..2f7efcf5e80b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 000000000000..d643f83b36a8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 000000000000..51863f498e68
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 000000000000..9a9bf6800777
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
deleted file mode 100644
index c625a3602bcb..000000000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_search_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
deleted file mode 100644
index c625a3602bcb..000000000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_search_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_lockscreen_search.xml b/core/res/res/drawable/ic_lockscreen_search.xml
index b1039228a4dc..2c0091acc893 100644
--- a/core/res/res/drawable/ic_lockscreen_search.xml
+++ b/core/res/res/drawable/ic_lockscreen_search.xml
@@ -19,12 +19,12 @@
android:state_enabled="true"
android:state_active="false"
android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_search_normal" />
+ android:drawable="@drawable/ic_lockscreen_google_normal" />
<item
android:state_enabled="true"
android:state_active="true"
android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_search_activated" />
+ android:drawable="@drawable/ic_lockscreen_google_activated" />
</selector>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0ac381d2b59e..9fa666e629fd 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5383,6 +5383,9 @@
<!-- Used to shift center of pattern horizontally. -->
<attr name="horizontalOffset" format="dimension" />
+
+ <!-- Used when the handle shouldn't wait to be hit before following the finger -->
+ <attr name="alwaysTrackFinger" format="boolean" />
</declare-styleable>
<!-- =============================== -->
diff --git a/packages/InputDevices/res/raw/keyboard_layout_french.kcm b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
new file mode 100644
index 000000000000..89e83dab372e
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
@@ -0,0 +1,336 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# French keyboard layout, AZERTY style.
+#
+
+type OVERLAY
+
+map key 16 A
+map key 17 Z
+map key 30 Q
+map key 39 M
+map key 44 W
+map key 50 COMMA
+map key 51 SEMICOLON
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '\u00b2'
+ base: '\u00b2'
+}
+
+key 1 {
+ label: '1'
+ base: '&'
+ shift: '1'
+}
+
+key 2 {
+ label: '2'
+ base: '\u00e9'
+ shift: '2'
+ ralt: '~'
+}
+
+key 3 {
+ label: '3'
+ base: '"'
+ shift: '3'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '\''
+ shift: '4'
+ ralt: '{'
+}
+
+key 5 {
+ label: '5'
+ base: '('
+ shift: '5'
+ ralt: '['
+}
+
+key 6 {
+ label: '6'
+ base: '-'
+ shift: '6'
+ ralt: '|'
+}
+
+key 7 {
+ label: '7'
+ base: '\u00e8'
+ shift: '7'
+ ralt: '`'
+}
+
+key 8 {
+ label: '8'
+ base: '_'
+ shift: '8'
+ ralt: '\\'
+}
+
+key 9 {
+ label: '9'
+ base: '\u00e7'
+ shift: '9'
+ ralt: '^'
+}
+
+key 0 {
+ label: '0'
+ base: '\u00e0'
+ shift: '0'
+ ralt: '@'
+}
+
+key MINUS {
+ label: ')'
+ base: ')'
+ shift: '\u00b0'
+ ralt: ']'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+ ralt: '}'
+}
+
+### ROW 2
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u02c6'
+ base: '\u0302'
+ shift: '\u0308'
+}
+
+key RIGHT_BRACKET {
+ label: '$'
+ base: '$'
+ shift: '\u00a3'
+ ralt: '\u00a4'
+}
+
+### ROW 3
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key APOSTROPHE {
+ label: '\u00f9'
+ base: '\u00f9'
+ shift: '%'
+}
+
+key BACKSLASH {
+ label: '*'
+ base: '*'
+ shift: '\u00b5'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '<'
+ base: '<'
+ shift: '>'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '?'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: '.'
+}
+
+key PERIOD {
+ label: ':'
+ base: ':'
+ shift: '/'
+}
+
+key SLASH {
+ label: '!'
+ base: '!'
+ shift: '\u00a7'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm b/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm
new file mode 100644
index 000000000000..55ddd6096eff
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_french_ca.kcm
@@ -0,0 +1,339 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# French (Canada) keyboard layout.
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '#'
+ base: '#'
+ shift: '|'
+ ralt: '\\'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+ ralt: '\u00b1'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '/'
+ ralt: '\u00a3'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+ ralt: '\u00a2'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+ ralt: '\u00a4'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '?'
+ ralt: '\u00ac'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '&'
+ ralt: '\u00a6'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+ ralt: '\u00b2'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+ ralt: '\u00b3'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+ ralt: '\u00bc'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+ ralt: '\u00bd'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+ ralt: '\u00be'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+ ralt: '\u00a7'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+ ralt: '\u00b6'
+}
+
+key LEFT_BRACKET {
+ label: '\u02c6'
+ base: '\u0302'
+ ralt: '['
+}
+
+key RIGHT_BRACKET {
+ label: '\u00b8'
+ base: '\u0327'
+ shift: '\u0308'
+ ralt: ']'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: ';'
+ base: ';'
+ shift: ':'
+ ralt: '~'
+}
+
+key APOSTROPHE {
+ label: '\u02cb'
+ base: '\u0300'
+ ralt: '{'
+}
+
+key BACKSLASH {
+ label: '<'
+ base: '<'
+ shift: '>'
+ ralt: '}'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '\u00ab'
+ base: '\u00ab'
+ shift: '\u00bb'
+ ralt: '\u00b0'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+ ralt: '\u00b5'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: '\''
+ ralt: '_'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ ralt: '-'
+}
+
+key SLASH {
+ label: '\u00c9'
+ base: '\u00e9'
+ shift, capslock: '\u00c9'
+ ralt: '\u0301'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
index 9c7597308c8c..d9caa32c81fe 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_german.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
@@ -178,7 +178,7 @@ key P {
key LEFT_BRACKET {
label: '\u00dc'
base: '\u00fc'
- shift: '\u00dc'
+ shift, capslock: '\u00dc'
}
key RIGHT_BRACKET {
@@ -247,13 +247,13 @@ key L {
key SEMICOLON {
label: '\u00d6'
base: '\u00f6'
- shift: '\u00d6'
+ shift, capslock: '\u00d6'
}
key APOSTROPHE {
label: '\u00c4'
base: '\u00e4'
- shift: '\u00c4'
+ shift, capslock: '\u00c4'
}
key BACKSLASH {
diff --git a/packages/InputDevices/res/raw/keyboard_layout_russian.kcm b/packages/InputDevices/res/raw/keyboard_layout_russian.kcm
new file mode 100644
index 000000000000..73646d2288d6
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_russian.kcm
@@ -0,0 +1,396 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Russian keyboard layout.
+# This is a typical Russian PC keyboard layout.
+# English characters are accessible using ralt (Alt Gr).
+#
+
+type OVERLAY
+
+map key 86 BACKSLASH
+
+### ROW 1
+
+key GRAVE {
+ label: '\u0401'
+ base: '\u0451'
+ shift, capslock: '\u0401'
+ ralt: '`'
+ ralt+shift: '~'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+ ralt: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '\u2116'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: ';'
+ ralt: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+ ralt: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: ':'
+ ralt: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '?'
+ ralt: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '*'
+ ralt: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+ ralt: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+ ralt: ')'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+ ralt: '-'
+ ralt+shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+ ralt: '='
+ ralt+shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: '\u0419'
+ base: '\u0439'
+ shift, capslock: '\u0419'
+ ralt: 'q'
+ ralt+shift, ralt+capslock: 'Q'
+}
+
+key W {
+ label: '\u0426'
+ base: '\u0446'
+ shift, capslock: '\u0426'
+ ralt: 'w'
+ ralt+shift, ralt+capslock: 'W'
+}
+
+key E {
+ label: '\u0423'
+ base: '\u0443'
+ shift, capslock: '\u0423'
+ ralt: 'e'
+ ralt+shift, ralt+capslock: 'E'
+}
+
+key R {
+ label: '\u041a'
+ base: '\u043a'
+ shift, capslock: '\u041a'
+ ralt: 'r'
+ ralt+shift, ralt+capslock: 'R'
+}
+
+key T {
+ label: '\u0415'
+ base: '\u0435'
+ shift, capslock: '\u0415'
+ ralt: 't'
+ ralt+shift, ralt+capslock: 'T'
+}
+
+key Y {
+ label: '\u041d'
+ base: '\u043d'
+ shift, capslock: '\u041d'
+ ralt: 'y'
+ ralt+shift, ralt+capslock: 'Y'
+}
+
+key U {
+ label: '\u0413'
+ base: '\u0433'
+ shift, capslock: '\u0413'
+ ralt: 'u'
+ ralt+shift, ralt+capslock: 'U'
+}
+
+key I {
+ label: '\u0428'
+ base: '\u0448'
+ shift, capslock: '\u0428'
+ ralt: 'i'
+ ralt+shift, ralt+capslock: 'I'
+}
+
+key O {
+ label: '\u0429'
+ base: '\u0449'
+ shift, capslock: '\u0429'
+ ralt: 'o'
+ ralt+shift, ralt+capslock: 'O'
+}
+
+key P {
+ label: '\u0417'
+ base: '\u0437'
+ shift, capslock: '\u0417'
+ ralt: 'p'
+ ralt+shift, ralt+capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u0425'
+ base: '\u0445'
+ shift, capslock: '\u0425'
+ ralt: '['
+ ralt+shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: '\u042a'
+ base: '\u044a'
+ shift, capslock: '\u042a'
+ ralt: ']'
+ ralt+shift: '}'
+}
+
+### ROW 3
+
+key A {
+ label: '\u0424'
+ base: '\u0444'
+ shift, capslock: '\u0424'
+ ralt: 'a'
+ ralt+shift, ralt+capslock: 'A'
+}
+
+key S {
+ label: '\u042b'
+ base: '\u044b'
+ shift, capslock: '\u042b'
+ ralt: 's'
+ ralt+shift, ralt+capslock: 'S'
+}
+
+key D {
+ label: '\u0412'
+ base: '\u0432'
+ shift, capslock: '\u0412'
+ ralt: 'd'
+ ralt+shift, ralt+capslock: 'D'
+}
+
+key F {
+ label: '\u0410'
+ base: '\u0430'
+ shift, capslock: '\u0410'
+ ralt: 'f'
+ ralt+shift, ralt+capslock: 'F'
+}
+
+key G {
+ label: '\u041f'
+ base: '\u043f'
+ shift, capslock: '\u041f'
+ ralt: 'g'
+ ralt+shift, ralt+capslock: 'G'
+}
+
+key H {
+ label: '\u0420'
+ base: '\u0440'
+ shift, capslock: '\u0420'
+ ralt: 'h'
+ ralt+shift, ralt+capslock: 'H'
+}
+
+key J {
+ label: '\u041e'
+ base: '\u043e'
+ shift, capslock: '\u041e'
+ ralt: 'j'
+ ralt+shift, ralt+capslock: 'J'
+}
+
+key K {
+ label: '\u041b'
+ base: '\u043b'
+ shift, capslock: '\u041b'
+ ralt: 'k'
+ ralt+shift, ralt+capslock: 'K'
+}
+
+key L {
+ label: '\u0414'
+ base: '\u0434'
+ shift, capslock: '\u0414'
+ ralt: 'l'
+ ralt+shift, ralt+capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u0416'
+ base: '\u0436'
+ shift, capslock: '\u0416'
+ ralt: ';'
+ ralt+shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\u042d'
+ base: '\u044d'
+ shift, capslock: '\u042d'
+ ralt: '\''
+ ralt+shift: '"'
+}
+
+key BACKSLASH {
+ label: '\\'
+ base: '\\'
+ shift: '/'
+ ralt: '|'
+}
+
+### ROW 4
+
+key Z {
+ label: '\u042f'
+ base: '\u044f'
+ shift, capslock: '\u042f'
+ ralt: 'z'
+ ralt+shift, ralt+capslock: 'Z'
+}
+
+key X {
+ label: '\u0427'
+ base: '\u0447'
+ shift, capslock: '\u0427'
+ ralt: 'x'
+ ralt+shift, ralt+capslock: 'X'
+}
+
+key C {
+ label: '\u0421'
+ base: '\u0441'
+ shift, capslock: '\u0421'
+ ralt: 'c'
+ ralt+shift, ralt+capslock: 'C'
+}
+
+key V {
+ label: '\u041c'
+ base: '\u043c'
+ shift, capslock: '\u041c'
+ ralt: 'v'
+ ralt+shift, ralt+capslock: 'V'
+}
+
+key B {
+ label: '\u0418'
+ base: '\u0438'
+ shift, capslock: '\u0418'
+ ralt: 'b'
+ ralt+shift, ralt+capslock: 'B'
+}
+
+key N {
+ label: '\u0422'
+ base: '\u0442'
+ shift, capslock: '\u0422'
+ ralt: 'n'
+ ralt+shift, ralt+capslock: 'N'
+}
+
+key M {
+ label: '\u042c'
+ base: '\u044c'
+ shift, capslock: '\u042c'
+ ralt: 'm'
+ ralt+shift, ralt+capslock: 'M'
+}
+
+key COMMA {
+ label: '\u0411'
+ base: '\u0431'
+ shift, capslock: '\u0411'
+ ralt: ','
+ ralt+shift: '<'
+}
+
+key PERIOD {
+ label: '\u042e'
+ base: '\u044e'
+ shift, capslock: '\u042e'
+ ralt: '.'
+ ralt+shift: '>'
+}
+
+key SLASH {
+ label: '.'
+ base: '.'
+ shift: ','
+ ralt: '/'
+ ralt+shift: '?'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm b/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm
new file mode 100644
index 000000000000..18893fe530e2
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm
@@ -0,0 +1,407 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Russian keyboard layout.
+# This is a variant of the typical Russian PC keyboard layout that is presented
+# on Apple keyboards. In contrast with the standard layout, some of the symbols and
+# punctuation characters have been rearranged.
+# English characters are accessible using ralt (Alt Gr).
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '>'
+ base: '>'
+ shift: '<'
+ ralt: '\u00a7'
+ ralt+shift: '\u00b1'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+ ralt: '!'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '\u2116'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '%'
+ ralt: '$'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: ':'
+ ralt: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: ','
+ ralt: '^'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '.'
+ ralt: '&'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: ';'
+ ralt: '*'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: '('
+ ralt: '('
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: ')'
+ ralt: ')'
+}
+
+key MINUS {
+ label: '-'
+ base: '-'
+ shift: '_'
+ ralt: '-'
+ ralt+shift: '_'
+}
+
+key EQUALS {
+ label: '='
+ base: '='
+ shift: '+'
+ ralt: '='
+ ralt+shift: '+'
+}
+
+### ROW 2
+
+key Q {
+ label: '\u0419'
+ base: '\u0439'
+ shift, capslock: '\u0419'
+ ralt: 'q'
+ ralt+shift, ralt+capslock: 'Q'
+}
+
+key W {
+ label: '\u0426'
+ base: '\u0446'
+ shift, capslock: '\u0426'
+ ralt: 'w'
+ ralt+shift, ralt+capslock: 'W'
+}
+
+key E {
+ label: '\u0423'
+ base: '\u0443'
+ shift, capslock: '\u0423'
+ ralt: 'e'
+ ralt+shift, ralt+capslock: 'E'
+}
+
+key R {
+ label: '\u041a'
+ base: '\u043a'
+ shift, capslock: '\u041a'
+ ralt: 'r'
+ ralt+shift, ralt+capslock: 'R'
+}
+
+key T {
+ label: '\u0415'
+ base: '\u0435'
+ shift, capslock: '\u0415'
+ ralt: 't'
+ ralt+shift, ralt+capslock: 'T'
+}
+
+key Y {
+ label: '\u041d'
+ base: '\u043d'
+ shift, capslock: '\u041d'
+ ralt: 'y'
+ ralt+shift, ralt+capslock: 'Y'
+}
+
+key U {
+ label: '\u0413'
+ base: '\u0433'
+ shift, capslock: '\u0413'
+ ralt: 'u'
+ ralt+shift, ralt+capslock: 'U'
+}
+
+key I {
+ label: '\u0428'
+ base: '\u0448'
+ shift, capslock: '\u0428'
+ ralt: 'i'
+ ralt+shift, ralt+capslock: 'I'
+}
+
+key O {
+ label: '\u0429'
+ base: '\u0449'
+ shift, capslock: '\u0429'
+ ralt: 'o'
+ ralt+shift, ralt+capslock: 'O'
+}
+
+key P {
+ label: '\u0417'
+ base: '\u0437'
+ shift, capslock: '\u0417'
+ ralt: 'p'
+ ralt+shift, ralt+capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u0425'
+ base: '\u0445'
+ shift, capslock: '\u0425'
+ ralt: '['
+ ralt+shift: '{'
+}
+
+key RIGHT_BRACKET {
+ label: '\u042a'
+ base: '\u044a'
+ shift, capslock: '\u042a'
+ ralt: ']'
+ ralt+shift: '}'
+}
+
+### ROW 3
+
+key A {
+ label: '\u0424'
+ base: '\u0444'
+ shift, capslock: '\u0424'
+ ralt: 'a'
+ ralt+shift, ralt+capslock: 'A'
+}
+
+key S {
+ label: '\u042b'
+ base: '\u044b'
+ shift, capslock: '\u042b'
+ ralt: 's'
+ ralt+shift, ralt+capslock: 'S'
+}
+
+key D {
+ label: '\u0412'
+ base: '\u0432'
+ shift, capslock: '\u0412'
+ ralt: 'd'
+ ralt+shift, ralt+capslock: 'D'
+}
+
+key F {
+ label: '\u0410'
+ base: '\u0430'
+ shift, capslock: '\u0410'
+ ralt: 'f'
+ ralt+shift, ralt+capslock: 'F'
+}
+
+key G {
+ label: '\u041f'
+ base: '\u043f'
+ shift, capslock: '\u041f'
+ ralt: 'g'
+ ralt+shift, ralt+capslock: 'G'
+}
+
+key H {
+ label: '\u0420'
+ base: '\u0440'
+ shift, capslock: '\u0420'
+ ralt: 'h'
+ ralt+shift, ralt+capslock: 'H'
+}
+
+key J {
+ label: '\u041e'
+ base: '\u043e'
+ shift, capslock: '\u041e'
+ ralt: 'j'
+ ralt+shift, ralt+capslock: 'J'
+}
+
+key K {
+ label: '\u041b'
+ base: '\u043b'
+ shift, capslock: '\u041b'
+ ralt: 'k'
+ ralt+shift, ralt+capslock: 'K'
+}
+
+key L {
+ label: '\u0414'
+ base: '\u0434'
+ shift, capslock: '\u0414'
+ ralt: 'l'
+ ralt+shift, ralt+capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u0416'
+ base: '\u0436'
+ shift, capslock: '\u0416'
+ ralt: ';'
+ ralt+shift: ':'
+}
+
+key APOSTROPHE {
+ label: '\u042d'
+ base: '\u044d'
+ shift, capslock: '\u042d'
+ ralt: '\''
+ ralt+shift: '"'
+}
+
+key BACKSLASH {
+ label: '\u0401'
+ base: '\u0451'
+ shift, capslock: '\u0401'
+ ralt: '\\'
+ ralt+shift: '|'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '['
+ base: '['
+ shift: ']'
+ ralt: '`'
+ ralt+shift: '~'
+}
+
+key Z {
+ label: '\u042f'
+ base: '\u044f'
+ shift, capslock: '\u042f'
+ ralt: 'z'
+ ralt+shift, ralt+capslock: 'Z'
+}
+
+key X {
+ label: '\u0427'
+ base: '\u0447'
+ shift, capslock: '\u0427'
+ ralt: 'x'
+ ralt+shift, ralt+capslock: 'X'
+}
+
+key C {
+ label: '\u0421'
+ base: '\u0441'
+ shift, capslock: '\u0421'
+ ralt: 'c'
+ ralt+shift, ralt+capslock: 'C'
+}
+
+key V {
+ label: '\u041c'
+ base: '\u043c'
+ shift, capslock: '\u041c'
+ ralt: 'v'
+ ralt+shift, ralt+capslock: 'V'
+}
+
+key B {
+ label: '\u0418'
+ base: '\u0438'
+ shift, capslock: '\u0418'
+ ralt: 'b'
+ ralt+shift, ralt+capslock: 'B'
+}
+
+key N {
+ label: '\u0422'
+ base: '\u0442'
+ shift, capslock: '\u0422'
+ ralt: 'n'
+ ralt+shift, ralt+capslock: 'N'
+}
+
+key M {
+ label: '\u042c'
+ base: '\u044c'
+ shift, capslock: '\u042c'
+ ralt: 'm'
+ ralt+shift, ralt+capslock: 'M'
+}
+
+key COMMA {
+ label: '\u0411'
+ base: '\u0431'
+ shift, capslock: '\u0411'
+ ralt: ','
+ ralt+shift: '<'
+}
+
+key PERIOD {
+ label: '\u042e'
+ base: '\u044e'
+ shift, capslock: '\u042e'
+ ralt: '.'
+ ralt+shift: '>'
+}
+
+key SLASH {
+ label: '/'
+ base: '/'
+ shift: '?'
+ ralt: '/'
+ ralt+shift: '?'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_spanish.kcm b/packages/InputDevices/res/raw/keyboard_layout_spanish.kcm
new file mode 100644
index 000000000000..da9159b89bf8
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_spanish.kcm
@@ -0,0 +1,329 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Spanish (Spain) keyboard layout.
+#
+
+type OVERLAY
+
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '\u00ba'
+ base: '\u00ba'
+ shift: '\u00aa'
+ ralt: '\\'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '!'
+ ralt: '|'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '\u00b7'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '$'
+ ralt: '\u0303'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+ ralt: '\u20ac'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '&'
+ ralt: '\u00ac'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '/'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '('
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: ')'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: '='
+}
+
+key MINUS {
+ label: '\''
+ base: '\''
+ shift: '?'
+}
+
+key EQUALS {
+ label: '\u00a1'
+ base: '\u00a1'
+ shift: '\u00bf'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u02cb'
+ base: '\u0300'
+ shift: '\u0302'
+ ralt: '['
+}
+
+key RIGHT_BRACKET {
+ label: '+'
+ base: '+'
+ shift: '*'
+ ralt: ']'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u00d1'
+ base: '\u00f1'
+ shift, capslock: '\u00d1'
+}
+
+key APOSTROPHE {
+ label: '\u00b4'
+ base: '\u0301'
+ shift: '\u0308'
+ ralt: '{'
+}
+
+key BACKSLASH {
+ label: '\u00c7'
+ base: '\u00e7'
+ shift, capslock: '\u00c7'
+ ralt: '}'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '<'
+ base: '<'
+ shift: '>'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: ';'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: ':'
+}
+
+key SLASH {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_swiss_french.kcm b/packages/InputDevices/res/raw/keyboard_layout_swiss_french.kcm
new file mode 100644
index 000000000000..a75d15487a63
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_swiss_french.kcm
@@ -0,0 +1,334 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Swiss French keyboard layout.
+# Same as Swiss German except in the placement of the umlaut / accented keys.
+#
+
+type OVERLAY
+
+map key 21 Z
+map key 44 Y
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '\u00a7'
+ base: '\u00a7'
+ shift: '\u00b0'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '+'
+ ralt: '\u00a6'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '*'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '\u00e7'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '&'
+ ralt: '\u00ac'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '/'
+ ralt: '|'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '('
+ ralt: '\u00a2'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: ')'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: '='
+}
+
+key MINUS {
+ label: '\''
+ base: '\''
+ shift: '?'
+ ralt: '\u0301'
+}
+
+key EQUALS {
+ label: '\u02c6'
+ base: '\u0302'
+ shift: '\u0300'
+ ralt: '\u0303'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u00e8'
+ base: '\u00e8'
+ shift: '\u00fc'
+ ralt: '['
+}
+
+key RIGHT_BRACKET {
+ label: '\u00a8'
+ base: '\u0308'
+ shift: '!'
+ ralt: ']'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u00e9'
+ base: '\u00e9'
+ shift: '\u00f6'
+}
+
+key APOSTROPHE {
+ label: '\u00e0'
+ base: '\u00e0'
+ shift: '\u00e4'
+ ralt: '{'
+}
+
+key BACKSLASH {
+ label: '$'
+ base: '$'
+ shift: '\u00a3'
+ ralt: '}'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '<'
+ base: '<'
+ shift: '>'
+ ralt: '\\'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: ';'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: ':'
+}
+
+key SLASH {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_swiss_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_swiss_german.kcm
new file mode 100644
index 000000000000..ae93f4bc39b6
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_swiss_german.kcm
@@ -0,0 +1,334 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Swiss German keyboard layout.
+# Same as Swiss French except in the placement of the umlaut / accented keys.
+#
+
+type OVERLAY
+
+map key 21 Z
+map key 44 Y
+map key 86 PLUS
+
+### ROW 1
+
+key GRAVE {
+ label: '\u00a7'
+ base: '\u00a7'
+ shift: '\u00b0'
+}
+
+key 1 {
+ label: '1'
+ base: '1'
+ shift: '+'
+ ralt: '\u00a6'
+}
+
+key 2 {
+ label: '2'
+ base: '2'
+ shift: '"'
+ ralt: '@'
+}
+
+key 3 {
+ label: '3'
+ base: '3'
+ shift: '*'
+ ralt: '#'
+}
+
+key 4 {
+ label: '4'
+ base: '4'
+ shift: '\u00e7'
+}
+
+key 5 {
+ label: '5'
+ base: '5'
+ shift: '%'
+}
+
+key 6 {
+ label: '6'
+ base: '6'
+ shift: '&'
+ ralt: '\u00ac'
+}
+
+key 7 {
+ label: '7'
+ base: '7'
+ shift: '/'
+ ralt: '|'
+}
+
+key 8 {
+ label: '8'
+ base: '8'
+ shift: '('
+ ralt: '\u00a2'
+}
+
+key 9 {
+ label: '9'
+ base: '9'
+ shift: ')'
+}
+
+key 0 {
+ label: '0'
+ base: '0'
+ shift: '='
+}
+
+key MINUS {
+ label: '\''
+ base: '\''
+ shift: '?'
+ ralt: '\u0301'
+}
+
+key EQUALS {
+ label: '\u02c6'
+ base: '\u0302'
+ shift: '\u0300'
+ ralt: '\u0303'
+}
+
+### ROW 2
+
+key Q {
+ label: 'Q'
+ base: 'q'
+ shift, capslock: 'Q'
+}
+
+key W {
+ label: 'W'
+ base: 'w'
+ shift, capslock: 'W'
+}
+
+key E {
+ label: 'E'
+ base: 'e'
+ shift, capslock: 'E'
+ ralt: '\u20ac'
+}
+
+key R {
+ label: 'R'
+ base: 'r'
+ shift, capslock: 'R'
+}
+
+key T {
+ label: 'T'
+ base: 't'
+ shift, capslock: 'T'
+}
+
+key Z {
+ label: 'Z'
+ base: 'z'
+ shift, capslock: 'Z'
+}
+
+key U {
+ label: 'U'
+ base: 'u'
+ shift, capslock: 'U'
+}
+
+key I {
+ label: 'I'
+ base: 'i'
+ shift, capslock: 'I'
+}
+
+key O {
+ label: 'O'
+ base: 'o'
+ shift, capslock: 'O'
+}
+
+key P {
+ label: 'P'
+ base: 'p'
+ shift, capslock: 'P'
+}
+
+key LEFT_BRACKET {
+ label: '\u00fc'
+ base: '\u00fc'
+ shift: '\u00e8'
+ ralt: '['
+}
+
+key RIGHT_BRACKET {
+ label: '\u00a8'
+ base: '\u0308'
+ shift: '!'
+ ralt: ']'
+}
+
+### ROW 3
+
+key A {
+ label: 'A'
+ base: 'a'
+ shift, capslock: 'A'
+}
+
+key S {
+ label: 'S'
+ base: 's'
+ shift, capslock: 'S'
+}
+
+key D {
+ label: 'D'
+ base: 'd'
+ shift, capslock: 'D'
+}
+
+key F {
+ label: 'F'
+ base: 'f'
+ shift, capslock: 'F'
+}
+
+key G {
+ label: 'G'
+ base: 'g'
+ shift, capslock: 'G'
+}
+
+key H {
+ label: 'H'
+ base: 'h'
+ shift, capslock: 'H'
+}
+
+key J {
+ label: 'J'
+ base: 'j'
+ shift, capslock: 'J'
+}
+
+key K {
+ label: 'K'
+ base: 'k'
+ shift, capslock: 'K'
+}
+
+key L {
+ label: 'L'
+ base: 'l'
+ shift, capslock: 'L'
+}
+
+key SEMICOLON {
+ label: '\u00f6'
+ base: '\u00f6'
+ shift: '\u00e9'
+}
+
+key APOSTROPHE {
+ label: '\u00e4'
+ base: '\u00e4'
+ shift: '\u00e0'
+ ralt: '{'
+}
+
+key BACKSLASH {
+ label: '$'
+ base: '$'
+ shift: '\u00a3'
+ ralt: '}'
+}
+
+### ROW 4
+
+key PLUS {
+ label: '<'
+ base: '<'
+ shift: '>'
+ ralt: '\\'
+}
+
+key Y {
+ label: 'Y'
+ base: 'y'
+ shift, capslock: 'Y'
+}
+
+key X {
+ label: 'X'
+ base: 'x'
+ shift, capslock: 'X'
+}
+
+key C {
+ label: 'C'
+ base: 'c'
+ shift, capslock: 'C'
+}
+
+key V {
+ label: 'V'
+ base: 'v'
+ shift, capslock: 'V'
+}
+
+key B {
+ label: 'B'
+ base: 'b'
+ shift, capslock: 'B'
+}
+
+key N {
+ label: 'N'
+ base: 'n'
+ shift, capslock: 'N'
+}
+
+key M {
+ label: 'M'
+ base: 'm'
+ shift, capslock: 'M'
+}
+
+key COMMA {
+ label: ','
+ base: ','
+ shift: ';'
+}
+
+key PERIOD {
+ label: '.'
+ base: '.'
+ shift: ':'
+}
+
+key SLASH {
+ label: '-'
+ base: '-'
+ shift: '_'
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 6d5ee988b29a..b44bc5cb278f 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -11,4 +11,25 @@
<!-- German keyboard layout label. [CHAR LIMIT=35] -->
<string name="keyboard_layout_german_label">German</string>
+
+ <!-- French keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_french_label">French</string>
+
+ <!-- Canadian French keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_french_ca_label">French (Canada)</string>
+
+ <!-- Russian keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_russian_label">Russian</string>
+
+ <!-- Russian (Apple style) keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_russian_apple_label">Russian, Apple</string>
+
+ <!-- Spanish keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_spanish_label">Spanish</string>
+
+ <!-- Swiss French keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_swiss_french_label">Swiss French</string>
+
+ <!-- Swiss German keyboard layout label. [CHAR LIMIT=35] -->
+ <string name="keyboard_layout_swiss_german_label">Swiss German</string>
</resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 459a0e4d00d0..58920dc8fbfe 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -11,4 +11,32 @@
<keyboard-layout android:name="keyboard_layout_german"
android:label="@string/keyboard_layout_german_label"
android:kcm="@raw/keyboard_layout_german" />
+
+ <keyboard-layout android:name="keyboard_layout_french"
+ android:label="@string/keyboard_layout_french_label"
+ android:kcm="@raw/keyboard_layout_french" />
+
+ <keyboard-layout android:name="keyboard_layout_french_ca"
+ android:label="@string/keyboard_layout_french_ca_label"
+ android:kcm="@raw/keyboard_layout_french_ca" />
+
+ <keyboard-layout android:name="keyboard_layout_russian"
+ android:label="@string/keyboard_layout_russian_label"
+ android:kcm="@raw/keyboard_layout_russian" />
+
+ <keyboard-layout android:name="keyboard_layout_russian_apple"
+ android:label="@string/keyboard_layout_russian_apple_label"
+ android:kcm="@raw/keyboard_layout_russian_apple" />
+
+ <keyboard-layout android:name="keyboard_layout_spanish"
+ android:label="@string/keyboard_layout_spanish_label"
+ android:kcm="@raw/keyboard_layout_spanish" />
+
+ <keyboard-layout android:name="keyboard_layout_swiss_french"
+ android:label="@string/keyboard_layout_swiss_french_label"
+ android:kcm="@raw/keyboard_layout_swiss_french" />
+
+ <keyboard-layout android:name="keyboard_layout_swiss_german"
+ android:label="@string/keyboard_layout_swiss_german_label"
+ android:kcm="@raw/keyboard_layout_swiss_german" />
</keyboard-layouts>
diff --git a/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png b/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png
new file mode 100644
index 000000000000..d595ed26ba5c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/navbar_search_bg_scrim.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/navbar_search_handle.xml b/packages/SystemUI/res/drawable/navbar_search_handle.xml
new file mode 100644
index 000000000000..e40fa2cbf11b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/navbar_search_handle.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@*android:drawable/ic_lockscreen_handle_pressed" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@*android:drawable/ic_lockscreen_handle_pressed" />
+
+</selector>
diff --git a/packages/SystemUI/res/drawable/navbar_search_outerring.xml b/packages/SystemUI/res/drawable/navbar_search_outerring.xml
new file mode 100644
index 000000000000..37b6c1cf6c22
--- /dev/null
+++ b/packages/SystemUI/res/drawable/navbar_search_outerring.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size android:height="@dimen/navbar_search_outerring_diameter"
+ android:width="@dimen/navbar_search_outerring_diameter" />
+ <solid android:color="#00000000" />
+ <stroke android:color="#1affffff" android:width="2dp" />
+</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
new file mode 100644
index 000000000000..2adee335f8d3
--- /dev/null
+++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.SearchPanelView
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/search_panel_container"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:paddingBottom="0dip">
+
+ <RelativeLayout
+ android:id="@+id/search_bg_protect"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="0dip">
+
+ <RelativeLayout
+ android:id="@+id/search_panel_container"
+ android:layout_width="230dip"
+ android:layout_height="match_parent"
+ android:layout_alignParentRight="true">
+
+ <com.android.internal.widget.multiwaveview.MultiWaveView
+ android:id="@+id/multi_wave_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="true"
+ android:background="@drawable/navbar_search_bg_scrim"
+
+ prvandroid:targetDrawables="@array/navbar_search_targets"
+ prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
+ prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
+ prvandroid:handleDrawable="@drawable/navbar_search_handle"
+ prvandroid:waveDrawable="@drawable/navbar_search_outerring"
+ prvandroid:outerRadius="@dimen/navbar_search_target_placement_radius"
+ prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
+ prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
+ prvandroid:verticalOffset="0dip"
+ prvandroid:horizontalOffset="60dip"
+ prvandroid:feedbackCount="0"
+ prvandroid:vibrationDuration="0"
+ prvandroid:alwaysTrackFinger="true"/>
+
+ </RelativeLayout>
+
+ </RelativeLayout>
+
+</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout-port/status_bar_search_panel.xml b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
new file mode 100644
index 000000000000..463fa042d56e
--- /dev/null
+++ b/packages/SystemUI/res/layout-port/status_bar_search_panel.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.SearchPanelView
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/search_panel_container"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:paddingBottom="0dip">
+
+ <RelativeLayout
+ android:id="@+id/search_bg_protect"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="0dip">
+
+ <RelativeLayout
+ android:id="@+id/search_panel_container"
+ android:layout_width="match_parent"
+ android:layout_height="230dip"
+ android:layout_alignParentBottom="true">
+
+ <com.android.internal.widget.multiwaveview.MultiWaveView
+ android:id="@+id/multi_wave_view"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="true"
+ android:background="@drawable/navbar_search_bg_scrim"
+
+ prvandroid:targetDrawables="@array/navbar_search_targets"
+ prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
+ prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
+ prvandroid:handleDrawable="@drawable/navbar_search_handle"
+ prvandroid:waveDrawable="@drawable/navbar_search_outerring"
+ prvandroid:outerRadius="@dimen/navbar_search_target_placement_radius"
+ prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
+ prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
+ prvandroid:horizontalOffset="0dip"
+ prvandroid:verticalOffset="60dip"
+ prvandroid:feedbackCount="0"
+ prvandroid:vibrationDuration="0"
+ prvandroid:alwaysTrackFinger="true"/>
+
+ </RelativeLayout>
+
+ </RelativeLayout>
+
+</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml
new file mode 100644
index 000000000000..53f374da5272
--- /dev/null
+++ b/packages/SystemUI/res/values-land/arrays.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <array name="navbar_search_targets">
+ <item>@null</item>
+ <item>@null</item>
+ <item>@*android:drawable/ic_lockscreen_search</item>
+ <item>@null</item>
+ </array>
+
+ <array name="navbar_search_target_descriptions">
+ <item>@null</item>
+ <item>@null</item>
+ <item>@*android:string/description_target_search</item>
+ <item>@null</item>
+ </array>
+
+ <array name="navbar_search_direction_descriptions">
+ <item>@null</item>
+ <item>@null</item>
+ <item>@*android:string/description_direction_left</item>
+ <item>@null</item>
+ </array>
+
+</resources>
diff --git a/packages/SystemUI/res/values-port/arrays.xml b/packages/SystemUI/res/values-port/arrays.xml
new file mode 100644
index 000000000000..f8b1620556da
--- /dev/null
+++ b/packages/SystemUI/res/values-port/arrays.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <array name="navbar_search_targets">
+ <item>@null</item>
+ <item>@*android:drawable/ic_lockscreen_search</item>
+ <item>@null</item>
+ <item>@null</item>
+ </array>
+
+ <array name="navbar_search_target_descriptions">
+ <item>@null</item>
+ <item>@*android:string/description_target_search</item>
+ <item>@null</item>
+ <item>@null</item>
+ </array>
+
+ <array name="navbar_search_direction_descriptions">
+ <item>@null</item>
+ <item>@*android:string/description_direction_up</item>
+ <item>@null</item>
+ <item>@null</item>
+ </array>
+
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b8e8fe4f83a9..531f154af19a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -105,4 +105,17 @@
<!-- The width of the view containing the menu status bar icon -->
<dimen name="navigation_menu_key_width">40dip</dimen>
+
+ <!-- Default target placement radius for navigation bar search target -->
+ <dimen name="navbar_search_target_placement_radius">150dip</dimen>
+
+ <!-- Default distance beyond which snaps to the target radius -->
+ <dimen name="navbar_search_snap_margin">20dip</dimen>
+
+ <!-- Default distance from each snap target considers a "hit" -->
+ <dimen name="navbar_search_hit_radius">60dip</dimen>
+
+ <!-- Diameter of outer shape drawable shown in navbar search-->
+ <dimen name="navbar_search_outerring_diameter">300dip</dimen>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
new file mode 100644
index 000000000000..369a093ae5f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.animation.Animator;
+import android.animation.LayoutTransition;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.speech.RecognizerIntent;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.internal.widget.multiwaveview.MultiWaveView;
+import com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener;
+import com.android.systemui.R;
+import com.android.systemui.recent.StatusBarTouchProxy;
+import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.tablet.StatusBarPanel;
+import com.android.systemui.statusbar.tablet.TabletStatusBar;
+
+public class SearchPanelView extends FrameLayout implements
+ StatusBarPanel, Animator.AnimatorListener {
+ static final String TAG = "SearchPanelView";
+ static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+ private Context mContext;
+ private BaseStatusBar mBar;
+ private StatusBarTouchProxy mStatusBarTouchProxy;
+
+ private boolean mShowing;
+ private View mSearchTargetsContainer;
+ private MultiWaveView mMultiWaveView;
+
+
+ public SearchPanelView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SearchPanelView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ }
+
+ final MultiWaveView.OnTriggerListener mMultiWaveViewListener
+ = new MultiWaveView.OnTriggerListener() {
+
+ public void onGrabbed(View v, int handle) {
+ }
+
+ public void onReleased(View v, int handle) {
+ }
+
+ public void onGrabbedStateChange(View v, int handle) {
+ if (OnTriggerListener.NO_HANDLE == handle) {
+ mBar.hideSearchPanel();
+ }
+ }
+
+ public void onTrigger(View v, int target) {
+ final int resId = mMultiWaveView.getResourceIdForTarget(target);
+ switch (resId) {
+ case com.android.internal.R.drawable.ic_lockscreen_search:
+ Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Application not found for action " + intent.getAction());
+ }
+ mBar.hideSearchPanel();
+ break;
+ }
+ }
+ };
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mSearchTargetsContainer = (ViewGroup) findViewById(R.id.search_panel_container);
+ mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
+ // TODO: fetch views
+ mMultiWaveView = (MultiWaveView) findViewById(R.id.multi_wave_view);
+ mMultiWaveView.setOnTriggerListener(mMultiWaveViewListener);
+ }
+
+ private boolean pointInside(int x, int y, View v) {
+ final int l = v.getLeft();
+ final int r = v.getRight();
+ final int t = v.getTop();
+ final int b = v.getBottom();
+ return x >= l && x < r && y >= t && y < b;
+ }
+
+ public boolean isInContentArea(int x, int y) {
+ if (pointInside(x, y, mSearchTargetsContainer)) {
+ return true;
+ } else if (mStatusBarTouchProxy != null &&
+ pointInside(x, y, mStatusBarTouchProxy)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void show(boolean show, boolean animate) {
+ if (animate) {
+ if (mShowing != show) {
+ mShowing = show;
+ // TODO: start animating ring
+ }
+ } else {
+ mShowing = show;
+ onAnimationEnd(null);
+ }
+ setVisibility(show ? View.VISIBLE : View.GONE);
+ if (show) {
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ requestFocus();
+ }
+ }
+
+ public void hide(boolean animate) {
+ if (!animate) {
+ setVisibility(View.GONE);
+ }
+ if (mBar != null) {
+ // This will indirectly cause show(false, ...) to get called
+ mBar.animateCollapse();
+ }
+ }
+
+ public void onAnimationCancel(Animator animation) {
+ }
+
+ public void onAnimationEnd(Animator animation) {
+ if (mShowing) {
+ final LayoutTransition transitioner = new LayoutTransition();
+ ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner);
+ createCustomAnimations(transitioner);
+ } else {
+ ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(null);
+ }
+ }
+
+ public void onAnimationRepeat(Animator animation) {
+ }
+
+ public void onAnimationStart(Animator animation) {
+ }
+
+ /**
+ * We need to be aligned at the bottom. LinearLayout can't do this, so instead,
+ * let LinearLayout do all the hard work, and then shift everything down to the bottom.
+ */
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ // setPanelHeight(mSearchTargetsContainer.getHeight());
+ }
+
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+
+ /**
+ * Whether the panel is showing, or, if it's animating, whether it will be
+ * when the animation is done.
+ */
+ public boolean isShowing() {
+ return mShowing;
+ }
+
+ public void setBar(BaseStatusBar bar) {
+ mBar = bar;
+ }
+
+ public void setStatusBarView(final View statusBarView) {
+ if (mStatusBarTouchProxy != null) {
+ mStatusBarTouchProxy.setStatusBar(statusBarView);
+// mMultiWaveView.setOnTouchListener(new OnTouchListener() {
+// public boolean onTouch(View v, MotionEvent event) {
+// return statusBarView.onTouchEvent(event);
+// }
+// });
+ }
+ }
+
+ private void createCustomAnimations(LayoutTransition transitioner) {
+ transitioner.setDuration(200);
+ transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
+ transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 19306a950311..4dd96fac75bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -55,6 +55,7 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
import com.android.internal.widget.SizeAdaptiveLayout;
+import com.android.systemui.SearchPanelView;
import com.android.systemui.SystemUI;
import com.android.systemui.recent.RecentsPanelView;
import com.android.systemui.recent.RecentTasksLoader;
@@ -73,6 +74,8 @@ public abstract class BaseStatusBar extends SystemUI implements
protected static final int MSG_CLOSE_RECENTS_PANEL = 1021;
protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
+ protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
+ protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
protected CommandQueue mCommandQueue;
protected IStatusBarService mBarService;
@@ -81,6 +84,9 @@ public abstract class BaseStatusBar extends SystemUI implements
// used to notify status bar for suppressing notification LED
protected boolean mPanelSlightlyVisible;
+ // Search panel
+ protected SearchPanelView mSearchPanelView;
+
// Recent apps
protected RecentsPanelView mRecentsPanel;
protected RecentTasksLoader mRecentTasksLoader;
@@ -278,12 +284,29 @@ public abstract class BaseStatusBar extends SystemUI implements
}
@Override
+ public void showSearchPanel() {
+ int msg = MSG_OPEN_SEARCH_PANEL;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ @Override
+ public void hideSearchPanel() {
+ int msg = MSG_CLOSE_SEARCH_PANEL;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ @Override
public void onRecentsPanelVisibilityChanged(boolean visible) {
}
protected abstract WindowManager.LayoutParams getRecentsLayoutParams(
LayoutParams layoutParams);
+ protected abstract WindowManager.LayoutParams getSearchLayoutParams(
+ LayoutParams layoutParams);
+
protected void updateRecentsPanel(int recentsResId) {
// Recents Panel
boolean visible = false;
@@ -319,6 +342,31 @@ public abstract class BaseStatusBar extends SystemUI implements
}
+ protected void updateSearchPanel() {
+ // Search Panel
+ boolean visible = false;
+ if (mSearchPanelView != null) {
+ visible = mSearchPanelView.isShowing();
+ WindowManagerImpl.getDefault().removeView(mSearchPanelView);
+ }
+
+ // Provide SearchPanel with a temporary parent to allow layout params to work.
+ LinearLayout tmpRoot = new LinearLayout(mContext);
+ mSearchPanelView = (SearchPanelView) LayoutInflater.from(mContext).inflate(
+ R.layout.status_bar_search_panel, tmpRoot, false);
+ mSearchPanelView.setOnTouchListener(
+ new TouchOutsideListener(MSG_CLOSE_SEARCH_PANEL, mSearchPanelView));
+ mSearchPanelView.setVisibility(View.GONE);
+
+ WindowManager.LayoutParams lp = getSearchLayoutParams(mSearchPanelView.getLayoutParams());
+
+ WindowManagerImpl.getDefault().addView(mSearchPanelView, lp);
+ mSearchPanelView.setBar(this);
+ if (visible) {
+ mSearchPanelView.show(true, false);
+ }
+ }
+
protected H createHandler() {
return new H();
}
@@ -346,6 +394,18 @@ public abstract class BaseStatusBar extends SystemUI implements
if (DEBUG) Slog.d(TAG, "cancel preloading recents");
mRecentsPanel.clearRecentTasksList();
break;
+ case MSG_OPEN_SEARCH_PANEL:
+ if (DEBUG) Slog.d(TAG, "opening search panel");
+ if (mSearchPanelView != null) {
+ mSearchPanelView.show(true, true);
+ }
+ break;
+ case MSG_CLOSE_SEARCH_PANEL:
+ if (DEBUG) Slog.d(TAG, "closing search panel");
+ if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
+ mSearchPanelView.show(false, true);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f88a3cc95421..42093549112b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -59,7 +59,7 @@ public class CommandQueue extends IStatusBar.Stub {
private static final int MSG_TOP_APP_WINDOW_CHANGED = 8 << MSG_SHIFT;
private static final int MSG_SHOW_IME_BUTTON = 9 << MSG_SHIFT;
private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT;
-
+
private static final int MSG_TOGGLE_RECENT_APPS = 11 << MSG_SHIFT;
private static final int MSG_PRELOAD_RECENT_APPS = 12 << MSG_SHIFT;
private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 13 << MSG_SHIFT;
@@ -95,6 +95,8 @@ public class CommandQueue extends IStatusBar.Stub {
public void setHardKeyboardStatus(boolean available, boolean enabled);
public void toggleRecentApps();
public void preloadRecentApps();
+ public void showSearchPanel();
+ public void hideSearchPanel();
public void cancelPreloadRecentApps();
public void setNavigationIconHints(int hints);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
new file mode 100644
index 000000000000..f725724de6cb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
@@ -0,0 +1,90 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.VelocityTracker;
+import android.view.View;
+
+public class DelegateViewHelper {
+ private static final int VELOCITY_THRESHOLD = 1000;
+ private VelocityTracker mVelocityTracker;
+ private View mDelegateView;
+ private View mSourceView;
+ private BaseStatusBar mBar;
+ private int[] mTempPoint = new int[2];
+ private int mOrientation;
+
+ public DelegateViewHelper(View sourceView) {
+ mSourceView = sourceView;
+ }
+
+ public void setDelegateView(View view) {
+ mDelegateView = view;
+ }
+
+ public void setBar(BaseStatusBar phoneStatusBar) {
+ mBar = phoneStatusBar;
+ }
+
+ public void setOrientation(int orientation) {
+ mOrientation = orientation;
+ }
+
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mVelocityTracker = VelocityTracker.obtain();
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ break;
+ }
+ if (mVelocityTracker != null) {
+ if (mDelegateView != null && mDelegateView.getVisibility() != View.VISIBLE) {
+ mVelocityTracker.addMovement(event);
+ mVelocityTracker.computeCurrentVelocity(1000);
+ final boolean isVertical = (mOrientation == Surface.ROTATION_90
+ || mOrientation == Surface.ROTATION_270);
+ float velocity = isVertical ? - mVelocityTracker.getXVelocity()
+ : - mVelocityTracker.getYVelocity();
+ if (velocity > VELOCITY_THRESHOLD) {
+ if (mDelegateView != null && mDelegateView.getVisibility() != View.VISIBLE) {
+ mBar.showSearchPanel();
+ }
+ }
+ }
+ }
+ if (mDelegateView != null) {
+ mSourceView.getLocationOnScreen(mTempPoint);
+ float deltaX = mTempPoint[0];
+ float deltaY = mTempPoint[1];
+
+ mDelegateView.getLocationOnScreen(mTempPoint);
+ deltaX -= mTempPoint[0];
+ deltaY -= mTempPoint[1];
+
+ event.offsetLocation(deltaX, deltaY);
+ mDelegateView.dispatchTouchEvent(event);
+ event.offsetLocation(-deltaX, -deltaY);
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 11e067f54881..73c5d3a5c02b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -31,10 +31,12 @@ import android.util.Slog;
import android.view.animation.AccelerateInterpolator;
import android.view.Display;
import android.view.MotionEvent;
+import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.Surface;
import android.view.WindowManager;
+import android.view.WindowManagerImpl;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -43,8 +45,9 @@ import java.io.PrintWriter;
import java.lang.StringBuilder;
import com.android.internal.statusbar.IStatusBarService;
-
import com.android.systemui.R;
+import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.DelegateViewHelper;
public class NavigationBarView extends LinearLayout {
final static boolean DEBUG = false;
@@ -68,6 +71,8 @@ public class NavigationBarView extends LinearLayout {
int mDisabledFlags = 0;
int mNavigationIconHints = 0;
+ private DelegateViewHelper mDelegateHelper;
+
// workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
final static boolean WORKAROUND_INVALID_LAYOUT = true;
final static int MSG_CHECK_INVALID_LAYOUT = 8686;
@@ -95,6 +100,19 @@ public class NavigationBarView extends LinearLayout {
}
}
+ public void setDelegateView(View view) {
+ mDelegateHelper.setDelegateView(view);
+ }
+
+ public void setBar(BaseStatusBar phoneStatusBar) {
+ mDelegateHelper.setBar(phoneStatusBar);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return mDelegateHelper.onInterceptTouchEvent(event);
+ }
+
private H mHandler = new H();
public View getRecentsButton() {
@@ -127,6 +145,7 @@ public class NavigationBarView extends LinearLayout {
mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
mVertical = false;
mShowMenu = false;
+ mDelegateHelper = new DelegateViewHelper(this);
}
View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
@@ -411,4 +430,5 @@ public class NavigationBarView extends LinearLayout {
);
pw.println(" }");
}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 61500e9bc3d2..80ee64f99bb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -258,7 +258,7 @@ public class PhoneStatusBar extends BaseStatusBar {
// ================================================================================
// Constructing the view
// ================================================================================
- protected View makeStatusBarView() {
+ protected PhoneStatusBarView makeStatusBarView() {
final Context context = mContext;
Resources res = context.getResources();
@@ -294,6 +294,7 @@ public class PhoneStatusBar extends BaseStatusBar {
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled);
+ mNavigationBarView.setBar(this);
}
} catch (RemoteException ex) {
// no window manager? good luck with that
@@ -389,6 +390,32 @@ public class PhoneStatusBar extends BaseStatusBar {
return lp;
}
+ @Override
+ protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
+ boolean opaque = false;
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+ (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
+ if (ActivityManager.isHighEndGfx(mDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ } else {
+ lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+ lp.dimAmount = 0.7f;
+ }
+ lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
+ lp.setTitle("SearchPanel");
+ // TODO: Define custom animation for Search panel
+ lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
+ lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+ return lp;
+ }
+
protected void updateRecentsPanel() {
super.updateRecentsPanel(R.layout.status_bar_recent_panel);
// Make .03 alpha the minimum so you always see the item a bit-- slightly below
@@ -397,6 +424,33 @@ public class PhoneStatusBar extends BaseStatusBar {
mRecentsPanel.setMinSwipeAlpha(0.03f);
}
+ @Override
+ protected void updateSearchPanel() {
+ super.updateSearchPanel();
+ mSearchPanelView.setStatusBarView(mStatusBarView);
+ mNavigationBarView.setDelegateView(mSearchPanelView);
+ }
+
+ @Override
+ public void showSearchPanel() {
+ super.showSearchPanel();
+ WindowManager.LayoutParams lp =
+ (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
+ WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
+ }
+
+ @Override
+ public void hideSearchPanel() {
+ super.hideSearchPanel();
+ WindowManager.LayoutParams lp =
+ (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
+ lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+ lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
+ WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
+ }
+
protected int getStatusBarGravity() {
return Gravity.TOP | Gravity.FILL_HORIZONTAL;
}
@@ -412,12 +466,30 @@ public class PhoneStatusBar extends BaseStatusBar {
}
};
private StatusBarNotification mCurrentlyIntrudingNotification;
+ View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent event) {
+ switch(event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ Slog.d(TAG, "showing search panel");
+ showSearchPanel();
+ break;
+
+ case MotionEvent.ACTION_UP:
+ Slog.d(TAG, "hiding search panel");
+ hideSearchPanel();
+ break;
+ }
+ return false;
+ }
+ };
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
+ updateSearchPanel();
+// mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
}
// For small-screen devices (read: phones) that lack hardware navigation buttons
@@ -528,7 +600,7 @@ public class PhoneStatusBar extends BaseStatusBar {
Slog.d(TAG, "Presenting high-priority notification");
// special new transient ticker mode
// 1. Populate mIntruderAlertView
-
+
if (notification.notification.intruderView == null) {
Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
return;
@@ -544,7 +616,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
mCurrentlyIntrudingNotification = notification;
-
+
// 2. Animate mIntruderAlertView in
mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
@@ -698,7 +770,7 @@ public class PhoneStatusBar extends BaseStatusBar {
// Recalculate the position of the sliding windows and the titles.
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
-
+
if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
}
@@ -1672,7 +1744,7 @@ public class PhoneStatusBar extends BaseStatusBar {
addStatusBarWindow();
addExpandedWindow();
}
-
+
private void addStatusBarWindow() {
// Put up the view
final int height = getStatusBarHeight();
@@ -1697,9 +1769,10 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
- WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp);
+ mStatusBarView = makeStatusBarView();
+ WindowManagerImpl.getDefault().addView(mStatusBarView, lp);
}
-
+
void addExpandedWindow() {
WindowManager.LayoutParams lp;
int pixelFormat;
@@ -1780,11 +1853,11 @@ public class PhoneStatusBar extends BaseStatusBar {
panelh = disph;
}
}
-
+
// catch orientation changes and other peculiar cases
if (panelh > disph || (panelh < disph && !mTracking && !mAnimating))
panelh = disph;
-
+
mTrackingPosition = panelh;
// XXX: this is all very WIP
//mNotificationPanel.setY(panelh);
@@ -1796,9 +1869,9 @@ public class PhoneStatusBar extends BaseStatusBar {
final float frac = (float)panelh / disph;
final int color = ((int)(0xB0 * frac * frac)) << 24;
mExpandedWindowView.setBackgroundColor(color);
-
+
// Slog.d(TAG, String.format("updateExpanded: pos=%d frac=%.2f col=0x%08x", pos, frac, color));
-
+
// if (mExpandedParams != null) {
// if (mCloseView.getWindowVisibility() == View.VISIBLE) {
// mCloseView.getLocationInWindow(mPositionTmp);
@@ -2060,7 +2133,7 @@ public class PhoneStatusBar extends BaseStatusBar {
// oh well
}
}
-
+
/**
* Reload some of our resources when the configuration changes.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 7b3b745e7e7b..3bdefcb2a5ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.tablet;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Notification;
import android.app.PendingIntent;
@@ -174,7 +175,7 @@ public class TabletStatusBar extends BaseStatusBar implements
KeyEvent mSpaceBarKeyEvent = null;
View mCompatibilityHelpDialog = null;
-
+
// for disabling the status bar
int mDisabled = 0;
@@ -192,7 +193,7 @@ public class TabletStatusBar extends BaseStatusBar implements
addStatusBarWindow();
addPanelWindows();
}
-
+
private void addStatusBarWindow() {
final View sb = makeStatusBarView();
@@ -328,6 +329,10 @@ public class TabletStatusBar extends BaseStatusBar implements
mRecentTasksLoader = new RecentTasksLoader(context);
updateRecentsPanel();
+ // Search Panel
+ mStatusBarView.setBar(this);
+ updateSearchPanel();
+
// Input methods Panel
mInputMethodsPanel = (InputMethodsPanel) View.inflate(context,
R.layout.system_bar_input_methods_panel, null);
@@ -350,7 +355,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.windowAnimations = R.style.Animation_RecentPanel;
WindowManagerImpl.getDefault().addView(mInputMethodsPanel, lp);
-
+
// Compatibility mode selector panel
mCompatModePanel = (CompatModePanel) View.inflate(context,
R.layout.system_bar_compat_mode_panel, null);
@@ -373,7 +378,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.windowAnimations = android.R.style.Animation_Dialog;
WindowManagerImpl.getDefault().addView(mCompatModePanel, lp);
-
+
mRecentButton.setOnTouchListener(mRecentsPanel);
mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
@@ -646,11 +651,64 @@ public class TabletStatusBar extends BaseStatusBar implements
return lp;
}
+ @Override
+ protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
+ boolean opaque = false;
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+ (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
+ if (ActivityManager.isHighEndGfx(mDisplay)) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ } else {
+ lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+ lp.dimAmount = 0.7f;
+ }
+ lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
+ lp.setTitle("SearchPanel");
+ // TODO: Define custom animation for Search panel
+ lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
+ lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+ return lp;
+ }
+
protected void updateRecentsPanel() {
super.updateRecentsPanel(R.layout.system_bar_recent_panel);
mRecentsPanel.setStatusBarView(mStatusBarView);
}
+ @Override
+ protected void updateSearchPanel() {
+ super.updateSearchPanel();
+ mSearchPanelView.setStatusBarView(mStatusBarView);
+ mStatusBarView.setDelegateView(mSearchPanelView);
+ }
+
+ @Override
+ public void showSearchPanel() {
+ super.showSearchPanel();
+ WindowManager.LayoutParams lp =
+ (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+ lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
+ WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
+ }
+
+ @Override
+ public void hideSearchPanel() {
+ super.hideSearchPanel();
+ WindowManager.LayoutParams lp =
+ (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
+ lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+ lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
+ WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
+ }
+
public int getStatusBarHeight() {
return mStatusBarView != null ? mStatusBarView.getHeight()
: mContext.getResources().getDimensionPixelSize(
@@ -1191,7 +1249,7 @@ public class TabletStatusBar extends BaseStatusBar implements
if (mCompatibilityHelpDialog != null) {
return;
}
-
+
mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null);
View button = mCompatibilityHelpDialog.findViewById(R.id.button);
@@ -1227,7 +1285,7 @@ public class TabletStatusBar extends BaseStatusBar implements
mCompatibilityHelpDialog = null;
}
}
-
+
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
mInputMethodSwitchButton.setImeWindowStatus(token,
(vis & InputMethodService.IME_ACTIVE) != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index 877a40efae31..a6fc3965bca8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.tablet;
+import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.DelegateViewHelper;
+
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
@@ -31,13 +34,24 @@ public class TabletStatusBarView extends FrameLayout {
private final View[] mIgnoreChildren = new View[MAX_PANELS];
private final View[] mPanels = new View[MAX_PANELS];
private final int[] mPos = new int[2];
+ private DelegateViewHelper mDelegateHelper;
public TabletStatusBarView(Context context) {
super(context);
+ mDelegateHelper = new DelegateViewHelper(this);
}
public TabletStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mDelegateHelper = new DelegateViewHelper(this);
+ }
+
+ public void setDelegateView(View view) {
+ mDelegateHelper.setDelegateView(view);
+ }
+
+ public void setBar(BaseStatusBar phoneStatusBar) {
+ mDelegateHelper.setBar(phoneStatusBar);
}
@Override
@@ -72,6 +86,9 @@ public class TabletStatusBarView extends FrameLayout {
if (TabletStatusBar.DEBUG) {
Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
}
+ if (mDelegateHelper != null) {
+ return mDelegateHelper.onInterceptTouchEvent(ev);
+ }
return super.onInterceptTouchEvent(ev);
}
@@ -97,7 +114,7 @@ public class TabletStatusBarView extends FrameLayout {
/**
* Let the status bar know that if you tap on ignore while panel is showing, don't do anything.
- *
+ *
* Debounces taps on, say, a popup's trigger when the popup is already showing.
*/
public void setIgnoreChildren(int index, View ignore, View panel) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index cc663c2c5091..50863256497a 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -131,6 +131,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
@@ -216,16 +217,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int SYSTEM_OVERLAY_LAYER = 18;
// the navigation bar, if available, shows atop most things
static final int NAVIGATION_BAR_LAYER = 19;
+ // some panels (e.g. search) need to show on top of the navigation bar
+ static final int NAVIGATION_BAR_PANEL_LAYER = 20;
// system-level error dialogs
- static final int SYSTEM_ERROR_LAYER = 20;
+ static final int SYSTEM_ERROR_LAYER = 21;
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- static final int DRAG_LAYER = 21;
- static final int SECURE_SYSTEM_OVERLAY_LAYER = 22;
- static final int BOOT_PROGRESS_LAYER = 23;
+ static final int DRAG_LAYER = 22;
+ static final int SECURE_SYSTEM_OVERLAY_LAYER = 23;
+ static final int BOOT_PROGRESS_LAYER = 24;
// the (mouse) pointer layer
- static final int POINTER_LAYER = 24;
- static final int HIDDEN_NAV_CONSUMER_LAYER = 25;
+ static final int POINTER_LAYER = 25;
+ static final int HIDDEN_NAV_CONSUMER_LAYER = 26;
static final int APPLICATION_MEDIA_SUBLAYER = -2;
static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -1335,6 +1338,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return POINTER_LAYER;
case TYPE_NAVIGATION_BAR:
return NAVIGATION_BAR_LAYER;
+ case TYPE_NAVIGATION_BAR_PANEL:
+ return NAVIGATION_BAR_PANEL_LAYER;
case TYPE_BOOT_PROGRESS:
return BOOT_PROGRESS_LAYER;
case TYPE_HIDDEN_NAV_CONSUMER:
@@ -1577,6 +1582,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mNavigationBar = win;
if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
break;
+ case TYPE_NAVIGATION_BAR_PANEL:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE,
+ "PhoneWindowManager");
+ break;
case TYPE_STATUS_BAR_PANEL:
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.STATUS_BAR_SERVICE,
@@ -2480,7 +2490,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
"Laying out IN_SCREEN status bar window: (%d,%d - %d,%d)",
pf.left, pf.top, pf.right, pf.bottom));
}
- } else if (attrs.type == TYPE_NAVIGATION_BAR) {
+ } else if (attrs.type == TYPE_NAVIGATION_BAR
+ || attrs.type == TYPE_NAVIGATION_BAR_PANEL) {
// The navigation bar has Real Ultimate Power.
pf.left = df.left = mUnrestrictedScreenLeft;
pf.top = df.top = mUnrestrictedScreenTop;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 529537c1bd82..6c99cdb955e4 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -13408,7 +13408,8 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
ActivityRecord srec = ActivityRecord.forToken(token);
- return srec.task.affinity != null && srec.task.affinity.equals(destAffinity);
+ return srec != null && srec.task.affinity != null &&
+ srec.task.affinity.equals(destAffinity);
}
public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
@@ -13417,6 +13418,9 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
ActivityRecord srec = ActivityRecord.forToken(token);
+ if (srec == null) {
+ return false;
+ }
ArrayList<ActivityRecord> history = srec.stack.mHistory;
final int start = history.indexOf(srec);
if (start < 0) {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 52d50195f863..f873b6ccce7a 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1665,20 +1665,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateRulesForAppLocked(appId);
}
- // and catch system UIDs
- // TODO: keep in sync with android_filesystem_config.h
- for (int uid = 1000; uid <= 1025; uid++) {
- updateRulesForUidLocked(uid);
- }
- for (int uid = 2000; uid <= 2002; uid++) {
- updateRulesForUidLocked(uid);
- }
- for (int uid = 3000; uid <= 3007; uid++) {
- updateRulesForUidLocked(uid);
- }
- for (int uid = 9998; uid <= 9999; uid++) {
- updateRulesForUidLocked(uid);
- }
+ // limit data usage for some internal system services
+ updateRulesForUidLocked(android.os.Process.MEDIA_UID);
+ updateRulesForUidLocked(android.os.Process.DRM_UID);
}
private void updateRulesForAppLocked(int appId) {
@@ -1688,7 +1677,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ private static boolean isUidValidForRules(int uid) {
+ // allow rules on specific system services, and any apps
+ if (uid == android.os.Process.MEDIA_UID || uid == android.os.Process.DRM_UID
+ || UserId.isApp(uid)) {
+ return true;
+ }
+
+ return false;
+ }
+
private void updateRulesForUidLocked(int uid) {
+ if (!isUidValidForRules(uid)) return;
+
final int appId = UserId.getAppId(uid);
final int appPolicy = getAppPolicy(appId);
final boolean uidForeground = isUidForeground(uid);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index defe824fbd5b..ab51f6d70f42 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -130,6 +130,7 @@ import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
+import android.view.animation.TranslateAnimation;
import java.io.BufferedWriter;
import java.io.DataInputStream;
@@ -3129,13 +3130,16 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.integer.config_shortAnimTime);
break;
default:
- duration = 500;
+ duration = 300;
break;
}
if (enter) {
// Entering app zooms out from the center of the initial rect.
- float scaleW = mNextAppTransitionStartWidth/(float)mAppDisplayWidth;
- float scaleH = mNextAppTransitionStartHeight/(float)mAppDisplayHeight;
+ final float minScale = 0.1f;
+ float scaleW = minScale +
+ ((1f - minScale) * mNextAppTransitionStartWidth / (float) mAppDisplayWidth);
+ float scaleH = minScale +
+ ((1f - minScale) * mNextAppTransitionStartHeight / (float) mAppDisplayHeight);
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
@@ -3152,7 +3156,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
a.setFillAfter(true);
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_quad);
+ com.android.internal.R.interpolator.decelerate_cubic);
a.setInterpolator(interpolator);
a.initialize(mAppDisplayWidth, mAppDisplayHeight,
mAppDisplayWidth, mAppDisplayHeight);
@@ -3177,7 +3181,7 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.integer.config_shortAnimTime);
break;
default:
- duration = 500;
+ duration = 300;
break;
}
if (thumb) {