am 2b7df368: am cab997b2: Merge "Fix 6667238: allow market apps to support ACTION_ASSIST" into jb-dev
* commit '2b7df3686f24a5a653a6609556dd98210324f7bd':
Fix 6667238: allow market apps to support ACTION_ASSIST
diff --git a/Android.mk b/Android.mk
index 5aaea97..235ee96 100644
--- a/Android.mk
+++ b/Android.mk
@@ -411,6 +411,7 @@
-since ./frameworks/base/api/13.xml 13 \
-since ./frameworks/base/api/14.txt 14 \
-since ./frameworks/base/api/15.txt 15 \
+ -since ./frameworks/base/api/16.txt 16 \
-werror -hide 113 \
-overview $(LOCAL_PATH)/core/java/overview.html
@@ -521,7 +522,7 @@
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=4.0
+framework_docs_SDK_VERSION:=4.1
# release version (ie "Release x") (full releases only)
framework_docs_SDK_REL_ID:=1
diff --git a/api/current.txt b/api/current.txt
index 308e4d4..89f265d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -602,6 +602,7 @@
field public static final int layerType = 16843604; // 0x1010354
field public static final int layout = 16842994; // 0x10100f2
field public static final int layoutAnimation = 16842988; // 0x10100ec
+ field public static final int layoutDirection = 16843697; // 0x10103b1
field public static final int layout_above = 16843140; // 0x1010184
field public static final int layout_alignBaseline = 16843142; // 0x1010186
field public static final int layout_alignBottom = 16843146; // 0x101018a
@@ -623,8 +624,10 @@
field public static final int layout_height = 16842997; // 0x10100f5
field public static final int layout_margin = 16842998; // 0x10100f6
field public static final int layout_marginBottom = 16843002; // 0x10100fa
+ field public static final int layout_marginEnd = 16843701; // 0x10103b5
field public static final int layout_marginLeft = 16842999; // 0x10100f7
field public static final int layout_marginRight = 16843001; // 0x10100f9
+ field public static final int layout_marginStart = 16843700; // 0x10103b4
field public static final int layout_marginTop = 16843000; // 0x10100f8
field public static final int layout_row = 16843643; // 0x101037b
field public static final int layout_rowSpan = 16843644; // 0x101037c
@@ -721,8 +724,10 @@
field public static final int packageNames = 16843649; // 0x1010381
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
+ field public static final int paddingEnd = 16843699; // 0x10103b3
field public static final int paddingLeft = 16842966; // 0x10100d6
field public static final int paddingRight = 16842968; // 0x10100d8
+ field public static final int paddingStart = 16843698; // 0x10103b2
field public static final int paddingTop = 16842967; // 0x10100d7
field public static final int panelBackground = 16842846; // 0x101005e
field public static final int panelColorBackground = 16842849; // 0x1010061
@@ -934,6 +939,7 @@
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
+ field public static final int supportsRtl = 16843694; // 0x10103ae
field public static final int supportsUploading = 16843419; // 0x101029b
field public static final int switchMinWidth = 16843632; // 0x1010370
field public static final int switchPadding = 16843633; // 0x1010371
@@ -964,6 +970,7 @@
field public static final int tension = 16843370; // 0x101026a
field public static final int testOnly = 16843378; // 0x1010272
field public static final int text = 16843087; // 0x101014f
+ field public static final int textAlignment = 16843696; // 0x10103b0
field public static final int textAllCaps = 16843660; // 0x101038c
field public static final int textAppearance = 16842804; // 0x1010034
field public static final int textAppearanceButton = 16843271; // 0x1010207
@@ -1003,6 +1010,7 @@
field public static final int textColorTertiary = 16843282; // 0x1010212
field public static final int textColorTertiaryInverse = 16843283; // 0x1010213
field public static final int textCursorDrawable = 16843618; // 0x1010362
+ field public static final int textDirection = 16843695; // 0x10103af
field public static final int textEditNoPasteWindowLayout = 16843541; // 0x1010315
field public static final int textEditPasteWindowLayout = 16843540; // 0x1010314
field public static final int textEditSideNoPasteWindowLayout = 16843615; // 0x101035f
@@ -4329,6 +4337,7 @@
method public void deleteHost();
method protected android.appwidget.AppWidgetHostView onCreateView(android.content.Context, int, android.appwidget.AppWidgetProviderInfo);
method protected void onProviderChanged(int, android.appwidget.AppWidgetProviderInfo);
+ method protected void onProvidersChanged();
method public void startListening();
method public void stopListening();
}
@@ -5801,7 +5810,9 @@
field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
+ field public static final java.lang.String EXTRA_ORIGINATING_URL = "android.intent.extra.ORIGINATING_URL";
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
+ field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
field public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING";
field public static final java.lang.String EXTRA_RETURN_RESULT = "android.intent.extra.RETURN_RESULT";
@@ -6259,6 +6270,7 @@
field public static final int FLAG_STOPPED = 2097152; // 0x200000
field public static final int FLAG_SUPPORTS_LARGE_SCREENS = 2048; // 0x800
field public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1024; // 0x400
+ field public static final int FLAG_SUPPORTS_RTL = 4194304; // 0x400000
field public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 8192; // 0x2000
field public static final int FLAG_SUPPORTS_SMALL_SCREENS = 512; // 0x200
field public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 524288; // 0x80000
@@ -6939,7 +6951,7 @@
method public int getIndexCount();
method public int getInt(int, int);
method public int getInteger(int, int);
- method public int getLayoutDimension(int, java.lang.String);
+ method public deprecated int getLayoutDimension(int, java.lang.String);
method public int getLayoutDimension(int, int);
method public java.lang.String getNonResourceString(int);
method public java.lang.String getPositionDescription();
@@ -8596,6 +8608,7 @@
method public android.graphics.Paint.Align getTextAlign();
method public void getTextBounds(java.lang.String, int, int, android.graphics.Rect);
method public void getTextBounds(char[], int, int, android.graphics.Rect);
+ method public java.util.Locale getTextLocale();
method public void getTextPath(char[], int, int, float, float, android.graphics.Path);
method public void getTextPath(java.lang.String, int, int, float, float, android.graphics.Path);
method public float getTextScaleX();
@@ -8645,6 +8658,7 @@
method public void setStyle(android.graphics.Paint.Style);
method public void setSubpixelText(boolean);
method public void setTextAlign(android.graphics.Paint.Align);
+ method public void setTextLocale(java.util.Locale);
method public void setTextScaleX(float);
method public void setTextSize(float);
method public void setTextSkewX(float);
@@ -9239,6 +9253,7 @@
method public android.graphics.drawable.Drawable getCurrent();
method public int getIntrinsicHeight();
method public int getIntrinsicWidth();
+ method public int getLayoutDirection();
method public final int getLevel();
method public int getMinimumHeight();
method public int getMinimumWidth();
@@ -9266,6 +9281,7 @@
method public void setColorFilter(int, android.graphics.PorterDuff.Mode);
method public void setDither(boolean);
method public void setFilterBitmap(boolean);
+ method public void setLayoutDirection(int);
method public final boolean setLevel(int);
method public boolean setState(int[]);
method public boolean setVisible(boolean, boolean);
@@ -22463,6 +22479,10 @@
method public android.util.JsonWriter value(java.lang.Number) throws java.io.IOException;
}
+ public class LocaleUtil {
+ method public static int getLayoutDirectionFromLocale(java.util.Locale);
+ }
+
public final class Log {
method public static int d(java.lang.String, java.lang.String);
method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
@@ -22950,8 +22970,12 @@
public class Gravity {
ctor public Gravity();
method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect);
+ method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect);
+ method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect);
+ method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+ method public static int getAbsoluteGravity(int, int);
method public static boolean isHorizontal(int);
method public static boolean isVertical(int);
field public static final int AXIS_CLIP = 8; // 0x8
@@ -23995,6 +24019,9 @@
method public void buildDrawingCache(boolean);
method public void buildLayer();
method public boolean callOnClick();
+ method public boolean canResolveLayoutDirection();
+ method public boolean canResolveTextAlignment();
+ method public boolean canResolveTextDirection();
method public boolean canScrollHorizontally(int);
method public boolean canScrollVertically(int);
method public void cancelLongPress();
@@ -24083,6 +24110,7 @@
method public boolean getKeepScreenOn();
method public android.view.KeyEvent.DispatcherState getKeyDispatcherState();
method public int getLayerType();
+ method public int getLayoutDirection();
method public android.view.ViewGroup.LayoutParams getLayoutParams();
method public final int getLeft();
method protected float getLeftFadingEdgeStrength();
@@ -24106,13 +24134,18 @@
method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
method public int getOverScrollMode();
method public int getPaddingBottom();
+ method public int getPaddingEnd();
method public int getPaddingLeft();
method public int getPaddingRight();
+ method public int getPaddingStart();
method public int getPaddingTop();
method public final android.view.ViewParent getParent();
method public android.view.ViewParent getParentForAccessibility();
method public float getPivotX();
method public float getPivotY();
+ method public int getResolvedLayoutDirection();
+ method public int getResolvedTextAlignment();
+ method public int getResolvedTextDirection();
method public android.content.res.Resources getResources();
method public final int getRight();
method protected float getRightFadingEdgeStrength();
@@ -24135,6 +24168,8 @@
method public int getSystemUiVisibility();
method public java.lang.Object getTag();
method public java.lang.Object getTag(int);
+ method public int getTextAlignment();
+ method public int getTextDirection();
method public final int getTop();
method protected float getTopFadingEdgeStrength();
method protected int getTopPaddingOffset();
@@ -24184,10 +24219,13 @@
method public boolean isHovered();
method public boolean isInEditMode();
method public boolean isInTouchMode();
+ method protected static boolean isLayoutDirectionRtl(java.util.Locale);
method public boolean isLayoutRequested();
+ method public boolean isLayoutRtl();
method public boolean isLongClickable();
method public boolean isOpaque();
method protected boolean isPaddingOffsetRequired();
+ method public boolean isPaddingRelative();
method public boolean isPressed();
method public boolean isSaveEnabled();
method public boolean isSaveFromParentEnabled();
@@ -24235,7 +24273,15 @@
method protected void onLayout(boolean, int, int, int, int);
method protected void onMeasure(int, int);
method protected void onOverScrolled(int, int, boolean, boolean);
+ method public void onPaddingChanged(int);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public void onResolveDrawables(int);
+ method public void onResolvedLayoutDirectionChanged();
+ method public void onResolvedLayoutDirectionReset();
+ method public void onResolvedTextAlignmentChanged();
+ method public void onResolvedTextAlignmentReset();
+ method public void onResolvedTextDirectionChanged();
+ method public void onResolvedTextDirectionReset();
method protected void onRestoreInstanceState(android.os.Parcelable);
method protected android.os.Parcelable onSaveInstanceState();
method public void onScreenStateChanged(int);
@@ -24278,8 +24324,16 @@
method public void requestLayout();
method public boolean requestRectangleOnScreen(android.graphics.Rect);
method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
+ method public void resetResolvedLayoutDirection();
+ method public void resetResolvedTextAlignment();
+ method public void resetResolvedTextDirection();
+ method public void resolveDrawables();
+ method public void resolveLayoutDirection();
+ method public void resolvePadding();
method public static int resolveSize(int, int);
method public static int resolveSizeAndState(int, int, int);
+ method public void resolveTextAlignment();
+ method public void resolveTextDirection();
method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -24318,6 +24372,7 @@
method public void setImportantForAccessibility(int);
method public void setKeepScreenOn(boolean);
method public void setLayerType(int, android.graphics.Paint);
+ method public void setLayoutDirection(int);
method public void setLayoutParams(android.view.ViewGroup.LayoutParams);
method public final void setLeft(int);
method public void setLongClickable(boolean);
@@ -24341,6 +24396,7 @@
method public void setOnTouchListener(android.view.View.OnTouchListener);
method public void setOverScrollMode(int);
method public void setPadding(int, int, int, int);
+ method public void setPaddingRelative(int, int, int, int);
method public void setPivotX(float);
method public void setPivotY(float);
method public void setPressed(boolean);
@@ -24365,6 +24421,8 @@
method public void setSystemUiVisibility(int);
method public void setTag(java.lang.Object);
method public void setTag(int, java.lang.Object);
+ method public void setTextAlignment(int);
+ method public void setTextDirection(int);
method public final void setTop(int);
method public void setTouchDelegate(android.view.TouchDelegate);
method public void setTranslationX(float);
@@ -24423,6 +24481,10 @@
field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
field public static final int LAYER_TYPE_NONE = 0; // 0x0
field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+ field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+ field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+ field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+ field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
@@ -24473,8 +24535,22 @@
field public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1; // 0x1
field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
field public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536; // 0x600
+ field public static final int TEXT_ALIGNMENT_CENTER = 4; // 0x4
+ field protected static int TEXT_ALIGNMENT_DEFAULT;
+ field public static final int TEXT_ALIGNMENT_GRAVITY = 1; // 0x1
field public static final int TEXT_ALIGNMENT_INHERIT = 0; // 0x0
field public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = 131072; // 0x20000
+ field public static final int TEXT_ALIGNMENT_TEXT_END = 3; // 0x3
+ field public static final int TEXT_ALIGNMENT_TEXT_START = 2; // 0x2
+ field public static final int TEXT_ALIGNMENT_VIEW_END = 6; // 0x6
+ field public static final int TEXT_ALIGNMENT_VIEW_START = 5; // 0x5
+ field public static final int TEXT_DIRECTION_ANY_RTL = 2; // 0x2
+ field protected static int TEXT_DIRECTION_DEFAULT;
+ field public static final int TEXT_DIRECTION_FIRST_STRONG = 1; // 0x1
+ field public static final int TEXT_DIRECTION_INHERIT = 0; // 0x0
+ field public static final int TEXT_DIRECTION_LOCALE = 5; // 0x5
+ field public static final int TEXT_DIRECTION_LTR = 3; // 0x3
+ field public static final int TEXT_DIRECTION_RTL = 4; // 0x4
field public static final android.util.Property TRANSLATION_X;
field public static final android.util.Property TRANSLATION_Y;
field protected static final java.lang.String VIEW_LOG_TAG = "View";
@@ -24778,6 +24854,7 @@
ctor public ViewGroup.LayoutParams(android.content.Context, android.util.AttributeSet);
ctor public ViewGroup.LayoutParams(int, int);
ctor public ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams);
+ method public void onResolveLayoutDirection(int);
method protected void setBaseAttributes(android.content.res.TypedArray, int, int);
field public static final deprecated int FILL_PARENT = -1; // 0xffffffff
field public static final int MATCH_PARENT = -1; // 0xffffffff
@@ -24792,10 +24869,15 @@
ctor public ViewGroup.MarginLayoutParams(int, int);
ctor public ViewGroup.MarginLayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public ViewGroup.MarginLayoutParams(android.view.ViewGroup.LayoutParams);
+ method public int getMarginEnd();
+ method public int getMarginStart();
+ method public boolean isMarginRelative();
method public void setMargins(int, int, int, int);
field public int bottomMargin;
+ field public int endMargin;
field public int leftMargin;
field public int rightMargin;
+ field public int startMargin;
field public int topMargin;
}
@@ -26256,7 +26338,7 @@
method public boolean onJsBeforeUnload(android.webkit.WebView, java.lang.String, java.lang.String, android.webkit.JsResult);
method public boolean onJsConfirm(android.webkit.WebView, java.lang.String, java.lang.String, android.webkit.JsResult);
method public boolean onJsPrompt(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String, android.webkit.JsPromptResult);
- method public boolean onJsTimeout();
+ method public deprecated boolean onJsTimeout();
method public void onProgressChanged(android.webkit.WebView, int);
method public void onReachedMaxAppCacheSize(long, long, android.webkit.WebStorage.QuotaUpdater);
method public void onReceivedIcon(android.webkit.WebView, android.graphics.Bitmap);
@@ -27126,7 +27208,6 @@
ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
method public android.graphics.drawable.Drawable getCheckMarkDrawable();
method public boolean isChecked();
- method public void onPaddingChanged(int);
method public void setCheckMarkDrawable(int);
method public void setCheckMarkDrawable(android.graphics.drawable.Drawable);
method public void setChecked(boolean);
@@ -28156,6 +28237,7 @@
method public void setString(int, java.lang.String, java.lang.String);
method public void setTextColor(int, int);
method public void setTextViewCompoundDrawables(int, int, int, int, int);
+ method public void setTextViewCompoundDrawablesRelative(int, int, int, int, int);
method public void setTextViewText(int, java.lang.CharSequence);
method public void setUri(int, java.lang.String, android.net.Uri);
method public void setViewVisibility(int, int);
@@ -28635,9 +28717,12 @@
method public final int getAutoLinkMask();
method public int getCompoundDrawablePadding();
method public android.graphics.drawable.Drawable[] getCompoundDrawables();
+ method public android.graphics.drawable.Drawable[] getCompoundDrawablesRelative();
method public int getCompoundPaddingBottom();
+ method public int getCompoundPaddingEnd();
method public int getCompoundPaddingLeft();
method public int getCompoundPaddingRight();
+ method public int getCompoundPaddingStart();
method public int getCompoundPaddingTop();
method public final int getCurrentHintTextColor();
method public final int getCurrentTextColor();
@@ -28697,8 +28782,10 @@
method public float getTextScaleX();
method public float getTextSize();
method public int getTotalPaddingBottom();
+ method public int getTotalPaddingEnd();
method public int getTotalPaddingLeft();
method public int getTotalPaddingRight();
+ method public int getTotalPaddingStart();
method public int getTotalPaddingTop();
method public final android.text.method.TransformationMethod getTransformationMethod();
method public android.graphics.Typeface getTypeface();
@@ -28724,11 +28811,13 @@
method public boolean onTextContextMenuItem(int);
method public void removeTextChangedListener(android.text.TextWatcher);
method protected void resetResolvedDrawables();
- method protected void resolveDrawables();
method public void setAllCaps(boolean);
method public final void setAutoLinkMask(int);
method public void setCompoundDrawablePadding(int);
method public void setCompoundDrawables(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public void setCompoundDrawablesRelative(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public void setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int);
+ method public void setCompoundDrawablesRelativeWithIntrinsicBounds(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public void setCompoundDrawablesWithIntrinsicBounds(int, int, int, int);
method public void setCompoundDrawablesWithIntrinsicBounds(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public void setCursorVisible(boolean);
@@ -28772,7 +28861,6 @@
method public void setMinWidth(int);
method public final void setMovementMethod(android.text.method.MovementMethod);
method public void setOnEditorActionListener(android.widget.TextView.OnEditorActionListener);
- method public void setPaddingRelative(int, int, int, int);
method public void setPaintFlags(int);
method public void setPrivateImeOptions(java.lang.String);
method public void setRawInputType(int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 191a696..9a50a41 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1206,7 +1206,8 @@
return mPM.getUsers();
} catch (RemoteException re) {
ArrayList<UserInfo> users = new ArrayList<UserInfo>();
- UserInfo primary = new UserInfo(0, "Root!", UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+ UserInfo primary = new UserInfo(0, "Root!", null,
+ UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
users.add(primary);
return users;
}
@@ -1240,9 +1241,9 @@
* @hide
*/
@Override
- public void updateUserName(int id, String name) {
+ public void setUserName(int id, String name) {
try {
- mPM.updateUserName(id, name);
+ mPM.setUserName(id, name);
} catch (RemoteException re) {
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b902550..5e21403 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1187,6 +1187,9 @@
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
IServiceConnection sd;
+ if (conn == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
@@ -1217,6 +1220,9 @@
@Override
public void unbindService(ServiceConnection conn) {
+ if (conn == null) {
+ throw new IllegalArgumentException("connection is null");
+ }
if (mPackageInfo != null) {
IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
getOuterContext(), conn);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9ba5305..d8777fb 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1912,7 +1912,7 @@
if (mActive != null) {
for (int i=0; i<mAdded.size(); i++) {
Fragment f = mAdded.get(i);
- if (f != null && !f.mHidden && f.mUserVisibleHint) {
+ if (f != null && !f.mHidden) {
if (f.onContextItemSelected(item)) {
return true;
}
diff --git a/core/java/android/app/IInstrumentationWatcher.aidl b/core/java/android/app/IInstrumentationWatcher.aidl
index 405a3d8..6c8c4d6 100644
--- a/core/java/android/app/IInstrumentationWatcher.aidl
+++ b/core/java/android/app/IInstrumentationWatcher.aidl
@@ -21,7 +21,7 @@
import android.os.Bundle;
/** @hide */
-oneway interface IInstrumentationWatcher
+interface IInstrumentationWatcher
{
void instrumentationStatus(in ComponentName name, int resultCode,
in Bundle results);
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 35cc324..396f910 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -1,6 +1,5 @@
package android.app;
-import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
import android.content.Context;
@@ -119,7 +118,7 @@
}
}
- static class InputMethodCallback extends IInputMethodCallback.Stub {
+ static final class InputMethodCallback implements InputMethodManager.FinishedEventCallback {
WeakReference<NativeActivity> mNa;
InputMethodCallback(NativeActivity na) {
@@ -133,11 +132,6 @@
na.finishPreDispatchKeyEventNative(na.mNativeHandle, seq, handled);
}
}
-
- @Override
- public void sessionCreated(IInputMethodSession session) {
- // Stub -- not for use in the client.
- }
}
@Override
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 08bc0ac..2c19c0c 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -41,7 +41,8 @@
static final int HANDLE_UPDATE = 1;
static final int HANDLE_PROVIDER_CHANGED = 2;
- static final int HANDLE_VIEW_DATA_CHANGED = 3;
+ static final int HANDLE_PROVIDERS_CHANGED = 3;
+ static final int HANDLE_VIEW_DATA_CHANGED = 4;
final static Object sServiceLock = new Object();
static IAppWidgetService sService;
@@ -65,6 +66,11 @@
msg.sendToTarget();
}
+ public void providersChanged() {
+ Message msg = mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED);
+ msg.sendToTarget();
+ }
+
public void viewDataChanged(int appWidgetId, int viewId) {
Message msg = mHandler.obtainMessage(HANDLE_VIEW_DATA_CHANGED);
msg.arg1 = appWidgetId;
@@ -88,6 +94,10 @@
onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj);
break;
}
+ case HANDLE_PROVIDERS_CHANGED: {
+ onProvidersChanged();
+ break;
+ }
case HANDLE_VIEW_DATA_CHANGED: {
viewDataChanged(msg.arg1, msg.arg2);
break;
@@ -274,6 +284,14 @@
}
}
+ /**
+ * Called when the set of available widgets changes (ie. widget containing packages
+ * are added, updated or removed, or widget components are enabled or disabled.)
+ */
+ protected void onProvidersChanged() {
+ // Do nothing
+ }
+
void updateAppWidgetView(int appWidgetId, RemoteViews views) {
AppWidgetHostView v;
synchronized (mViews) {
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index c9603bf..020f051 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -304,6 +304,25 @@
}
}
+ @Override
+ protected void onQuitting() {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ mBroadcastReceiver = null;
+ mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
+ mBluetoothProfileServiceListener = null;
+ mOutgoingHandsfree = null;
+ mPbap = null;
+ mPbapService.close();
+ mPbapService = null;
+ mIncomingHid = null;
+ mOutgoingHid = null;
+ mIncomingHandsfree = null;
+ mOutgoingHandsfree = null;
+ mIncomingA2dp = null;
+ mOutgoingA2dp = null;
+ mBondedDevice = null;
+ }
+
private class BondedDevice extends State {
@Override
public void enter() {
@@ -416,26 +435,6 @@
case TRANSITION_TO_STABLE:
// ignore.
break;
- case SM_QUIT_CMD:
- mContext.unregisterReceiver(mBroadcastReceiver);
- mBroadcastReceiver = null;
- mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
- mBluetoothProfileServiceListener = null;
- mOutgoingHandsfree = null;
- mPbap = null;
- mPbapService.close();
- mPbapService = null;
- mIncomingHid = null;
- mOutgoingHid = null;
- mIncomingHandsfree = null;
- mOutgoingHandsfree = null;
- mIncomingA2dp = null;
- mOutgoingA2dp = null;
- mBondedDevice = null;
- // There is a problem in the State Machine code
- // where things are not cleaned up properly, when quit message
- // is handled so return NOT_HANDLED as a workaround.
- return NOT_HANDLED;
default:
return NOT_HANDLED;
}
@@ -1341,6 +1340,15 @@
return mDevice;
}
+ /**
+ * Quit the state machine, only to be called by BluetoothService.
+ *
+ * @hide
+ */
+ public void doQuit() {
+ this.quit();
+ }
+
private void log(String message) {
if (DBG) {
Log.i(TAG, "Device:" + mDevice + " Message:" + message);
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 19d13ef..20e8515 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -242,8 +242,10 @@
// abortNative(), so this lock should immediately acquire
mLock.writeLock().lock();
try {
- mSocketState = SocketState.CLOSED;
- destroyNative();
+ if (mSocketState != SocketState.CLOSED) {
+ mSocketState = SocketState.CLOSED;
+ destroyNative();
+ }
} finally {
mLock.writeLock().unlock();
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 621113d..2800930 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1379,6 +1379,7 @@
* description (action, category, etc) to match an
* {@link IntentFilter} published by a service.
* @param conn Receives information as the service is started and stopped.
+ * This must be a valid ServiceConnection object; it must not be null.
* @param flags Operation options for the binding. May be 0,
* {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
* {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
@@ -1414,7 +1415,7 @@
* stop at any time.
*
* @param conn The connection interface previously supplied to
- * bindService().
+ * bindService(). This parameter must not be null.
*
* @see #bindService
*/
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 50972e8..746bb84 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -571,7 +571,9 @@
* <li> {@link #EXTRA_INITIAL_INTENTS}
* <li> {@link #EXTRA_INTENT}
* <li> {@link #EXTRA_KEY_EVENT}
+ * <li> {@link #EXTRA_ORIGINATING_URL}
* <li> {@link #EXTRA_PHONE_NUMBER}
+ * <li> {@link #EXTRA_REFERRER}
* <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
* <li> {@link #EXTRA_REPLACING}
* <li> {@link #EXTRA_SHORTCUT_ICON}
@@ -1286,6 +1288,22 @@
= "android.intent.extra.NOT_UNKNOWN_SOURCE";
/**
+ * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the URL from which the local APK in the Intent
+ * data field originated from.
+ */
+ public static final String EXTRA_ORIGINATING_URL
+ = "android.intent.extra.ORIGINATING_URL";
+
+ /**
+ * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the HTTP referrer associated with the Intent
+ * data field or {@link #EXTRA_ORIGINATING_URL}.
+ */
+ public static final String EXTRA_REFERRER
+ = "android.intent.extra.REFERRER";
+
+ /**
* Used as a boolean extra field with {@link #ACTION_INSTALL_PACKAGE} to install a
* package. Tells the installer UI to skip the confirmation with the user
* if the .apk is replacing an existing one.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index e1434b3..cbabc7c 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -298,7 +298,6 @@
* activity's manifest.
*
* Default value is false (no support for RTL).
- * @hide
*/
public static final int FLAG_SUPPORTS_RTL = 1<<22;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 90b4247..0d87df5 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -41,6 +41,7 @@
import android.content.pm.UserInfo;
import android.content.pm.VerifierDeviceIdentity;
import android.net.Uri;
+import android.os.ParcelFileDescriptor;
import android.content.IntentSender;
/**
@@ -359,7 +360,8 @@
UserInfo createUser(in String name, int flags);
boolean removeUser(int userId);
- void updateUserName(int userId, String name);
+ void setUserName(int userId, String name);
+ ParcelFileDescriptor setUserIcon(int userId);
void installPackageWithVerification(in Uri packageURI, in IPackageInstallObserver observer,
int flags, in String installerPackageName, in Uri verificationURI,
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6de69b0..f9f7e2d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2646,7 +2646,7 @@
* @param name the new name for the user
* @hide
*/
- public abstract void updateUserName(int id, String name);
+ public abstract void setUserName(int id, String name);
/**
* Changes the user's properties specified by the flags.
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index ba5331c..68a7257 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -43,12 +43,18 @@
public int id;
public String name;
+ public String iconPath;
public int flags;
public UserInfo(int id, String name, int flags) {
+ this(id, name, null, flags);
+ }
+
+ public UserInfo(int id, String name, String iconPath, int flags) {
this.id = id;
this.name = name;
this.flags = flags;
+ this.iconPath = iconPath;
}
public boolean isPrimary() {
@@ -68,6 +74,7 @@
public UserInfo(UserInfo orig) {
name = orig.name;
+ iconPath = orig.iconPath;
id = orig.id;
flags = orig.flags;
}
@@ -84,6 +91,7 @@
public void writeToParcel(Parcel dest, int parcelableFlags) {
dest.writeInt(id);
dest.writeString(name);
+ dest.writeString(iconPath);
dest.writeInt(flags);
}
@@ -100,6 +108,7 @@
private UserInfo(Parcel source) {
id = source.readInt();
name = source.readString();
+ iconPath = source.readString();
flags = source.readInt();
}
}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 2df492e..281b843 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -469,13 +469,20 @@
* {@link android.view.ViewGroup}'s layout_width and layout_height
* attributes. This is only here for performance reasons; applications
* should use {@link #getDimensionPixelSize}.
- *
+ *
* @param index Index of the attribute to retrieve.
* @param name Textual name of attribute for error reporting.
*
* @return Attribute dimension value multiplied by the appropriate
* metric and truncated to integer pixels.
+ *
+ * @throws RuntimeException
+ * if this TypedArray does not contain an entry for <code>index</code>
+ *
+ * @deprecated Use {@link #getLayoutDimension(int, int)} instead.
+ *
*/
+ @Deprecated
public int getLayoutDimension(int index, String name) {
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 397a12a..cc3e34f 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -163,8 +163,21 @@
mRegisteredForPreDhcpNotification = true;
}
+ /**
+ * Quit the DhcpStateMachine.
+ *
+ * @hide
+ */
+ public void doQuit() {
+ quit();
+ }
+
class DefaultState extends State {
@Override
+ public void exit() {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ }
+ @Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch (message.what) {
@@ -172,10 +185,6 @@
Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
mDhcpRenewWakeLock.release();
break;
- case SM_QUIT_CMD:
- mContext.unregisterReceiver(mBroadcastReceiver);
- //let parent kill the state machine
- return NOT_HANDLED;
default:
Log.e(TAG, "Error! unhandled message " + message);
break;
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 28bd289..5197c9e 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -230,6 +230,10 @@
mNetworkInfo.setExtraInfo(mHwAddr);
}
}
+
+ // if a DHCP client had previously been started for this interface, then stop it
+ NetworkUtils.stopDhcp(mIface);
+
reconnect();
break;
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 438c536..2aa6fb5 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -71,9 +71,9 @@
public static final int FULL_WIFI_LOCK = 5;
/**
- * A constant indicating a scan wifi lock timer
+ * A constant indicating a wifi scan
*/
- public static final int SCAN_WIFI_LOCK = 6;
+ public static final int WIFI_SCAN = 6;
/**
* A constant indicating a wifi multicast timer
@@ -136,7 +136,7 @@
private static final String BATTERY_DATA = "bt";
private static final String BATTERY_DISCHARGE_DATA = "dc";
private static final String BATTERY_LEVEL_DATA = "lv";
- private static final String WIFI_LOCK_DATA = "wfl";
+ private static final String WIFI_DATA = "wfl";
private static final String MISC_DATA = "m";
private static final String SCREEN_BRIGHTNESS_DATA = "br";
private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
@@ -260,8 +260,8 @@
public abstract void noteWifiStoppedLocked();
public abstract void noteFullWifiLockAcquiredLocked();
public abstract void noteFullWifiLockReleasedLocked();
- public abstract void noteScanWifiLockAcquiredLocked();
- public abstract void noteScanWifiLockReleasedLocked();
+ public abstract void noteWifiScanStartedLocked();
+ public abstract void noteWifiScanStoppedLocked();
public abstract void noteWifiMulticastEnabledLocked();
public abstract void noteWifiMulticastDisabledLocked();
public abstract void noteAudioTurnedOnLocked();
@@ -270,7 +270,7 @@
public abstract void noteVideoTurnedOffLocked();
public abstract long getWifiRunningTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which);
- public abstract long getScanWifiLockTime(long batteryRealtime, int which);
+ public abstract long getWifiScanTime(long batteryRealtime, int which);
public abstract long getWifiMulticastTime(long batteryRealtime,
int which);
public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
@@ -453,7 +453,7 @@
public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
- public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<24;
+ public static final int STATE_WIFI_SCAN_FLAG = 1<<24;
public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
// These are on the lower bits used for the command; if they change
// we need to write another int of data.
@@ -859,7 +859,7 @@
new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"),
new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"),
new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"),
- new BitDescription(HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG, "wifi_scan_lock"),
+ new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan"),
new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"),
new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"),
new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"),
@@ -1326,15 +1326,15 @@
long rx = u.getTcpBytesReceived(which);
long tx = u.getTcpBytesSent(which);
long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
- long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
+ long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
- if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
+ if (fullWifiLockOnTime != 0 || wifiScanTime != 0
|| uidWifiRunningTime != 0) {
- dumpLine(pw, uid, category, WIFI_LOCK_DATA,
- fullWifiLockOnTime, scanWifiLockOnTime, uidWifiRunningTime);
+ dumpLine(pw, uid, category, WIFI_DATA,
+ fullWifiLockOnTime, wifiScanTime, uidWifiRunningTime);
}
if (u.hasUserActivity()) {
@@ -1692,7 +1692,7 @@
long tcpReceived = u.getTcpBytesReceived(which);
long tcpSent = u.getTcpBytesSent(which);
long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
- long scanWifiLockOnTime = u.getScanWifiLockTime(batteryRealtime, which);
+ long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
if (tcpReceived != 0 || tcpSent != 0) {
@@ -1723,7 +1723,7 @@
}
}
- if (fullWifiLockOnTime != 0 || scanWifiLockOnTime != 0
+ if (fullWifiLockOnTime != 0 || wifiScanTime != 0
|| uidWifiRunningTime != 0) {
sb.setLength(0);
sb.append(prefix); sb.append(" Wifi Running: ");
@@ -1731,12 +1731,12 @@
sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
whichBatteryRealtime)); sb.append(")\n");
sb.append(prefix); sb.append(" Full Wifi Lock: ");
- formatTimeMs(sb, fullWifiLockOnTime / 1000);
- sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
+ formatTimeMs(sb, fullWifiLockOnTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
whichBatteryRealtime)); sb.append(")\n");
- sb.append(prefix); sb.append(" Scan Wifi Lock: ");
- formatTimeMs(sb, scanWifiLockOnTime / 1000);
- sb.append("("); sb.append(formatRatioLocked(scanWifiLockOnTime,
+ sb.append(prefix); sb.append(" Wifi Scan: ");
+ formatTimeMs(sb, wifiScanTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
whichBatteryRealtime)); sb.append(")");
pw.println(sb.toString());
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index d2050b7..59d0f7a 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -39,11 +39,12 @@
public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
public static final long TRACE_TAG_AUDIO = 1L << 8;
public static final long TRACE_TAG_VIDEO = 1L << 9;
+ public static final long TRACE_TAG_CAMERA = 1L << 10;
public static final int TRACE_FLAGS_START_BIT = 1;
public static final String[] TRACE_TAGS = {
"Graphics", "Input", "View", "WebView", "Window Manager",
- "Activity Manager", "Sync Manager", "Audio", "Video",
+ "Activity Manager", "Sync Manager", "Audio", "Video", "Camera",
};
public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a90dd8c..d9f6bf1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4279,6 +4279,9 @@
/** Timeout for package verification. {@hide} */
public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
+ /** Default response code for package verification. {@hide} */
+ public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
+
/** {@hide} */
public static final String
READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT = "read_external_storage_enforced_default";
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 97c0209..6296b11 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2448,7 +2448,7 @@
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state == null) return;
- state.quit();
+ state.doQuit();
mDeviceProfileState.remove(address);
}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index c783e6a..2411cec 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -29,9 +29,12 @@
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
+import android.os.Binder;
import android.os.Process;
+import android.os.UserId;
import android.provider.Settings;
import android.util.Log;
+import android.util.SparseArray;
import java.util.List;
@@ -48,7 +51,7 @@
private final Context mContext;
// This field is initialized lazily in getSearchables(), and then never modified.
- private Searchables mSearchables;
+ private SparseArray<Searchables> mSearchables;
private ContentObserver mGlobalSearchObserver;
@@ -66,14 +69,24 @@
mContext.getContentResolver());
}
- private synchronized Searchables getSearchables() {
+ private synchronized Searchables getSearchables(int userId) {
if (mSearchables == null) {
- Log.i(TAG, "Building list of searchable activities");
new MyPackageMonitor().register(mContext, null, true);
- mSearchables = new Searchables(mContext);
- mSearchables.buildSearchableList();
+ mSearchables = new SparseArray<Searchables>();
}
- return mSearchables;
+ Searchables searchables = mSearchables.get(userId);
+
+ long origId = Binder.clearCallingIdentity();
+ boolean userExists = mContext.getPackageManager().getUser(userId) != null;
+ Binder.restoreCallingIdentity(origId);
+
+ if (searchables == null && userExists) {
+ Log.i(TAG, "Building list of searchable activities for userId=" + userId);
+ searchables = new Searchables(mContext, userId);
+ searchables.buildSearchableList();
+ mSearchables.append(userId, searchables);
+ }
+ return searchables;
}
/**
@@ -87,7 +100,7 @@
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
mContext.unregisterReceiver(BootCompletedReceiver.this);
- getSearchables();
+ getSearchables(0);
}
}.start();
}
@@ -109,8 +122,12 @@
}
private void updateSearchables() {
- // Update list of searchable activities
- getSearchables().buildSearchableList();
+ synchronized (SearchManagerService.this) {
+ // Update list of searchable activities
+ for (int i = 0; i < mSearchables.size(); i++) {
+ getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ }
+ }
// Inform all listeners that the list of searchables has been updated.
Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
@@ -132,7 +149,11 @@
@Override
public void onChange(boolean selfChange) {
- getSearchables().buildSearchableList();
+ synchronized (SearchManagerService.this) {
+ for (int i = 0; i < mSearchables.size(); i++) {
+ getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ }
+ }
Intent intent = new Intent(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
mContext.sendBroadcast(intent);
@@ -156,32 +177,32 @@
Log.e(TAG, "getSearchableInfo(), activity == null");
return null;
}
- return getSearchables().getSearchableInfo(launchActivity);
+ return getSearchables(UserId.getCallingUserId()).getSearchableInfo(launchActivity);
}
/**
* Returns a list of the searchable activities that can be included in global search.
*/
public List<SearchableInfo> getSearchablesInGlobalSearch() {
- return getSearchables().getSearchablesInGlobalSearchList();
+ return getSearchables(UserId.getCallingUserId()).getSearchablesInGlobalSearchList();
}
public List<ResolveInfo> getGlobalSearchActivities() {
- return getSearchables().getGlobalSearchActivities();
+ return getSearchables(UserId.getCallingUserId()).getGlobalSearchActivities();
}
/**
* Gets the name of the global search activity.
*/
public ComponentName getGlobalSearchActivity() {
- return getSearchables().getGlobalSearchActivity();
+ return getSearchables(UserId.getCallingUserId()).getGlobalSearchActivity();
}
/**
* Gets the name of the web search activity.
*/
public ComponentName getWebSearchActivity() {
- return getSearchables().getWebSearchActivity();
+ return getSearchables(UserId.getCallingUserId()).getWebSearchActivity();
}
}
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index f24d52f..4e00ef9 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -16,6 +16,7 @@
package android.server.search;
+import android.app.AppGlobals;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ComponentName;
@@ -23,9 +24,11 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.os.RemoteException;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
@@ -38,6 +41,7 @@
/**
* This class maintains the information about all searchable activities.
+ * This is a hidden class.
*/
public class Searchables {
@@ -65,12 +69,18 @@
public static String ENHANCED_GOOGLE_SEARCH_COMPONENT_NAME =
"com.google.android.providers.enhancedgooglesearch/.Launcher";
+ // Cache the package manager instance
+ private IPackageManager mPm;
+ // User for which this Searchables caches information
+ private int mUserId;
+
/**
*
* @param context Context to use for looking up activities etc.
*/
- public Searchables (Context context) {
+ public Searchables (Context context, int userId) {
mContext = context;
+ mUserId = userId;
}
/**
@@ -195,16 +205,14 @@
ArrayList<SearchableInfo> newSearchablesInGlobalSearchList
= new ArrayList<SearchableInfo>();
- final PackageManager pm = mContext.getPackageManager();
-
// Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers.
List<ResolveInfo> searchList;
final Intent intent = new Intent(Intent.ACTION_SEARCH);
- searchList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
+ searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
List<ResolveInfo> webSearchInfoList;
final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
- webSearchInfoList = pm.queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
+ webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
// analyze each one, generate a Searchables record, and record
if (searchList != null || webSearchInfoList != null) {
@@ -262,10 +270,8 @@
// Step 1 : Query the package manager for a list
// of activities that can handle the GLOBAL_SEARCH intent.
Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);
- PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> activities =
- pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
-
+ queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (activities != null && !activities.isEmpty()) {
// Step 2: Rank matching activities according to our heuristics.
Collections.sort(activities, GLOBAL_SEARCH_RANKER);
@@ -301,10 +307,8 @@
Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);
intent.setComponent(globalSearch);
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> activities =
- pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
-
+ List<ResolveInfo> activities = queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
if (activities != null && !activities.isEmpty()) {
return true;
}
@@ -374,9 +378,8 @@
}
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.setPackage(globalSearchActivity.getPackageName());
- PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> activities =
- pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (activities != null && !activities.isEmpty()) {
ActivityInfo ai = activities.get(0).activityInfo;
@@ -387,6 +390,22 @@
return null;
}
+ private List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+ if (mPm == null) {
+ mPm = AppGlobals.getPackageManager();
+ }
+ List<ResolveInfo> activities = null;
+ try {
+ activities =
+ mPm.queryIntentActivities(intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ flags, mUserId);
+ } catch (RemoteException re) {
+ // Local call
+ }
+ return activities;
+ }
+
/**
* Returns the list of searchable activities.
*/
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index be2840b..bbaa173 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -22,6 +22,7 @@
/**
* Some objects that implement TextDirectionHeuristic.
+ *
* @hide
*/
public class TextDirectionHeuristics {
diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java
index 93f5cd3..60526e1 100644
--- a/core/java/android/util/LocaleUtil.java
+++ b/core/java/android/util/LocaleUtil.java
@@ -24,7 +24,6 @@
/**
* Various utilities for Locales
*
- * @hide
*/
public class LocaleUtil {
@@ -41,8 +40,7 @@
* {@link View#LAYOUT_DIRECTION_LTR} or
* {@link View#LAYOUT_DIRECTION_RTL}.
*
- * Warning: this code does not support vertical scripts.
- * @hide
+ * Be careful: this code will need to be updated when vertical scripts will be supported
*/
public static int getLayoutDirectionFromLocale(Locale locale) {
if (locale != null && !locale.equals(Locale.ROOT)) {
@@ -68,7 +66,8 @@
* {@link View#LAYOUT_DIRECTION_LTR} or
* {@link View#LAYOUT_DIRECTION_RTL}.
*
- * Warning: this code does not support vertical scripts.
+ * Be careful: this code will need to be updated when vertical scripts will be supported
+ *
* @hide
*/
private static int getLayoutDirectionFromFirstChar(Locale locale) {
diff --git a/core/java/android/view/Gravity.java b/core/java/android/view/Gravity.java
index 4547aa6..f031fe7 100644
--- a/core/java/android/view/Gravity.java
+++ b/core/java/android/view/Gravity.java
@@ -155,7 +155,6 @@
*
* @see {@link View#LAYOUT_DIRECTION_LTR}
* @see {@link View#LAYOUT_DIRECTION_RTL}
- * @hide
*/
public static void apply(int gravity, int w, int h, Rect container,
Rect outRect, int layoutDirection) {
@@ -293,7 +292,6 @@
*
* @see {@link View#LAYOUT_DIRECTION_LTR}
* @see {@link View#LAYOUT_DIRECTION_RTL}
- * @hide
*/
public static void apply(int gravity, int w, int h, Rect container,
int xAdj, int yAdj, Rect outRect, int layoutDirection) {
@@ -374,7 +372,6 @@
*
* @see {@link View#LAYOUT_DIRECTION_LTR}
* @see {@link View#LAYOUT_DIRECTION_RTL}
- * @hide
*/
public static void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) {
int absGravity = getAbsoluteGravity(gravity, layoutDirection);
@@ -411,7 +408,6 @@
* @param gravity The gravity to convert to absolute (horizontal) values.
* @param layoutDirection The layout direction.
* @return gravity converted to absolute (horizontal) values.
- * @hide
*/
public static int getAbsoluteGravity(int gravity, int layoutDirection) {
int result = gravity;
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 26a5b26..f692e05 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.Message;
import android.widget.FrameLayout;
+import com.android.internal.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -43,20 +44,20 @@
*
* <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService
* (Context.LAYOUT_INFLATER_SERVICE);</pre>
- *
+ *
* <p>
* To create a new LayoutInflater with an additional {@link Factory} for your
* own views, you can use {@link #cloneInContext} to clone an existing
* ViewFactory, and then call {@link #setFactory} on it to include your
* Factory.
- *
+ *
* <p>
* For performance reasons, view inflation relies heavily on pre-processing of
* XML files that is done at build time. Therefore, it is not currently possible
* to use LayoutInflater with an XmlPullParser over a plain XML file at runtime;
* it only works with an XmlPullParser returned from a compiled resource
* (R.<em>something</em> file.)
- *
+ *
* @see Context#getSystemService
*/
public abstract class LayoutInflater {
@@ -82,7 +83,7 @@
private static final HashMap<String, Constructor<? extends View>> sConstructorMap =
new HashMap<String, Constructor<? extends View>>();
-
+
private HashMap<String, Boolean> mFilterMap;
private static final String TAG_MERGE = "merge";
@@ -93,36 +94,36 @@
/**
* Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
* to be inflated.
- *
+ *
*/
public interface Filter {
/**
* Hook to allow clients of the LayoutInflater to restrict the set of Views
* that are allowed to be inflated.
- *
+ *
* @param clazz The class object for the View that is about to be inflated
- *
+ *
* @return True if this class is allowed to be inflated, or false otherwise
*/
@SuppressWarnings("unchecked")
boolean onLoadClass(Class clazz);
}
-
+
public interface Factory {
/**
* Hook you can supply that is called when inflating from a LayoutInflater.
* You can use this to customize the tag names available in your XML
* layout files.
- *
+ *
* <p>
* Note that it is good practice to prefix these custom names with your
* package (i.e., com.coolcompany.apps) to avoid conflicts with system
* names.
- *
+ *
* @param name Tag name to be inflated.
* @param context The context the view is being created in.
* @param attrs Inflation attributes as specified in XML file.
- *
+ *
* @return View Newly created view. Return null for the default
* behavior.
*/
@@ -150,14 +151,14 @@
private static class FactoryMerger implements Factory2 {
private final Factory mF1, mF2;
private final Factory2 mF12, mF22;
-
+
FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) {
mF1 = f1;
mF2 = f2;
mF12 = f12;
mF22 = f22;
}
-
+
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = mF1.onCreateView(name, context, attrs);
if (v != null) return v;
@@ -172,13 +173,13 @@
: mF2.onCreateView(name, context, attrs);
}
}
-
+
/**
* Create a new LayoutInflater instance associated with a particular Context.
* Applications will almost always want to use
* {@link Context#getSystemService Context.getSystemService()} to retrieve
* the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}.
- *
+ *
* @param context The Context in which this LayoutInflater will create its
* Views; most importantly, this supplies the theme from which the default
* values for their attributes are retrieved.
@@ -191,7 +192,7 @@
* Create a new LayoutInflater instance that is a copy of an existing
* LayoutInflater, optionally with its Context changed. For use in
* implementing {@link #cloneInContext}.
- *
+ *
* @param original The original LayoutInflater to copy.
* @param newContext The new Context to use.
*/
@@ -202,7 +203,7 @@
mPrivateFactory = original.mPrivateFactory;
mFilter = original.mFilter;
}
-
+
/**
* Obtains the LayoutInflater from the given context.
*/
@@ -220,15 +221,15 @@
* pointing to a different Context than the original. This is used by
* {@link ContextThemeWrapper} to create a new LayoutInflater to go along
* with the new Context theme.
- *
+ *
* @param newContext The new Context to associate with the new LayoutInflater.
* May be the same as the original Context if desired.
- *
+ *
* @return Returns a brand spanking new LayoutInflater object associated with
* the given Context.
*/
public abstract LayoutInflater cloneInContext(Context newContext);
-
+
/**
* Return the context we are running in, for access to resources, class
* loader, etc.
@@ -264,7 +265,7 @@
* called on each element name as the xml is parsed. If the factory returns
* a View, that is added to the hierarchy. If it returns null, the next
* factory default {@link #onCreateView} method is called.
- *
+ *
* <p>If you have an existing
* LayoutInflater and want to add your own factory to it, use
* {@link #cloneInContext} to clone the existing instance and then you
@@ -320,13 +321,13 @@
public Filter getFilter() {
return mFilter;
}
-
+
/**
* Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated
* which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will
* throw an {@link InflateException}. This filter will replace any previous filter set on this
* LayoutInflater.
- *
+ *
* @param filter The Filter which restricts the set of Views that are allowed to be inflated.
* This filter will replace any previous filter set on this LayoutInflater.
*/
@@ -340,7 +341,7 @@
/**
* Inflate a new view hierarchy from the specified xml resource. Throws
* {@link InflateException} if there is an error.
- *
+ *
* @param resource ID for an XML layout resource to load (e.g.,
* <code>R.layout.main_page</code>)
* @param root Optional view to be the parent of the generated hierarchy.
@@ -360,7 +361,7 @@
* reasons, view inflation relies heavily on pre-processing of XML files
* that is done at build time. Therefore, it is not currently possible to
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
- *
+ *
* @param parser XML dom node containing the description of the view
* hierarchy.
* @param root Optional view to be the parent of the generated hierarchy.
@@ -375,7 +376,7 @@
/**
* Inflate a new view hierarchy from the specified xml resource. Throws
* {@link InflateException} if there is an error.
- *
+ *
* @param resource ID for an XML layout resource to load (e.g.,
* <code>R.layout.main_page</code>)
* @param root Optional view to be the parent of the generated hierarchy (if
@@ -407,7 +408,7 @@
* reasons, view inflation relies heavily on pre-processing of XML files
* that is done at build time. Therefore, it is not currently possible to
* use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
- *
+ *
* @param parser XML dom node containing the description of the view
* hierarchy.
* @param root Optional view to be the parent of the generated hierarchy (if
@@ -442,7 +443,7 @@
}
final String name = parser.getName();
-
+
if (DEBUG) {
System.out.println("**************************");
System.out.println("Creating root view: "
@@ -528,17 +529,17 @@
* Low-level function for instantiating a view by name. This attempts to
* instantiate a view class of the given <var>name</var> found in this
* LayoutInflater's ClassLoader.
- *
+ *
* <p>
* There are two things that can happen in an error case: either the
* exception describing the error will be thrown, or a null will be
* returned. You must deal with both possibilities -- the former will happen
* the first time createView() is called for a class of a particular name,
* the latter every time there-after for that class name.
- *
+ *
* @param name The full name of the class to be instantiated.
* @param attrs The XML attributes supplied for this instance.
- *
+ *
* @return View The newly instantiated view, or null.
*/
public final View createView(String name, String prefix, AttributeSet attrs)
@@ -551,7 +552,7 @@
// Class not found in the cache, see if it's real, and try to add it
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
-
+
if (mFilter != null && clazz != null) {
boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
@@ -569,7 +570,7 @@
// New class -- remember whether it is allowed
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
-
+
boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
mFilterMap.put(name, allowed);
if (!allowed) {
@@ -632,10 +633,10 @@
* given the xml element name. Override it to handle custom view objects. If
* you override this in your subclass be sure to call through to
* super.onCreateView(name) for names you do not recognize.
- *
+ *
* @param name The fully qualified class name of the View to be create.
* @param attrs An AttributeSet of attributes to apply to the View.
- *
+ *
* @return View The View created.
*/
protected View onCreateView(String name, AttributeSet attrs)
@@ -679,7 +680,7 @@
if (view == null && mPrivateFactory != null) {
view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
}
-
+
if (view == null) {
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
@@ -726,7 +727,7 @@
}
final String name = parser.getName();
-
+
if (TAG_REQUEST_FOCUS.equals(name)) {
parseRequestFocus(parser, parent);
} else if (TAG_INCLUDE.equals(name)) {
@@ -741,7 +742,7 @@
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
rInflate(parser, view, attrs, true);
- viewGroup.addView(view, params);
+ viewGroup.addView(view, params);
} else {
final View view = createViewFromTag(parent, name, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
@@ -810,21 +811,14 @@
// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
- // During a layoutparams generation, a runtime exception is thrown
- // if either layout_width or layout_height is missing. We catch
- // this exception and set localParams accordingly: true means we
- // successfully loaded layout params from the <include /> tag,
- // false means we need to rely on the included layout params.
- ViewGroup.LayoutParams params = null;
- try {
- params = group.generateLayoutParams(attrs);
- } catch (RuntimeException e) {
- params = group.generateLayoutParams(childAttrs);
- } finally {
- if (params != null) {
- view.setLayoutParams(params);
- }
- }
+ TypedArray ta = getContext().obtainStyledAttributes(attrs,
+ R.styleable.ViewGroup_Layout);
+ boolean definesBothWidthAndHeight =
+ ta.hasValue(R.styleable.ViewGroup_Layout_layout_width) &&
+ ta.hasValue(R.styleable.ViewGroup_Layout_layout_height);
+ AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs;
+ view.setLayoutParams(group.generateLayoutParams(attributes));
+ ta.recycle();
// Inflate all children.
rInflate(childParser, view, childAttrs, true);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b1caa2f..25f6516 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -343,9 +343,10 @@
* Padding can be used to offset the content of the view by a specific amount of
* pixels. For instance, a left padding of 2 will push the view's content by
* 2 pixels to the right of the left edge. Padding can be set using the
- * {@link #setPadding(int, int, int, int)} method and queried by calling
- * {@link #getPaddingLeft()}, {@link #getPaddingTop()}, {@link #getPaddingRight()},
- * {@link #getPaddingBottom()}.
+ * {@link #setPadding(int, int, int, int)} or {@link #setPaddingRelative(int, int, int, int)}
+ * method and queried by calling {@link #getPaddingLeft()}, {@link #getPaddingTop()},
+ * {@link #getPaddingRight()}, {@link #getPaddingBottom()}, {@link #getPaddingStart()},
+ * {@link #getPaddingEnd()}.
* </p>
*
* <p>
@@ -627,6 +628,8 @@
* @attr ref android.R.styleable#View_paddingLeft
* @attr ref android.R.styleable#View_paddingRight
* @attr ref android.R.styleable#View_paddingTop
+ * @attr ref android.R.styleable#View_paddingStart
+ * @attr ref android.R.styleable#View_paddingEnd
* @attr ref android.R.styleable#View_saveEnabled
* @attr ref android.R.styleable#View_rotation
* @attr ref android.R.styleable#View_rotationX
@@ -648,6 +651,7 @@
* @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
* @attr ref android.R.styleable#View_soundEffectsEnabled
* @attr ref android.R.styleable#View_tag
+ * @attr ref android.R.styleable#View_textAlignment
* @attr ref android.R.styleable#View_transformPivotX
* @attr ref android.R.styleable#View_transformPivotY
* @attr ref android.R.styleable#View_translationX
@@ -656,7 +660,7 @@
*
* @see android.view.ViewGroup
*/
-public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Callback,
+public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
private static final boolean DBG = false;
@@ -1801,28 +1805,24 @@
/**
* Horizontal layout direction of this view is from Left to Right.
* Use with {@link #setLayoutDirection}.
- * @hide
*/
public static final int LAYOUT_DIRECTION_LTR = 0;
/**
* Horizontal layout direction of this view is from Right to Left.
* Use with {@link #setLayoutDirection}.
- * @hide
*/
public static final int LAYOUT_DIRECTION_RTL = 1;
/**
* Horizontal layout direction of this view is inherited from its parent.
* Use with {@link #setLayoutDirection}.
- * @hide
*/
public static final int LAYOUT_DIRECTION_INHERIT = 2;
/**
* Horizontal layout direction of this view is from deduced from the default language
* script for the locale. Use with {@link #setLayoutDirection}.
- * @hide
*/
public static final int LAYOUT_DIRECTION_LOCALE = 3;
@@ -1887,7 +1887,6 @@
/**
* Text direction is inherited thru {@link ViewGroup}
- * @hide
*/
public static final int TEXT_DIRECTION_INHERIT = 0;
@@ -1895,7 +1894,6 @@
* Text direction is using "first strong algorithm". The first strong directional character
* determines the paragraph direction. If there is no strong directional character, the
* paragraph direction is the view's resolved layout direction.
- * @hide
*/
public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
@@ -1903,31 +1901,26 @@
* Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
* any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
* If there are neither, the paragraph direction is the view's resolved layout direction.
- * @hide
*/
public static final int TEXT_DIRECTION_ANY_RTL = 2;
/**
* Text direction is forced to LTR.
- * @hide
*/
public static final int TEXT_DIRECTION_LTR = 3;
/**
* Text direction is forced to RTL.
- * @hide
*/
public static final int TEXT_DIRECTION_RTL = 4;
/**
* Text direction is coming from the system Locale.
- * @hide
*/
public static final int TEXT_DIRECTION_LOCALE = 5;
/**
* Default text direction is inherited
- * @hide
*/
protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
@@ -1985,7 +1978,6 @@
/*
* Default text alignment. The text alignment of this View is inherited from its parent.
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_INHERIT = 0;
@@ -1994,7 +1986,6 @@
* ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s text direction.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_GRAVITY = 1;
@@ -2002,7 +1993,6 @@
* Align to the start of the paragraph, e.g. ALIGN_NORMAL.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_TEXT_START = 2;
@@ -2010,7 +2000,6 @@
* Align to the end of the paragraph, e.g. ALIGN_OPPOSITE.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_TEXT_END = 3;
@@ -2018,7 +2007,6 @@
* Center the paragraph, e.g. ALIGN_CENTER.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_CENTER = 4;
@@ -2027,7 +2015,6 @@
* layoutDirection is LTR, and ALIGN_RIGHT otherwise.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_VIEW_START = 5;
@@ -2036,13 +2023,11 @@
* layoutDirection is LTR, and ALIGN_LEFT otherwise.
*
* Use with {@link #setTextAlignment(int)}
- * @hide
*/
public static final int TEXT_ALIGNMENT_VIEW_END = 6;
/**
* Default text alignment is inherited
- * @hide
*/
protected static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
@@ -3881,6 +3866,15 @@
scrollabilityCache.scrollBar.setAlwaysDrawVerticalTrack(true);
}
+ // Apply layout direction to the new Drawables if needed
+ final int layoutDirection = getResolvedLayoutDirection();
+ if (track != null) {
+ track.setLayoutDirection(layoutDirection);
+ }
+ if (thumb != null) {
+ thumb.setLayoutDirection(layoutDirection);
+ }
+
// Re-apply user/background padding so that scrollbar(s) get added
resolvePadding();
}
@@ -5652,9 +5646,7 @@
* {@link #LAYOUT_DIRECTION_RTL},
* {@link #LAYOUT_DIRECTION_INHERIT} or
* {@link #LAYOUT_DIRECTION_LOCALE}.
- *
* @attr ref android.R.styleable#View_layoutDirection
- * @hide
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "LTR"),
@@ -5676,7 +5668,6 @@
* {@link #LAYOUT_DIRECTION_LOCALE}.
*
* @attr ref android.R.styleable#View_layoutDirection
- * @hide
*/
@RemotableViewMethod
public void setLayoutDirection(int layoutDirection) {
@@ -5696,7 +5687,6 @@
*
* @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
* {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
- * @hide
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
@@ -5716,7 +5706,6 @@
* layout attribute and/or the inherited value from the parent
*
* @return true if the layout is right-to-left.
- * @hide
*/
@ViewDebug.ExportedProperty(category = "layout")
public boolean isLayoutRtl() {
@@ -11483,7 +11472,6 @@
* Resolve and cache the layout direction. LTR is set initially. This is implicitly supposing
* that the parent directionality can and will be resolved before its children.
* Will call {@link View#onResolvedLayoutDirectionChanged} when resolution is done.
- * @hide
*/
public void resolveLayoutDirection() {
// Clear any previous layout direction resolution
@@ -11528,14 +11516,12 @@
* Called when layout direction has been resolved.
*
* The default implementation does nothing.
- * @hide
*/
public void onResolvedLayoutDirectionChanged() {
}
/**
* Resolve padding depending on layout direction.
- * @hide
*/
public void resolvePadding() {
// If the user specified the absolute padding (either with android:padding or
@@ -11595,7 +11581,6 @@
*
* @see {@link #LAYOUT_DIRECTION_LTR}
* @see {@link #LAYOUT_DIRECTION_RTL}
- * @hide
*/
public void onPaddingChanged(int layoutDirection) {
}
@@ -11604,7 +11589,6 @@
* Check if layout direction resolution can be done.
*
* @return true if layout direction resolution can be done otherwise return false.
- * @hide
*/
public boolean canResolveLayoutDirection() {
switch (getLayoutDirection()) {
@@ -11618,7 +11602,6 @@
/**
* Reset the resolved layout direction. Will call {@link View#onResolvedLayoutDirectionReset}
* when reset is done.
- * @hide
*/
public void resetResolvedLayoutDirection() {
// Reset the current resolved bits
@@ -11635,7 +11618,6 @@
* resolved layout direction, or to inform child views that inherit their layout direction.
*
* The default implementation does nothing.
- * @hide
*/
public void onResolvedLayoutDirectionReset() {
}
@@ -11645,7 +11627,6 @@
*
* @param locale Locale to check
* @return true if the Locale uses an RTL script.
- * @hide
*/
protected static boolean isLayoutDirectionRtl(Locale locale) {
return (LAYOUT_DIRECTION_RTL == LocaleUtil.getLayoutDirectionFromLocale(locale));
@@ -13951,13 +13932,29 @@
}
/**
- * Return the layout direction of a given Drawable.
- *
- * @param who the Drawable to query
- * @hide
- */
- public int getResolvedLayoutDirection(Drawable who) {
- return (who == mBackground) ? getResolvedLayoutDirection() : LAYOUT_DIRECTION_DEFAULT;
+ * Resolve the Drawables depending on the layout direction. This is implicitly supposing
+ * that the View directionality can and will be resolved before its Drawables.
+ *
+ * Will call {@link View#onResolveDrawables} when resolution is done.
+ */
+ public void resolveDrawables() {
+ if (mBackground != null) {
+ mBackground.setLayoutDirection(getResolvedLayoutDirection());
+ }
+ onResolveDrawables(getResolvedLayoutDirection());
+ }
+
+ /**
+ * Called when layout direction has been resolved.
+ *
+ * The default implementation does nothing.
+ *
+ * @param layoutDirection The resolved layout direction.
+ *
+ * @see {@link #LAYOUT_DIRECTION_LTR}
+ * @see {@link #LAYOUT_DIRECTION_RTL}
+ */
+ public void onResolveDrawables(int layoutDirection) {
}
/**
@@ -14226,8 +14223,9 @@
padding = new Rect();
sThreadLocal.set(padding);
}
+ background.setLayoutDirection(getResolvedLayoutDirection());
if (background.getPadding(padding)) {
- switch (background.getResolvedLayoutDirectionSelf()) {
+ switch (background.getLayoutDirection()) {
case LAYOUT_DIRECTION_RTL:
setPadding(padding.right, padding.top, padding.left, padding.bottom);
break;
@@ -14390,13 +14388,19 @@
/**
* Sets the relative padding. The view may add on the space required to display
* the scrollbars, depending on the style and visibility of the scrollbars.
+ * So the values returned from {@link #getPaddingStart}, {@link #getPaddingTop},
+ * {@link #getPaddingEnd} and {@link #getPaddingBottom} may be different
* from the values set in this call.
*
+ * @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingBottom
+ * @attr ref android.R.styleable#View_paddingStart
+ * @attr ref android.R.styleable#View_paddingEnd
+ * @attr ref android.R.styleable#View_paddingTop
* @param start the start padding in pixels
* @param top the top padding in pixels
* @param end the end padding in pixels
* @param bottom the bottom padding in pixels
- * @hide
*/
public void setPaddingRelative(int start, int top, int end, int bottom) {
mUserPaddingStart = start;
@@ -14450,7 +14454,6 @@
* required to display the scrollbars as well.
*
* @return the start padding in pixels
- * @hide
*/
public int getPaddingStart() {
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
@@ -14474,7 +14477,6 @@
* required to display the scrollbars as well.
*
* @return the end padding in pixels
- * @hide
*/
public int getPaddingEnd() {
return (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
@@ -14483,10 +14485,11 @@
/**
* Return if the padding as been set thru relative values
- * {@link #setPaddingRelative(int, int, int, int)}
+ * {@link #setPaddingRelative(int, int, int, int)} or thru
+ * @attr ref android.R.styleable#View_paddingStart or
+ * @attr ref android.R.styleable#View_paddingEnd
*
* @return true if the padding is relative or false if it is not.
- * @hide
*/
public boolean isPaddingRelative() {
return mUserPaddingRelative;
@@ -16285,7 +16288,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE}
- * @hide
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
@@ -16310,7 +16312,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE}
- * @hide
*/
public void setTextDirection(int textDirection) {
if (getTextDirection() != textDirection) {
@@ -16340,7 +16341,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE}
- * @hide
*/
public int getResolvedTextDirection() {
// The text direction will be resolved only if needed
@@ -16353,7 +16353,6 @@
/**
* Resolve the text direction. Will call {@link View#onResolvedTextDirectionChanged} when
* resolution is done.
- * @hide
*/
public void resolveTextDirection() {
// Reset any previous text direction resolution
@@ -16414,7 +16413,6 @@
* resolution should override this method.
*
* The default implementation does nothing.
- * @hide
*/
public void onResolvedTextDirectionChanged() {
}
@@ -16423,7 +16421,6 @@
* Check if text direction resolution can be done.
*
* @return true if text direction resolution can be done otherwise return false.
- * @hide
*/
public boolean canResolveTextDirection() {
switch (getTextDirection()) {
@@ -16438,7 +16435,6 @@
* Reset resolved text direction. Text direction can be resolved with a call to
* getResolvedTextDirection(). Will call {@link View#onResolvedTextDirectionReset} when
* reset is done.
- * @hide
*/
public void resetResolvedTextDirection() {
mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
@@ -16449,7 +16445,6 @@
* Called when text direction is reset. Subclasses that care about text direction reset should
* override this method and do a reset of the text direction of their children. The default
* implementation does nothing.
- * @hide
*/
public void onResolvedTextDirectionReset() {
}
@@ -16467,7 +16462,6 @@
* {@link #TEXT_ALIGNMENT_TEXT_END},
* {@link #TEXT_ALIGNMENT_VIEW_START},
* {@link #TEXT_ALIGNMENT_VIEW_END}
- * @hide
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
@@ -16496,7 +16490,6 @@
* {@link #TEXT_ALIGNMENT_VIEW_END}
*
* @attr ref android.R.styleable#View_textAlignment
- * @hide
*/
public void setTextAlignment(int textAlignment) {
if (textAlignment != getTextAlignment()) {
@@ -16526,7 +16519,6 @@
* {@link #TEXT_ALIGNMENT_TEXT_END},
* {@link #TEXT_ALIGNMENT_VIEW_START},
* {@link #TEXT_ALIGNMENT_VIEW_END}
- * @hide
*/
@ViewDebug.ExportedProperty(category = "text", mapping = {
@ViewDebug.IntToString(from = TEXT_ALIGNMENT_INHERIT, to = "INHERIT"),
@@ -16548,7 +16540,6 @@
/**
* Resolve the text alignment. Will call {@link View#onResolvedTextAlignmentChanged} when
* resolution is done.
- * @hide
*/
public void resolveTextAlignment() {
// Reset any previous text alignment resolution
@@ -16613,7 +16604,6 @@
* Check if text alignment resolution can be done.
*
* @return true if text alignment resolution can be done otherwise return false.
- * @hide
*/
public boolean canResolveTextAlignment() {
switch (getTextAlignment()) {
@@ -16629,7 +16619,6 @@
* resolution should override this method.
*
* The default implementation does nothing.
- * @hide
*/
public void onResolvedTextAlignmentChanged() {
}
@@ -16638,7 +16627,6 @@
* Reset resolved text alignment. Text alignment can be resolved with a call to
* getResolvedTextAlignment(). Will call {@link View#onResolvedTextAlignmentReset} when
* reset is done.
- * @hide
*/
public void resetResolvedTextAlignment() {
// Reset any previous text alignment resolution
@@ -16650,7 +16638,6 @@
* Called when text alignment is reset. Subclasses that care about text alignment reset should
* override this method and do a reset of the text alignment of their children. The default
* implementation does nothing.
- * @hide
*/
public void onResolvedTextAlignmentReset() {
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index dd671dc..00d4fc7 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -255,6 +255,35 @@
boolean retrieveReturn() default false;
}
+ /**
+ * Allows a View to inject custom children into HierarchyViewer. For example,
+ * WebView uses this to add its internal layer tree as a child to itself
+ * @hide
+ */
+ public interface HierarchyHandler {
+ /**
+ * Dumps custom children to hierarchy viewer.
+ * See ViewDebug.dumpViewWithProperties(Context, View, BufferedWriter, int)
+ * for the format
+ *
+ * An empty implementation should simply do nothing
+ *
+ * @param out The output writer
+ * @param level The indentation level
+ */
+ public void dumpViewHierarchyWithProperties(BufferedWriter out, int level);
+
+ /**
+ * Returns a View to enable grabbing screenshots from custom children
+ * returned in dumpViewHierarchyWithProperties.
+ *
+ * @param className The className of the view to find
+ * @param hashCode The hashCode of the view to find
+ * @return the View to capture from, or null if not found
+ */
+ public View findHierarchyView(String className, int hashCode);
+ }
+
private static HashMap<Class<?>, Method[]> mCapturedViewMethodsForClasses = null;
private static HashMap<Class<?>, Field[]> mCapturedViewFieldsForClasses = null;
@@ -759,6 +788,13 @@
} else if (isRequestedView(view, className, hashCode)) {
return view;
}
+ if (view instanceof HierarchyHandler) {
+ final View found = ((HierarchyHandler)view)
+ .findHierarchyView(className, hashCode);
+ if (found != null) {
+ return found;
+ }
+ }
}
return null;
@@ -783,6 +819,9 @@
dumpViewWithProperties(context, view, out, level + 1);
}
}
+ if (group instanceof HierarchyHandler) {
+ ((HierarchyHandler)group).dumpViewHierarchyWithProperties(out, level + 1);
+ }
}
private static boolean dumpViewWithProperties(Context context, View view,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e7b0e78..a6ba0ec 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5243,9 +5243,6 @@
}
}
- /**
- * @hide
- */
@Override
public void onResolvedLayoutDirectionReset() {
// Take care of resetting the children resolution too
@@ -5258,9 +5255,6 @@
}
}
- /**
- * @hide
- */
@Override
public void onResolvedTextDirectionReset() {
// Take care of resetting the children resolution too
@@ -5273,9 +5267,6 @@
}
}
- /**
- * @hide
- */
@Override
public void onResolvedTextAlignmentReset() {
// Take care of resetting the children resolution too
@@ -5446,15 +5437,19 @@
}
/**
- * Extracts the layout parameters from the supplied attributes.
+ * Extracts the <code>width</code> and <code>height</code> layout parameters
+ * from the supplied TypedArray, <code>a</code>, and assigns them
+ * to the appropriate fields. If, <code>a</code>, does not contain an
+ * entry for either attribute, the value, {@link ViewGroup.LayoutParams#WRAP_CONTENT},
+ * is used as a default.
*
* @param a the style attributes to extract the parameters from
* @param widthAttr the identifier of the width attribute
* @param heightAttr the identifier of the height attribute
*/
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
- width = a.getLayoutDimension(widthAttr, "layout_width");
- height = a.getLayoutDimension(heightAttr, "layout_height");
+ width = a.getLayoutDimension(widthAttr, WRAP_CONTENT);
+ height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
}
/**
@@ -5466,7 +5461,6 @@
*
* {@link View#LAYOUT_DIRECTION_LTR}
* {@link View#LAYOUT_DIRECTION_RTL}
- * @hide
*/
public void onResolveLayoutDirection(int layoutDirection) {
}
@@ -5558,7 +5552,6 @@
* The start margin in pixels of the child.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
- * @hide
*/
@ViewDebug.ExportedProperty(category = "layout")
public int startMargin = DEFAULT_RELATIVE;
@@ -5567,7 +5560,6 @@
* The end margin in pixels of the child.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
- * @hide
*/
@ViewDebug.ExportedProperty(category = "layout")
public int endMargin = DEFAULT_RELATIVE;
@@ -5686,6 +5678,7 @@
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
+ *
* @hide
*/
public void setMarginsRelative(int start, int top, int end, int bottom) {
@@ -5701,7 +5694,6 @@
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
*
* @return the start margin in pixels.
- * @hide
*/
public int getMarginStart() {
return startMargin;
@@ -5713,7 +5705,6 @@
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
*
* @return the end margin in pixels.
- * @hide
*/
public int getMarginEnd() {
return endMargin;
@@ -5726,7 +5717,6 @@
* @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
*
* @return true if either marginStart or marginEnd has been set
- * @hide
*/
public boolean isMarginRelative() {
return (startMargin != DEFAULT_RELATIVE) || (endMargin != DEFAULT_RELATIVE);
@@ -5735,7 +5725,6 @@
/**
* This will be called by {@link android.view.View#requestLayout()}. Left and Right margins
* may be overridden depending on layout direction.
- * @hide
*/
@Override
public void onResolveLayoutDirection(int layoutDirection) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6959b84..17783a4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -76,7 +76,6 @@
import com.android.internal.R;
import com.android.internal.policy.PolicyManager;
import com.android.internal.view.BaseSurfaceHolder;
-import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.RootViewSurfaceTaker;
@@ -4662,23 +4661,20 @@
}
}
- static class InputMethodCallback extends IInputMethodCallback.Stub {
+ static final class InputMethodCallback implements InputMethodManager.FinishedEventCallback {
private WeakReference<ViewRootImpl> mViewAncestor;
public InputMethodCallback(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
}
+ @Override
public void finishedEvent(int seq, boolean handled) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchImeFinishedEvent(seq, handled);
}
}
-
- public void sessionCreated(IInputMethodSession session) {
- // Stub -- not for use in the client.
- }
}
static class W extends IWindow.Stub {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 1c5d436..cfcf3c0 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -32,12 +32,18 @@
* for more information.
*/
public final class ViewTreeObserver {
+ // Recursive listeners use CopyOnWriteArrayList
private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
- private CopyOnWriteArrayList<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
- private CopyOnWriteArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
- private CopyOnWriteArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
- private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
+
+ // Non-recursive listeners use CopyOnWriteArray
+ // Any listener invoked from ViewRootImpl.performTraversals() should not be recursive
+ private CopyOnWriteArray<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
+ private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
+ private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners;
+ private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners;
+
+ // These listeners cannot be mutated during dispatch
private ArrayList<OnDrawListener> mOnDrawListeners;
private boolean mAlive = true;
@@ -147,7 +153,7 @@
* windows behind it should be placed.
*/
public final Rect contentInsets = new Rect();
-
+
/**
* Offsets from the frame of the window at which windows behind it
* are visible.
@@ -166,13 +172,13 @@
* can be touched.
*/
public static final int TOUCHABLE_INSETS_FRAME = 0;
-
+
/**
* Option for {@link #setTouchableInsets(int)}: the area inside of
* the content insets can be touched.
*/
public static final int TOUCHABLE_INSETS_CONTENT = 1;
-
+
/**
* Option for {@link #setTouchableInsets(int)}: the area inside of
* the visible insets can be touched.
@@ -195,7 +201,7 @@
}
int mTouchableInsets;
-
+
void reset() {
contentInsets.setEmpty();
visibleInsets.setEmpty();
@@ -231,7 +237,7 @@
mTouchableInsets = other.mTouchableInsets;
}
}
-
+
/**
* Interface definition for a callback to be invoked when layout has
* completed and the client can compute its interior insets.
@@ -363,7 +369,7 @@
checkIsAlive();
if (mOnGlobalLayoutListeners == null) {
- mOnGlobalLayoutListeners = new CopyOnWriteArrayList<OnGlobalLayoutListener>();
+ mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>();
}
mOnGlobalLayoutListeners.add(listener);
@@ -413,7 +419,7 @@
checkIsAlive();
if (mOnPreDrawListeners == null) {
- mOnPreDrawListeners = new ArrayList<OnPreDrawListener>();
+ mOnPreDrawListeners = new CopyOnWriteArray<OnPreDrawListener>();
}
mOnPreDrawListeners.add(listener);
@@ -485,7 +491,7 @@
checkIsAlive();
if (mOnScrollChangedListeners == null) {
- mOnScrollChangedListeners = new CopyOnWriteArrayList<OnScrollChangedListener>();
+ mOnScrollChangedListeners = new CopyOnWriteArray<OnScrollChangedListener>();
}
mOnScrollChangedListeners.add(listener);
@@ -558,7 +564,7 @@
if (mOnComputeInternalInsetsListeners == null) {
mOnComputeInternalInsetsListeners =
- new CopyOnWriteArrayList<OnComputeInternalInsetsListener>();
+ new CopyOnWriteArray<OnComputeInternalInsetsListener>();
}
mOnComputeInternalInsetsListeners.add(listener);
@@ -640,10 +646,16 @@
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
- final CopyOnWriteArrayList<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
+ final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
if (listeners != null && listeners.size() > 0) {
- for (OnGlobalLayoutListener listener : listeners) {
- listener.onGlobalLayout();
+ CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start();
+ try {
+ int count = access.size();
+ for (int i = 0; i < count; i++) {
+ access.get(i).onGlobalLayout();
+ }
+ } finally {
+ listeners.end();
}
}
}
@@ -658,17 +670,17 @@
*/
@SuppressWarnings("unchecked")
public final boolean dispatchOnPreDraw() {
- // NOTE: we *must* clone the listener list to perform the dispatching.
- // The clone is a safe guard against listeners that
- // could mutate the list by calling the various add/remove methods. This prevents
- // the array from being modified while we process it.
boolean cancelDraw = false;
- if (mOnPreDrawListeners != null && mOnPreDrawListeners.size() > 0) {
- final ArrayList<OnPreDrawListener> listeners =
- (ArrayList<OnPreDrawListener>) mOnPreDrawListeners.clone();
- int numListeners = listeners.size();
- for (int i = 0; i < numListeners; ++i) {
- cancelDraw |= !(listeners.get(i).onPreDraw());
+ final CopyOnWriteArray<OnPreDrawListener> listeners = mOnPreDrawListeners;
+ if (listeners != null && listeners.size() > 0) {
+ CopyOnWriteArray.Access<OnPreDrawListener> access = listeners.start();
+ try {
+ int count = access.size();
+ for (int i = 0; i < count; i++) {
+ cancelDraw |= !(access.get(i).onPreDraw());
+ }
+ } finally {
+ listeners.end();
}
}
return cancelDraw;
@@ -710,10 +722,16 @@
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
- final CopyOnWriteArrayList<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
+ final CopyOnWriteArray<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
if (listeners != null && listeners.size() > 0) {
- for (OnScrollChangedListener listener : listeners) {
- listener.onScrollChanged();
+ CopyOnWriteArray.Access<OnScrollChangedListener> access = listeners.start();
+ try {
+ int count = access.size();
+ for (int i = 0; i < count; i++) {
+ access.get(i).onScrollChanged();
+ }
+ } finally {
+ listeners.end();
}
}
}
@@ -722,11 +740,11 @@
* Returns whether there are listeners for computing internal insets.
*/
final boolean hasComputeInternalInsetsListeners() {
- final CopyOnWriteArrayList<OnComputeInternalInsetsListener> listeners =
+ final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners =
mOnComputeInternalInsetsListeners;
return (listeners != null && listeners.size() > 0);
}
-
+
/**
* Calls all listeners to compute the current insets.
*/
@@ -735,12 +753,105 @@
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
- final CopyOnWriteArrayList<OnComputeInternalInsetsListener> listeners =
+ final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners =
mOnComputeInternalInsetsListeners;
if (listeners != null && listeners.size() > 0) {
- for (OnComputeInternalInsetsListener listener : listeners) {
- listener.onComputeInternalInsets(inoutInfo);
+ CopyOnWriteArray.Access<OnComputeInternalInsetsListener> access = listeners.start();
+ try {
+ int count = access.size();
+ for (int i = 0; i < count; i++) {
+ access.get(i).onComputeInternalInsets(inoutInfo);
+ }
+ } finally {
+ listeners.end();
}
}
}
+
+ /**
+ * Copy on write array. This array is not thread safe, and only one loop can
+ * iterate over this array at any given time. This class avoids allocations
+ * until a concurrent modification happens.
+ *
+ * Usage:
+ *
+ * CopyOnWriteArray.Access<MyData> access = array.start();
+ * try {
+ * for (int i = 0; i < access.size(); i++) {
+ * MyData d = access.get(i);
+ * }
+ * } finally {
+ * access.end();
+ * }
+ */
+ static class CopyOnWriteArray<T> {
+ private ArrayList<T> mData = new ArrayList<T>();
+ private ArrayList<T> mDataCopy;
+
+ private final Access<T> mAccess = new Access<T>();
+
+ private boolean mStart;
+
+ static class Access<T> {
+ private ArrayList<T> mData;
+ private int mSize;
+
+ T get(int index) {
+ return mData.get(index);
+ }
+
+ int size() {
+ return mSize;
+ }
+ }
+
+ CopyOnWriteArray() {
+ }
+
+ private ArrayList<T> getArray() {
+ if (mStart) {
+ if (mDataCopy == null) mDataCopy = new ArrayList<T>(mData);
+ return mDataCopy;
+ }
+ return mData;
+ }
+
+ Access<T> start() {
+ if (mStart) throw new IllegalStateException("Iteration already started");
+ mStart = true;
+ mDataCopy = null;
+ mAccess.mData = mData;
+ mAccess.mSize = mData.size();
+ return mAccess;
+ }
+
+ void end() {
+ if (!mStart) throw new IllegalStateException("Iteration not started");
+ mStart = false;
+ if (mDataCopy != null) {
+ mData = mDataCopy;
+ }
+ mDataCopy = null;
+ }
+
+ int size() {
+ return getArray().size();
+ }
+
+ void add(T item) {
+ getArray().add(item);
+ }
+
+ void addAll(CopyOnWriteArray<T> array) {
+ getArray().addAll(array.mData);
+ }
+
+ void remove(T item) {
+ getArray().remove(item);
+ }
+
+ void clear() {
+ getArray().clear();
+ }
+ }
}
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index cf9bcdd..4d4e985c 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -104,6 +104,9 @@
private boolean mShowCombinedVolumes;
private boolean mVoiceCapable;
+ // True if we want to play tones on the system stream when the master stream is specified.
+ private final boolean mPlayMasterStreamTones;
+
/** Dialog containing all the sliders */
private final Dialog mDialog;
/** Dialog's content view */
@@ -282,6 +285,13 @@
mMoreButton.setOnClickListener(this);
}
+ boolean masterVolumeOnly = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_useMasterVolume);
+ boolean masterVolumeKeySounds = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_useVolumeKeySounds);
+
+ mPlayMasterStreamTones = masterVolumeOnly && masterVolumeKeySounds;
+
listenToRingerMode();
}
@@ -790,7 +800,16 @@
* Lock on this VolumePanel instance as long as you use the returned ToneGenerator.
*/
private ToneGenerator getOrCreateToneGenerator(int streamType) {
- if (streamType == STREAM_MASTER) return null;
+ if (streamType == STREAM_MASTER) {
+ // For devices that use the master volume setting only but still want to
+ // play a volume-changed tone, direct the master volume pseudostream to
+ // the system stream's tone generator.
+ if (mPlayMasterStreamTones) {
+ streamType = AudioManager.STREAM_SYSTEM;
+ } else {
+ return null;
+ }
+ }
synchronized (this) {
if (mToneGenerators[streamType] == null) {
try {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index b0e90db..ec4114e 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -718,6 +718,7 @@
* per {@link #setFlags}.
* @param flags The flag bits to be set.
* @see #setFlags
+ * @see #clearFlags
*/
public void addFlags(int flags) {
setFlags(flags, flags);
@@ -728,6 +729,7 @@
* per {@link #setFlags}.
* @param flags The flag bits to be cleared.
* @see #setFlags
+ * @see #addFlags
*/
public void clearFlags(int flags) {
setFlags(0, flags);
@@ -749,6 +751,8 @@
*
* @param flags The new window flags (see WindowManager.LayoutParams).
* @param mask Which of the window flag bits to modify.
+ * @see #addFlags
+ * @see #clearFlags
*/
public void setFlags(int flags, int mask) {
final WindowManager.LayoutParams attrs = getAttributes();
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d94275b..e6a29ea 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -162,6 +162,7 @@
@ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA, to = "TYPE_APPLICATION_MEDIA"),
@ViewDebug.IntToString(from = TYPE_APPLICATION_SUB_PANEL, to = "TYPE_APPLICATION_SUB_PANEL"),
@ViewDebug.IntToString(from = TYPE_APPLICATION_ATTACHED_DIALOG, to = "TYPE_APPLICATION_ATTACHED_DIALOG"),
+ @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA_OVERLAY, to = "TYPE_APPLICATION_MEDIA_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_STATUS_BAR, to = "TYPE_STATUS_BAR"),
@ViewDebug.IntToString(from = TYPE_SEARCH_BAR, to = "TYPE_SEARCH_BAR"),
@ViewDebug.IntToString(from = TYPE_PHONE, to = "TYPE_PHONE"),
@@ -170,8 +171,6 @@
@ViewDebug.IntToString(from = TYPE_TOAST, to = "TYPE_TOAST"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, to = "TYPE_SYSTEM_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE, to = "TYPE_PRIORITY_PHONE"),
- @ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL, to = "TYPE_STATUS_BAR_PANEL"),
- @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL, to = "TYPE_STATUS_BAR_SUB_PANEL"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_DIALOG, to = "TYPE_SYSTEM_DIALOG"),
@ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG, to = "TYPE_KEYGUARD_DIALOG"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
@@ -185,7 +184,10 @@
@ViewDebug.IntToString(from = TYPE_POINTER, to = "TYPE_POINTER"),
@ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR, to = "TYPE_NAVIGATION_BAR"),
@ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY, to = "TYPE_VOLUME_OVERLAY"),
- @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS")
+ @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS"),
+ @ViewDebug.IntToString(from = TYPE_HIDDEN_NAV_CONSUMER, to = "TYPE_HIDDEN_NAV_CONSUMER"),
+ @ViewDebug.IntToString(from = TYPE_DREAM, to = "TYPE_DREAM"),
+ @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL")
})
public int type;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index d2cc2d8..89932cc 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -35,6 +35,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.SystemClock;
import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.PrintWriterPrinter;
@@ -225,6 +226,13 @@
*/
public static final int CONTROL_START_INITIAL = 1<<8;
+ /**
+ * Timeout in milliseconds for delivering a key to an IME.
+ */
+ static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500;
+
+ private static final int MAX_PENDING_EVENT_POOL_SIZE = 4;
+
final IInputMethodManager mService;
final Looper mMainLooper;
@@ -312,12 +320,17 @@
*/
IInputMethodSession mCurMethod;
+ PendingEvent mPendingEventPool;
+ int mPendingEventPoolSize;
+ PendingEvent mFirstPendingEvent;
+
// -----------------------------------------------------------
static final int MSG_DUMP = 1;
static final int MSG_BIND = 2;
static final int MSG_UNBIND = 3;
static final int MSG_SET_ACTIVE = 4;
+ static final int MSG_EVENT_TIMEOUT = 5;
class H extends Handler {
H(Looper looper) {
@@ -413,6 +426,17 @@
}
return;
}
+ case MSG_EVENT_TIMEOUT: {
+ // Even though the message contains both the sequence number
+ // and the PendingEvent object itself, we only pass the
+ // sequence number to the timeoutEvent function because it's
+ // possible for the PendingEvent object to be dequeued and
+ // recycled concurrently. To avoid a possible race, we make
+ // a point of always looking up the PendingEvent within the
+ // queue given only the sequence number of the event.
+ timeoutEvent(msg.arg1);
+ return;
+ }
}
}
}
@@ -476,6 +500,18 @@
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
+
+ final IInputMethodCallback mInputMethodCallback = new IInputMethodCallback.Stub() {
+ @Override
+ public void finishedEvent(int seq, boolean handled) {
+ InputMethodManager.this.finishedEvent(seq, handled);
+ }
+
+ @Override
+ public void sessionCreated(IInputMethodSession session) {
+ // Stub -- not for use in the client.
+ }
+ };
InputMethodManager(IInputMethodManager service, Looper looper) {
mService = service;
@@ -1105,6 +1141,7 @@
if (res.id != null) {
mBindSequence = res.sequence;
mCurMethod = res.method;
+ mCurId = res.id;
} else if (mCurMethod == null) {
// This means there is no input method available.
if (DEBUG) Log.v(TAG, "ABORT input: no input method!");
@@ -1511,76 +1548,159 @@
* @hide
*/
public void dispatchKeyEvent(Context context, int seq, KeyEvent key,
- IInputMethodCallback callback) {
+ FinishedEventCallback callback) {
+ boolean handled = false;
synchronized (mH) {
if (DEBUG) Log.d(TAG, "dispatchKeyEvent");
-
- if (mCurMethod == null) {
- try {
- callback.finishedEvent(seq, false);
- } catch (RemoteException e) {
- }
- return;
- }
-
- if (key.getAction() == KeyEvent.ACTION_DOWN
- && key.getKeyCode() == KeyEvent.KEYCODE_SYM) {
- showInputMethodPicker();
- try {
- callback.finishedEvent(seq, true);
- } catch (RemoteException e) {
- }
- return;
- }
- try {
- if (DEBUG) Log.v(TAG, "DISPATCH KEY: " + mCurMethod);
- mCurMethod.dispatchKeyEvent(seq, key, callback);
- } catch (RemoteException e) {
- Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e);
- try {
- callback.finishedEvent(seq, false);
- } catch (RemoteException ex) {
+
+ if (mCurMethod != null) {
+ if (key.getAction() == KeyEvent.ACTION_DOWN
+ && key.getKeyCode() == KeyEvent.KEYCODE_SYM) {
+ showInputMethodPickerLocked();
+ handled = true;
+ } else {
+ try {
+ if (DEBUG) Log.v(TAG, "DISPATCH KEY: " + mCurMethod);
+ final long startTime = SystemClock.uptimeMillis();
+ mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback);
+ enqueuePendingEventLocked(startTime, seq, mCurId, callback);
+ return;
+ } catch (RemoteException e) {
+ Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e);
+ }
}
}
}
+
+ callback.finishedEvent(seq, handled);
}
/**
* @hide
*/
void dispatchTrackballEvent(Context context, int seq, MotionEvent motion,
- IInputMethodCallback callback) {
+ FinishedEventCallback callback) {
synchronized (mH) {
if (DEBUG) Log.d(TAG, "dispatchTrackballEvent");
-
- if (mCurMethod == null || mCurrentTextBoxAttribute == null) {
+
+ if (mCurMethod != null && mCurrentTextBoxAttribute != null) {
try {
- callback.finishedEvent(seq, false);
+ if (DEBUG) Log.v(TAG, "DISPATCH TRACKBALL: " + mCurMethod);
+ final long startTime = SystemClock.uptimeMillis();
+ mCurMethod.dispatchTrackballEvent(seq, motion, mInputMethodCallback);
+ enqueuePendingEventLocked(startTime, seq, mCurId, callback);
+ return;
} catch (RemoteException e) {
- }
- return;
- }
-
- try {
- if (DEBUG) Log.v(TAG, "DISPATCH TRACKBALL: " + mCurMethod);
- mCurMethod.dispatchTrackballEvent(seq, motion, callback);
- } catch (RemoteException e) {
- Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e);
- try {
- callback.finishedEvent(seq, false);
- } catch (RemoteException ex) {
+ Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e);
}
}
}
+
+ callback.finishedEvent(seq, false);
+ }
+
+ void finishedEvent(int seq, boolean handled) {
+ final FinishedEventCallback callback;
+ synchronized (mH) {
+ PendingEvent p = dequeuePendingEventLocked(seq);
+ if (p == null) {
+ return; // spurious, event already finished or timed out
+ }
+ mH.removeMessages(MSG_EVENT_TIMEOUT, p);
+ callback = p.mCallback;
+ recyclePendingEventLocked(p);
+ }
+ callback.finishedEvent(seq, handled);
+ }
+
+ void timeoutEvent(int seq) {
+ final FinishedEventCallback callback;
+ synchronized (mH) {
+ PendingEvent p = dequeuePendingEventLocked(seq);
+ if (p == null) {
+ return; // spurious, event already finished or timed out
+ }
+ long delay = SystemClock.uptimeMillis() - p.mStartTime;
+ Log.w(TAG, "Timeout waiting for IME to handle input event after "
+ + delay + "ms: " + p.mInputMethodId);
+ callback = p.mCallback;
+ recyclePendingEventLocked(p);
+ }
+ callback.finishedEvent(seq, false);
+ }
+
+ private void enqueuePendingEventLocked(
+ long startTime, int seq, String inputMethodId, FinishedEventCallback callback) {
+ PendingEvent p = obtainPendingEventLocked(startTime, seq, inputMethodId, callback);
+ p.mNext = mFirstPendingEvent;
+ mFirstPendingEvent = p;
+
+ Message msg = mH.obtainMessage(MSG_EVENT_TIMEOUT, seq, 0, p);
+ msg.setAsynchronous(true);
+ mH.sendMessageDelayed(msg, INPUT_METHOD_NOT_RESPONDING_TIMEOUT);
+ }
+
+ private PendingEvent dequeuePendingEventLocked(int seq) {
+ PendingEvent p = mFirstPendingEvent;
+ if (p == null) {
+ return null;
+ }
+ if (p.mSeq == seq) {
+ mFirstPendingEvent = p.mNext;
+ } else {
+ PendingEvent prev = p;
+ do {
+ p = prev.mNext;
+ if (p == null) {
+ return null;
+ }
+ } while (p.mSeq != seq);
+ prev.mNext = p.mNext;
+ }
+ p.mNext = null;
+ return p;
+ }
+
+ private PendingEvent obtainPendingEventLocked(
+ long startTime, int seq, String inputMethodId, FinishedEventCallback callback) {
+ PendingEvent p = mPendingEventPool;
+ if (p != null) {
+ mPendingEventPoolSize -= 1;
+ mPendingEventPool = p.mNext;
+ p.mNext = null;
+ } else {
+ p = new PendingEvent();
+ }
+
+ p.mStartTime = startTime;
+ p.mSeq = seq;
+ p.mInputMethodId = inputMethodId;
+ p.mCallback = callback;
+ return p;
+ }
+
+ private void recyclePendingEventLocked(PendingEvent p) {
+ p.mInputMethodId = null;
+ p.mCallback = null;
+
+ if (mPendingEventPoolSize < MAX_PENDING_EVENT_POOL_SIZE) {
+ mPendingEventPoolSize += 1;
+ p.mNext = mPendingEventPool;
+ mPendingEventPool = p;
+ }
}
public void showInputMethodPicker() {
synchronized (mH) {
- try {
- mService.showInputMethodPickerFromClient(mClient);
- } catch (RemoteException e) {
- Log.w(TAG, "IME died: " + mCurId, e);
- }
+ showInputMethodPickerLocked();
+ }
+ }
+
+ private void showInputMethodPickerLocked() {
+ try {
+ mService.showInputMethodPickerFromClient(mClient);
+ } catch (RemoteException e) {
+ Log.w(TAG, "IME died: " + mCurId, e);
}
}
@@ -1773,4 +1893,22 @@
+ " mCursorCandStart=" + mCursorCandStart
+ " mCursorCandEnd=" + mCursorCandEnd);
}
+
+ /**
+ * Callback that is invoked when an input event that was dispatched to
+ * the IME has been finished.
+ * @hide
+ */
+ public interface FinishedEventCallback {
+ public void finishedEvent(int seq, boolean handled);
+ }
+
+ private static final class PendingEvent {
+ public PendingEvent mNext;
+
+ public long mStartTime;
+ public int mSeq;
+ public String mInputMethodId;
+ public FinishedEventCallback mCallback;
+ }
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 5108990..fe812af 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -74,6 +74,7 @@
private final CallbackProxy mCallbackProxy;
private final WebSettingsClassic mSettings;
private final Context mContext;
+ private final WebViewDatabaseClassic mDatabase;
private final WebViewCore mWebViewCore;
/* package */ boolean mLoadInitFromJava;
private int mLoadType;
@@ -242,6 +243,7 @@
mSettings = settings;
mContext = context;
mCallbackProxy = proxy;
+ mDatabase = WebViewDatabaseClassic.getInstance(appContext);
mWebViewCore = w;
mSearchBox = new SearchBoxImpl(mWebViewCore, mCallbackProxy);
@@ -424,8 +426,7 @@
if (h != null) {
String url = WebTextView.urlForAutoCompleteData(h.getUrl());
if (url != null) {
- WebViewDatabaseClassic.getInstance(mContext).setFormData(
- url, data);
+ mDatabase.setFormData(url, data);
}
}
}
@@ -497,9 +498,8 @@
if (item != null) {
WebAddress uri = new WebAddress(item.getUrl());
String schemePlusHost = uri.getScheme() + uri.getHost();
- String[] up =
- WebViewDatabaseClassic.getInstance(mContext)
- .getUsernamePassword(schemePlusHost);
+ String[] up = mDatabase.getUsernamePassword(
+ schemePlusHost);
if (up != null && up[0] != null) {
setUsernamePassword(up[0], up[1]);
}
@@ -800,10 +800,10 @@
// the post data (there could be another form on the
// page and that was posted instead.
String postString = new String(postData);
- WebViewDatabaseClassic db = WebViewDatabaseClassic.getInstance(mContext);
if (postString.contains(URLEncoder.encode(username)) &&
postString.contains(URLEncoder.encode(password))) {
- String[] saved = db.getUsernamePassword(schemePlusHost);
+ String[] saved = mDatabase.getUsernamePassword(
+ schemePlusHost);
if (saved != null) {
// null username implies that user has chosen not to
// save password
@@ -811,8 +811,7 @@
// non-null username implies that user has
// chosen to save password, so update the
// recorded password
- db.setUsernamePassword(schemePlusHost, username,
- password);
+ mDatabase.setUsernamePassword(schemePlusHost, username, password);
}
} else {
// CallbackProxy will handle creating the resume
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 2d9f60d..36665ee 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -71,7 +71,7 @@
// Start with 100 to indicate it is not in load for the empty page.
private volatile int mLatestProgress = 100;
// Back/Forward list
- private final WebBackForwardList mBackForwardList;
+ private final WebBackForwardListClassic mBackForwardList;
// Back/Forward list client
private volatile WebBackForwardListClient mWebBackForwardListClient;
// Used to call startActivity during url override.
@@ -188,7 +188,7 @@
// Used to start a default activity.
mContext = context;
mWebView = w;
- mBackForwardList = new WebBackForwardList(this);
+ mBackForwardList = new WebBackForwardListClassic(this);
}
protected synchronized void blockMessages() {
@@ -249,7 +249,7 @@
* Get the Back/Forward list to return to the user or to update the cached
* history list.
*/
- public WebBackForwardList getBackForwardList() {
+ public WebBackForwardListClassic getBackForwardList() {
return mBackForwardList;
}
@@ -403,17 +403,18 @@
break;
case PROCEEDED_AFTER_SSL_ERROR:
- if (mWebViewClient != null) {
- mWebViewClient.onProceededAfterSslError(mWebView.getWebView(),
+ if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+ ((WebViewClientClassicExt) mWebViewClient).onProceededAfterSslError(
+ mWebView.getWebView(),
(SslError) msg.obj);
}
break;
case CLIENT_CERT_REQUEST:
- if (mWebViewClient != null) {
- HashMap<String, Object> map =
- (HashMap<String, Object>) msg.obj;
- mWebViewClient.onReceivedClientCertRequest(mWebView.getWebView(),
+ if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+ HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
+ ((WebViewClientClassicExt) mWebViewClient).onReceivedClientCertRequest(
+ mWebView.getWebView(),
(ClientCertRequestHandler) map.get("handler"),
(String) map.get("host_and_port"));
}
@@ -1081,7 +1082,7 @@
}
public void onProceededAfterSslError(SslError error) {
- if (mWebViewClient == null) {
+ if (mWebViewClient == null || !(mWebViewClient instanceof WebViewClientClassicExt)) {
return;
}
Message msg = obtainMessage(PROCEEDED_AFTER_SSL_ERROR);
@@ -1092,7 +1093,7 @@
public void onReceivedClientCertRequest(ClientCertRequestHandler handler, String host_and_port) {
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
- if (mWebViewClient == null) {
+ if (mWebViewClient == null || !(mWebViewClient instanceof WebViewClientClassicExt)) {
handler.cancel();
return;
}
@@ -1301,7 +1302,7 @@
public void onReceivedIcon(Bitmap icon) {
// The current item might be null if the icon was already stored in the
// database and this is a new WebView.
- WebHistoryItem i = mBackForwardList.getCurrentItem();
+ WebHistoryItemClassic i = mBackForwardList.getCurrentItem();
if (i != null) {
i.setFavicon(icon);
}
@@ -1316,7 +1317,7 @@
/* package */ void onReceivedTouchIconUrl(String url, boolean precomposed) {
// We should have a current item but we do not want to crash so check
// for null.
- WebHistoryItem i = mBackForwardList.getCurrentItem();
+ WebHistoryItemClassic i = mBackForwardList.getCurrentItem();
if (i != null) {
i.setTouchIconUrl(url, precomposed);
}
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 4e99335..276bcae 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -86,10 +86,8 @@
throw new IllegalArgumentException("Invalid context argument");
}
- JniUtil.setContext(context);
- Context appContext = context.getApplicationContext();
if (sRef == null) {
- sRef = new CookieSyncManager(appContext);
+ sRef = new CookieSyncManager(context);
}
return sRef;
}
diff --git a/core/java/android/webkit/MockGeolocation.java b/core/java/android/webkit/MockGeolocation.java
index fbda492..885c6c2 100644
--- a/core/java/android/webkit/MockGeolocation.java
+++ b/core/java/android/webkit/MockGeolocation.java
@@ -17,21 +17,29 @@
package android.webkit;
/**
- * This class is simply a container for the methods used to configure WebKit's
- * mock Geolocation service for use in LayoutTests.
+ * Used to configure the mock Geolocation client for the LayoutTests.
* @hide
*/
public final class MockGeolocation {
+ private WebViewCore mWebViewCore;
- // Global instance of a MockGeolocation
- private static MockGeolocation sMockGeolocation;
+ public MockGeolocation(WebViewCore webViewCore) {
+ mWebViewCore = webViewCore;
+ }
+
+ /**
+ * Sets use of the mock Geolocation client. Also resets that client.
+ */
+ public void setUseMock() {
+ nativeSetUseMock(mWebViewCore);
+ }
/**
* Set the position for the mock Geolocation service.
*/
public void setPosition(double latitude, double longitude, double accuracy) {
// This should only ever be called on the WebKit thread.
- nativeSetPosition(latitude, longitude, accuracy);
+ nativeSetPosition(mWebViewCore, latitude, longitude, accuracy);
}
/**
@@ -39,21 +47,18 @@
*/
public void setError(int code, String message) {
// This should only ever be called on the WebKit thread.
- nativeSetError(code, message);
+ nativeSetError(mWebViewCore, code, message);
}
- /**
- * Get the global instance of MockGeolocation.
- * @return The global MockGeolocation instance.
- */
- public static MockGeolocation getInstance() {
- if (sMockGeolocation == null) {
- sMockGeolocation = new MockGeolocation();
- }
- return sMockGeolocation;
+ public void setPermission(boolean allow) {
+ // This should only ever be called on the WebKit thread.
+ nativeSetPermission(mWebViewCore, allow);
}
// Native functions
- private static native void nativeSetPosition(double latitude, double longitude, double accuracy);
- private static native void nativeSetError(int code, String message);
+ private static native void nativeSetUseMock(WebViewCore webViewCore);
+ private static native void nativeSetPosition(WebViewCore webViewCore, double latitude,
+ double longitude, double accuracy);
+ private static native void nativeSetError(WebViewCore webViewCore, int code, String message);
+ private static native void nativeSetPermission(WebViewCore webViewCore, boolean allow);
}
diff --git a/core/java/android/webkit/ViewStateSerializer.java b/core/java/android/webkit/ViewStateSerializer.java
index c161085..096d4cda 100644
--- a/core/java/android/webkit/ViewStateSerializer.java
+++ b/core/java/android/webkit/ViewStateSerializer.java
@@ -16,7 +16,6 @@
package android.webkit;
import android.graphics.Point;
-import android.graphics.Region;
import android.webkit.WebViewCore.DrawData;
import java.io.DataInputStream;
@@ -68,6 +67,15 @@
return draw;
}
+ public static void dumpLayerHierarchy(int baseLayer, OutputStream out, int level) {
+ nativeDumpLayerHierarchy(baseLayer, level, out,
+ new byte[WORKING_STREAM_STORAGE]);
+ }
+
+
+ private static native void nativeDumpLayerHierarchy(int baseLayer, int level,
+ OutputStream out, byte[] storage);
+
private static native boolean nativeSerializeViewState(int baseLayer,
OutputStream stream, byte[] storage);
diff --git a/core/java/android/webkit/WebBackForwardList.java b/core/java/android/webkit/WebBackForwardList.java
index 79e634e..bfef2e7 100644
--- a/core/java/android/webkit/WebBackForwardList.java
+++ b/core/java/android/webkit/WebBackForwardList.java
@@ -17,7 +17,6 @@
package android.webkit;
import java.io.Serializable;
-import java.util.ArrayList;
/**
* This class contains the back/forward list for a WebView.
@@ -25,22 +24,11 @@
* inspect the entries in the list.
*/
public class WebBackForwardList implements Cloneable, Serializable {
- // Current position in the list.
- private int mCurrentIndex;
- // ArrayList of WebHistoryItems for maintaining our copy.
- private ArrayList<WebHistoryItem> mArray;
- // Flag to indicate that the list is invalid
- private boolean mClearPending;
- // CallbackProxy to issue client callbacks.
- private final CallbackProxy mCallbackProxy;
/**
- * Construct a back/forward list used by clients of WebView.
+ * @hide
*/
- /*package*/ WebBackForwardList(CallbackProxy proxy) {
- mCurrentIndex = -1;
- mArray = new ArrayList<WebHistoryItem>();
- mCallbackProxy = proxy;
+ public WebBackForwardList() {
}
/**
@@ -49,7 +37,7 @@
* @return The current history item.
*/
public synchronized WebHistoryItem getCurrentItem() {
- return getItemAtIndex(mCurrentIndex);
+ throw new MustOverrideException();
}
/**
@@ -58,7 +46,7 @@
* @return The current index from 0...n or -1 if the list is empty.
*/
public synchronized int getCurrentIndex() {
- return mCurrentIndex;
+ throw new MustOverrideException();
}
/**
@@ -67,10 +55,7 @@
* @param index The index to retrieve.
*/
public synchronized WebHistoryItem getItemAtIndex(int index) {
- if (index < 0 || index >= getSize()) {
- return null;
- }
- return mArray.get(index);
+ throw new MustOverrideException();
}
/**
@@ -78,78 +63,7 @@
* @return The size of the list.
*/
public synchronized int getSize() {
- return mArray.size();
- }
-
- /**
- * Mark the back/forward list as having a pending clear. This is used on the
- * UI side to mark the list as being invalid during the clearHistory method.
- */
- /*package*/ synchronized void setClearPending() {
- mClearPending = true;
- }
-
- /**
- * Return the status of the clear flag. This is used on the UI side to
- * determine if the list is valid for checking things like canGoBack.
- */
- /*package*/ synchronized boolean getClearPending() {
- return mClearPending;
- }
-
- /**
- * Add a new history item to the list. This will remove all items after the
- * current item and append the new item to the end of the list. Called from
- * the WebCore thread only. Synchronized because the UI thread may be
- * reading the array or the current index.
- * @param item A new history item.
- */
- /*package*/ synchronized void addHistoryItem(WebHistoryItem item) {
- // Update the current position because we are going to add the new item
- // in that slot.
- ++mCurrentIndex;
- // If the current position is not at the end, remove all history items
- // after the current item.
- final int size = mArray.size();
- final int newPos = mCurrentIndex;
- if (newPos != size) {
- for (int i = size - 1; i >= newPos; i--) {
- final WebHistoryItem h = mArray.remove(i);
- }
- }
- // Add the item to the list.
- mArray.add(item);
- if (mCallbackProxy != null) {
- mCallbackProxy.onNewHistoryItem(item);
- }
- }
-
- /**
- * Clear the back/forward list. Called from the WebCore thread.
- */
- /*package*/ synchronized void close(int nativeFrame) {
- // Clear the array first because nativeClose will call addHistoryItem
- // with the current item.
- mArray.clear();
- mCurrentIndex = -1;
- nativeClose(nativeFrame);
- // Reset the clear flag
- mClearPending = false;
- }
-
- /* Remove the item at the given index. Called by JNI only. */
- private synchronized void removeHistoryItem(int index) {
- // XXX: This is a special case. Since the callback is only triggered
- // when removing the first item, we can assert that the index is 0.
- // This lets us change the current index without having to query the
- // native BackForwardList.
- if (DebugFlags.WEB_BACK_FORWARD_LIST && (index != 0)) {
- throw new AssertionError();
- }
- final WebHistoryItem h = mArray.remove(index);
- // XXX: If we ever add another callback for removing history items at
- // any index, this will no longer be valid.
- mCurrentIndex--;
+ throw new MustOverrideException();
}
/**
@@ -158,39 +72,7 @@
* webkit package classes.
*/
protected synchronized WebBackForwardList clone() {
- WebBackForwardList l = new WebBackForwardList(null);
- if (mClearPending) {
- // If a clear is pending, return a copy with only the current item.
- l.addHistoryItem(getCurrentItem());
- return l;
- }
- l.mCurrentIndex = mCurrentIndex;
- int size = getSize();
- l.mArray = new ArrayList<WebHistoryItem>(size);
- for (int i = 0; i < size; i++) {
- // Add a copy of each WebHistoryItem
- l.mArray.add(mArray.get(i).clone());
- }
- return l;
+ throw new MustOverrideException();
}
- /**
- * Set the new history index.
- * @param newIndex The new history index.
- */
- /*package*/ synchronized void setCurrentIndex(int newIndex) {
- mCurrentIndex = newIndex;
- if (mCallbackProxy != null) {
- mCallbackProxy.onIndexChanged(getItemAtIndex(newIndex), newIndex);
- }
- }
-
- /**
- * Restore the history index.
- */
- /*package*/ static native synchronized void restoreIndex(int nativeFrame,
- int index);
-
- /* Close the native list. */
- private static native void nativeClose(int nativeFrame);
}
diff --git a/core/java/android/webkit/WebBackForwardListClassic.java b/core/java/android/webkit/WebBackForwardListClassic.java
new file mode 100644
index 0000000..2a14e6b
--- /dev/null
+++ b/core/java/android/webkit/WebBackForwardListClassic.java
@@ -0,0 +1,166 @@
+/*
+ * 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 android.webkit;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+/* package */ class WebBackForwardListClassic extends WebBackForwardList implements Cloneable,
+ Serializable {
+
+ // Current position in the list.
+ private int mCurrentIndex;
+ // ArrayList of WebHistoryItems for maintaining our copy.
+ private ArrayList<WebHistoryItemClassic> mArray;
+ // Flag to indicate that the list is invalid
+ private boolean mClearPending;
+ // CallbackProxy to issue client callbacks.
+ private final CallbackProxy mCallbackProxy;
+
+ /*package*/ WebBackForwardListClassic(CallbackProxy proxy) {
+ mCurrentIndex = -1;
+ mArray = new ArrayList<WebHistoryItemClassic>();
+ mCallbackProxy = proxy;
+ }
+
+ public synchronized WebHistoryItemClassic getCurrentItem() {
+ return getItemAtIndex(mCurrentIndex);
+ }
+
+ public synchronized int getCurrentIndex() {
+ return mCurrentIndex;
+ }
+
+ public synchronized WebHistoryItemClassic getItemAtIndex(int index) {
+ if (index < 0 || index >= getSize()) {
+ return null;
+ }
+ return mArray.get(index);
+ }
+
+ public synchronized int getSize() {
+ return mArray.size();
+ }
+
+ /**
+ * Mark the back/forward list as having a pending clear. This is used on the
+ * UI side to mark the list as being invalid during the clearHistory method.
+ */
+ /*package*/ synchronized void setClearPending() {
+ mClearPending = true;
+ }
+
+ /**
+ * Return the status of the clear flag. This is used on the UI side to
+ * determine if the list is valid for checking things like canGoBack.
+ */
+ /*package*/ synchronized boolean getClearPending() {
+ return mClearPending;
+ }
+
+ /**
+ * Add a new history item to the list. This will remove all items after the
+ * current item and append the new item to the end of the list. Called from
+ * the WebCore thread only. Synchronized because the UI thread may be
+ * reading the array or the current index.
+ * @param item A new history item.
+ */
+ /*package*/ synchronized void addHistoryItem(WebHistoryItem item) {
+ // Update the current position because we are going to add the new item
+ // in that slot.
+ ++mCurrentIndex;
+ // If the current position is not at the end, remove all history items
+ // after the current item.
+ final int size = mArray.size();
+ final int newPos = mCurrentIndex;
+ if (newPos != size) {
+ for (int i = size - 1; i >= newPos; i--) {
+ final WebHistoryItem h = mArray.remove(i);
+ }
+ }
+ // Add the item to the list.
+ mArray.add((WebHistoryItemClassic) item);
+ if (mCallbackProxy != null) {
+ mCallbackProxy.onNewHistoryItem(item);
+ }
+ }
+
+ /**
+ * Clear the back/forward list. Called from the WebCore thread.
+ */
+ /*package*/ synchronized void close(int nativeFrame) {
+ // Clear the array first because nativeClose will call addHistoryItem
+ // with the current item.
+ mArray.clear();
+ mCurrentIndex = -1;
+ nativeClose(nativeFrame);
+ // Reset the clear flag
+ mClearPending = false;
+ }
+
+ /* Remove the item at the given index. Called by JNI only. */
+ private synchronized void removeHistoryItem(int index) {
+ // XXX: This is a special case. Since the callback is only triggered
+ // when removing the first item, we can assert that the index is 0.
+ // This lets us change the current index without having to query the
+ // native BackForwardList.
+ if (DebugFlags.WEB_BACK_FORWARD_LIST && (index != 0)) {
+ throw new AssertionError();
+ }
+ final WebHistoryItem h = mArray.remove(index);
+ // XXX: If we ever add another callback for removing history items at
+ // any index, this will no longer be valid.
+ mCurrentIndex--;
+ }
+
+ public synchronized WebBackForwardListClassic clone() {
+ WebBackForwardListClassic l = new WebBackForwardListClassic(null);
+ if (mClearPending) {
+ // If a clear is pending, return a copy with only the current item.
+ l.addHistoryItem(getCurrentItem());
+ return l;
+ }
+ l.mCurrentIndex = mCurrentIndex;
+ int size = getSize();
+ l.mArray = new ArrayList<WebHistoryItemClassic>(size);
+ for (int i = 0; i < size; i++) {
+ // Add a copy of each WebHistoryItem
+ l.mArray.add(mArray.get(i).clone());
+ }
+ return l;
+ }
+
+ /**
+ * Set the new history index.
+ * @param newIndex The new history index.
+ */
+ /*package*/ synchronized void setCurrentIndex(int newIndex) {
+ mCurrentIndex = newIndex;
+ if (mCallbackProxy != null) {
+ mCallbackProxy.onIndexChanged(getItemAtIndex(newIndex), newIndex);
+ }
+ }
+
+ /**
+ * Restore the history index.
+ */
+ /*package*/ static native synchronized void restoreIndex(int nativeFrame,
+ int index);
+
+ /* Close the native list. */
+ private static native void nativeClose(int nativeFrame);
+}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 4e8790b..d90f031 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -297,7 +297,12 @@
* will continue to occur if the script does not finish at the next check
* point.
* @return boolean Whether the JavaScript execution should be interrupted.
+ * @deprecated This method is no longer supported and will not be invoked.
*/
+ // This method was only called when using the JSC javascript engine. V8 became
+ // the default JS engine with Froyo and support for building with JSC was
+ // removed in b/5495373. V8 does not have a mechanism for making a callback such
+ // as this.
public boolean onJsTimeout() {
return true;
}
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index 788d05c..3e0b177 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -18,9 +18,6 @@
import android.graphics.Bitmap;
-import java.net.MalformedURLException;
-import java.net.URL;
-
/**
* A convenience class for accessing fields in an entry in the back/forward list
* of a WebView. Each WebHistoryItem is a snapshot of the requested history
@@ -28,67 +25,8 @@
* @see WebBackForwardList
*/
public class WebHistoryItem implements Cloneable {
- // Global identifier count.
- private static int sNextId = 0;
- // Unique identifier.
- private final int mId;
- // A point to a native WebHistoryItem instance which contains the actual data
- private int mNativeBridge;
- // The favicon for this item.
- private Bitmap mFavicon;
- // The pre-flattened data used for saving the state.
- private byte[] mFlattenedData;
- // The apple-touch-icon url for use when adding the site to the home screen,
- // as obtained from a <link> element in the page.
- private String mTouchIconUrlFromLink;
- // If no <link> is specified, this holds the default location of the
- // apple-touch-icon.
- private String mTouchIconUrlServerDefault;
- // Custom client data that is not flattened or read by native code.
- private Object mCustomData;
- /**
- * Basic constructor that assigns a unique id to the item. Called by JNI
- * only.
- */
- private WebHistoryItem(int nativeBridge) {
- synchronized (WebHistoryItem.class) {
- mId = sNextId++;
- }
- mNativeBridge = nativeBridge;
- nativeRef(mNativeBridge);
- }
-
- protected void finalize() throws Throwable {
- if (mNativeBridge != 0) {
- nativeUnref(mNativeBridge);
- mNativeBridge = 0;
- }
- }
-
- /**
- * Construct a new WebHistoryItem with initial flattened data.
- * @param data The pre-flattened data coming from restoreState.
- */
- /*package*/ WebHistoryItem(byte[] data) {
- mFlattenedData = data;
- synchronized (WebHistoryItem.class) {
- mId = sNextId++;
- }
- }
-
- /**
- * Construct a clone of a WebHistoryItem from the given item.
- * @param item The history item to clone.
- */
- private WebHistoryItem(WebHistoryItem item) {
- mFlattenedData = item.mFlattenedData;
- mId = item.mId;
- mFavicon = item.mFavicon;
- mNativeBridge = item.mNativeBridge;
- if (mNativeBridge != 0) {
- nativeRef(mNativeBridge);
- }
+ /* package */ WebHistoryItem() {
}
/**
@@ -100,7 +38,7 @@
*/
@Deprecated
public int getId() {
- return mId;
+ throw new MustOverrideException();
}
/**
@@ -112,8 +50,7 @@
* to synchronize this method.
*/
public String getUrl() {
- if (mNativeBridge == 0) return null;
- return nativeGetUrl(mNativeBridge);
+ throw new MustOverrideException();
}
/**
@@ -123,8 +60,7 @@
* @return The original url of this history item.
*/
public String getOriginalUrl() {
- if (mNativeBridge == 0) return null;
- return nativeGetOriginalUrl(mNativeBridge);
+ throw new MustOverrideException();
}
/**
@@ -134,8 +70,7 @@
* to synchronize this method.
*/
public String getTitle() {
- if (mNativeBridge == 0) return null;
- return nativeGetTitle(mNativeBridge);
+ throw new MustOverrideException();
}
/**
@@ -145,119 +80,14 @@
* to synchronize this method.
*/
public Bitmap getFavicon() {
- if (mFavicon == null && mNativeBridge != 0) {
- mFavicon = nativeGetFavicon(mNativeBridge);
- }
- return mFavicon;
- }
-
- /**
- * Return the touch icon url.
- * If no touch icon <link> tag was specified, returns
- * <host>/apple-touch-icon.png. The DownloadTouchIcon class that
- * attempts to retrieve the touch icon will handle the case where
- * that file does not exist. An icon set by a <link> tag is always
- * used in preference to an icon saved on the server.
- * @hide
- */
- public String getTouchIconUrl() {
- if (mTouchIconUrlFromLink != null) {
- return mTouchIconUrlFromLink;
- } else if (mTouchIconUrlServerDefault != null) {
- return mTouchIconUrlServerDefault;
- }
-
- try {
- URL url = new URL(getOriginalUrl());
- mTouchIconUrlServerDefault = new URL(url.getProtocol(), url.getHost(), url.getPort(),
- "/apple-touch-icon.png").toString();
- } catch (MalformedURLException e) {
- return null;
- }
- return mTouchIconUrlServerDefault;
- }
-
- /**
- * Return the custom data provided by the client.
- * @hide
- */
- public Object getCustomData() {
- return mCustomData;
- }
-
- /**
- * Set the custom data field.
- * @param data An Object containing any data the client wishes to associate
- * with the item.
- * @hide
- */
- public void setCustomData(Object data) {
- // NOTE: WebHistoryItems are used in multiple threads. However, the
- // public facing apis are all getters with the exception of this one
- // api. Since this api is exclusive to clients, we don't make any
- // promises about thread safety.
- mCustomData = data;
- }
-
- /**
- * Set the favicon.
- * @param icon A Bitmap containing the favicon for this history item.
- * Note: The VM ensures 32-bit atomic read/write operations so we don't have
- * to synchronize this method.
- */
- /*package*/ void setFavicon(Bitmap icon) {
- mFavicon = icon;
- }
-
- /**
- * Set the touch icon url. Will not overwrite an icon that has been
- * set already from a <link> tag, unless the new icon is precomposed.
- * @hide
- */
- /*package*/ void setTouchIconUrl(String url, boolean precomposed) {
- if (precomposed || mTouchIconUrlFromLink == null) {
- mTouchIconUrlFromLink = url;
- }
- }
-
- /**
- * Get the pre-flattened data.
- * Note: The VM ensures 32-bit atomic read/write operations so we don't have
- * to synchronize this method.
- */
- /*package*/ byte[] getFlattenedData() {
- if (mNativeBridge != 0) {
- return nativeGetFlattenedData(mNativeBridge);
- }
- return mFlattenedData;
- }
-
- /**
- * Inflate this item.
- * Note: The VM ensures 32-bit atomic read/write operations so we don't have
- * to synchronize this method.
- */
- /*package*/ void inflate(int nativeFrame) {
- mNativeBridge = inflate(nativeFrame, mFlattenedData);
- mFlattenedData = null;
+ throw new MustOverrideException();
}
/**
* Clone the history item for use by clients of WebView.
*/
protected synchronized WebHistoryItem clone() {
- return new WebHistoryItem(this);
+ throw new MustOverrideException();
}
- /* Natively inflate this item, this method is called in the WebCore thread.
- */
- private native int inflate(int nativeFrame, byte[] data);
- private native void nativeRef(int nptr);
- private native void nativeUnref(int nptr);
- private native String nativeGetTitle(int nptr);
- private native String nativeGetUrl(int nptr);
- private native String nativeGetOriginalUrl(int nptr);
- private native byte[] nativeGetFlattenedData(int nptr);
- private native Bitmap nativeGetFavicon(int nptr);
-
}
diff --git a/core/java/android/webkit/WebHistoryItemClassic.java b/core/java/android/webkit/WebHistoryItemClassic.java
new file mode 100644
index 0000000..1620fbf
--- /dev/null
+++ b/core/java/android/webkit/WebHistoryItemClassic.java
@@ -0,0 +1,221 @@
+/*
+ * 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 android.webkit;
+
+import android.graphics.Bitmap;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/* package */ class WebHistoryItemClassic extends WebHistoryItem implements Cloneable {
+ // Global identifier count.
+ private static int sNextId = 0;
+ // Unique identifier.
+ private final int mId;
+ // A point to a native WebHistoryItem instance which contains the actual data
+ private int mNativeBridge;
+ // The favicon for this item.
+ private Bitmap mFavicon;
+ // The pre-flattened data used for saving the state.
+ private byte[] mFlattenedData;
+ // The apple-touch-icon url for use when adding the site to the home screen,
+ // as obtained from a <link> element in the page.
+ private String mTouchIconUrlFromLink;
+ // If no <link> is specified, this holds the default location of the
+ // apple-touch-icon.
+ private String mTouchIconUrlServerDefault;
+ // Custom client data that is not flattened or read by native code.
+ private Object mCustomData;
+
+ /**
+ * Basic constructor that assigns a unique id to the item. Called by JNI
+ * only.
+ */
+ private WebHistoryItemClassic(int nativeBridge) {
+ synchronized (WebHistoryItemClassic.class) {
+ mId = sNextId++;
+ }
+ mNativeBridge = nativeBridge;
+ nativeRef(mNativeBridge);
+ }
+
+ protected void finalize() throws Throwable {
+ if (mNativeBridge != 0) {
+ nativeUnref(mNativeBridge);
+ mNativeBridge = 0;
+ }
+ }
+
+ /**
+ * Construct a new WebHistoryItem with initial flattened data.
+ * @param data The pre-flattened data coming from restoreState.
+ */
+ /*package*/ WebHistoryItemClassic(byte[] data) {
+ mFlattenedData = data;
+ synchronized (WebHistoryItemClassic.class) {
+ mId = sNextId++;
+ }
+ }
+
+ /**
+ * Construct a clone of a WebHistoryItem from the given item.
+ * @param item The history item to clone.
+ */
+ private WebHistoryItemClassic(WebHistoryItemClassic item) {
+ mFlattenedData = item.mFlattenedData;
+ mId = item.mId;
+ mFavicon = item.mFavicon;
+ mNativeBridge = item.mNativeBridge;
+ if (mNativeBridge != 0) {
+ nativeRef(mNativeBridge);
+ }
+ }
+
+ @Deprecated
+ public int getId() {
+ return mId;
+ }
+
+ public String getUrl() {
+ if (mNativeBridge == 0) return null;
+ return nativeGetUrl(mNativeBridge);
+ }
+
+ public String getOriginalUrl() {
+ if (mNativeBridge == 0) return null;
+ return nativeGetOriginalUrl(mNativeBridge);
+ }
+
+ public String getTitle() {
+ if (mNativeBridge == 0) return null;
+ return nativeGetTitle(mNativeBridge);
+ }
+
+ public Bitmap getFavicon() {
+ if (mFavicon == null && mNativeBridge != 0) {
+ mFavicon = nativeGetFavicon(mNativeBridge);
+ }
+ return mFavicon;
+ }
+
+ /**
+ * Return the touch icon url.
+ * If no touch icon <link> tag was specified, returns
+ * <host>/apple-touch-icon.png. The DownloadTouchIcon class that
+ * attempts to retrieve the touch icon will handle the case where
+ * that file does not exist. An icon set by a <link> tag is always
+ * used in preference to an icon saved on the server.
+ * @hide
+ */
+ public String getTouchIconUrl() {
+ if (mTouchIconUrlFromLink != null) {
+ return mTouchIconUrlFromLink;
+ } else if (mTouchIconUrlServerDefault != null) {
+ return mTouchIconUrlServerDefault;
+ }
+
+ try {
+ URL url = new URL(getOriginalUrl());
+ mTouchIconUrlServerDefault = new URL(url.getProtocol(), url.getHost(), url.getPort(),
+ "/apple-touch-icon.png").toString();
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ return mTouchIconUrlServerDefault;
+ }
+
+ /**
+ * Return the custom data provided by the client.
+ * @hide
+ */
+ public Object getCustomData() {
+ return mCustomData;
+ }
+
+ /**
+ * Set the custom data field.
+ * @param data An Object containing any data the client wishes to associate
+ * with the item.
+ * @hide
+ */
+ public void setCustomData(Object data) {
+ // NOTE: WebHistoryItems are used in multiple threads. However, the
+ // public facing apis are all getters with the exception of this one
+ // api. Since this api is exclusive to clients, we don't make any
+ // promises about thread safety.
+ mCustomData = data;
+ }
+
+ /**
+ * Set the favicon.
+ * @param icon A Bitmap containing the favicon for this history item.
+ * Note: The VM ensures 32-bit atomic read/write operations so we don't have
+ * to synchronize this method.
+ */
+ /*package*/ void setFavicon(Bitmap icon) {
+ mFavicon = icon;
+ }
+
+ /**
+ * Set the touch icon url. Will not overwrite an icon that has been
+ * set already from a <link> tag, unless the new icon is precomposed.
+ * @hide
+ */
+ /*package*/ void setTouchIconUrl(String url, boolean precomposed) {
+ if (precomposed || mTouchIconUrlFromLink == null) {
+ mTouchIconUrlFromLink = url;
+ }
+ }
+
+ /**
+ * Get the pre-flattened data.
+ * Note: The VM ensures 32-bit atomic read/write operations so we don't have
+ * to synchronize this method.
+ */
+ /*package*/ byte[] getFlattenedData() {
+ if (mNativeBridge != 0) {
+ return nativeGetFlattenedData(mNativeBridge);
+ }
+ return mFlattenedData;
+ }
+
+ /**
+ * Inflate this item.
+ * Note: The VM ensures 32-bit atomic read/write operations so we don't have
+ * to synchronize this method.
+ */
+ /*package*/ void inflate(int nativeFrame) {
+ mNativeBridge = inflate(nativeFrame, mFlattenedData);
+ mFlattenedData = null;
+ }
+
+ public synchronized WebHistoryItemClassic clone() {
+ return new WebHistoryItemClassic(this);
+ }
+
+ /* Natively inflate this item, this method is called in the WebCore thread.
+ */
+ private native int inflate(int nativeFrame, byte[] data);
+ private native void nativeRef(int nptr);
+ private native void nativeUnref(int nptr);
+ private native String nativeGetTitle(int nptr);
+ private native String nativeGetUrl(int nptr);
+ private native String nativeGetOriginalUrl(int nptr);
+ private native byte[] nativeGetFlattenedData(int nptr);
+ private native Bitmap nativeGetFavicon(int nptr);
+
+}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index fa3cb20..f2a041a 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -153,7 +153,8 @@
}
/**
- * Enables dumping the pages navigation cache to a text file.
+ * Enables dumping the pages navigation cache to a text file. The default
+ * is false.
*
* @deprecated This method is now obsolete.
*/
@@ -165,6 +166,8 @@
/**
* Gets whether dumping the navigation cache is enabled.
*
+ * @return whether dumping the navigation cache is enabled
+ * @see #setNavDump
* @deprecated This method is now obsolete.
*/
@Deprecated
@@ -285,14 +288,18 @@
}
/**
- * Sets whether the WebView loads a page with overview mode.
+ * Sets whether the WebView loads pages in overview mode. The default is
+ * false.
*/
public void setLoadWithOverviewMode(boolean overview) {
throw new MustOverrideException();
}
/**
- * Gets whether this WebView loads pages with overview mode.
+ * Gets whether this WebView loads pages in overview mode.
+ *
+ * @return whether this WebView loads pages in overview mode
+ * @see #setLoadWithOverviewMode
*/
public boolean getLoadWithOverviewMode() {
throw new MustOverrideException();
@@ -344,38 +351,45 @@
}
/**
- * Sets whether the WebView is saving form data.
+ * Sets whether the WebView should save form data. The default is true,
+ * unless in private browsing mode, when the value is always false.
*/
public void setSaveFormData(boolean save) {
throw new MustOverrideException();
}
/**
- * Gets whether the WebView is saving form data and displaying prior
- * entries/autofill++. Always false in private browsing mode.
+ * Gets whether the WebView saves form data. Always false in private
+ * browsing mode.
+ *
+ * @return whether the WebView saves form data
+ * @see #setSaveFormData
*/
public boolean getSaveFormData() {
throw new MustOverrideException();
}
/**
- * Stores whether the WebView is saving password.
+ * Sets whether the WebView should save passwords. The default is true.
*/
public void setSavePassword(boolean save) {
throw new MustOverrideException();
}
/**
- * Gets whether the WebView is saving password.
+ * Gets whether the WebView saves passwords.
+ *
+ * @return whether the WebView saves passwords
+ * @see #setSavePassword
*/
public boolean getSavePassword() {
throw new MustOverrideException();
}
/**
- * Sets the text zoom of the page in percent. Default is 100.
+ * Sets the text zoom of the page in percent. The default is 100.
*
- * @param textZoom the percent value for increasing or decreasing the text
+ * @param textZoom the text zoom in percent
*/
public synchronized void setTextZoom(int textZoom) {
throw new MustOverrideException();
@@ -384,7 +398,7 @@
/**
* Gets the text zoom of the page in percent.
*
- * @return a percent value describing the text zoom
+ * @return the text zoom of the page in percent
* @see #setTextSizeZoom
*/
public synchronized int getTextZoom() {
@@ -392,11 +406,10 @@
}
/**
- * Sets the text size of the page.
+ * Sets the text size of the page. The default is {@link TextSize#NORMAL}.
*
- * @param t the TextSize value for increasing or decreasing the text
- * @see WebSettings.TextSize
- * @deprecated Use {@link #setTextZoom(int)} instead.
+ * @param t the text size as a {@link TextSize} value
+ * @deprecated Use {@link #setTextZoom} instead.
*/
public synchronized void setTextSize(TextSize t) {
throw new MustOverrideException();
@@ -404,33 +417,33 @@
/**
* Gets the text size of the page. If the text size was previously specified
- * in percent using {@link #setTextZoom(int)}, this will return
- * the closest matching {@link TextSize}.
+ * in percent using {@link #setTextZoom}, this will return the closest
+ * matching {@link TextSize}.
*
- * @return a TextSize enum value describing the text size
- * @see WebSettings.TextSize
- * @deprecated Use {@link #getTextZoom()} instead.
+ * @return the text size as a {@link TextSize} value
+ * @see #setTextSize
+ * @deprecated Use {@link #getTextZoom} instead.
*/
public synchronized TextSize getTextSize() {
throw new MustOverrideException();
}
/**
- * Sets the default zoom density of the page. This should be called from UI
- * thread.
+ * Sets the default zoom density of the page. This must be called from the UI
+ * thread. The default is {@link ZoomDensity#MEDIUM}.
*
- * @param zoom a ZoomDensity value
- * @see WebSettings.ZoomDensity
+ * @param zoom the zoom density
*/
public void setDefaultZoom(ZoomDensity zoom) {
throw new MustOverrideException();
}
/**
- * Gets the default zoom density of the page. This should be called from UI
- * thread.
- * @return a ZoomDensity value
- * @see WebSettings.ZoomDensity
+ * Gets the default zoom density of the page. This should be called from
+ * the UI thread.
+ *
+ * @return the zoom density
+ * @see #setDefaultZoom
*/
public ZoomDensity getDefaultZoom() {
throw new MustOverrideException();
@@ -438,6 +451,7 @@
/**
* Enables using light touches to make a selection and activate mouseovers.
+ * The default is false.
*/
public void setLightTouchEnabled(boolean enabled) {
throw new MustOverrideException();
@@ -445,6 +459,9 @@
/**
* Gets whether light touches are enabled.
+ *
+ * @return whether light touches are enabled
+ * @see #setLightTouchEnabled
*/
public boolean getLightTouchEnabled() {
throw new MustOverrideException();
@@ -474,11 +491,16 @@
}
/**
- * Tells the WebView about user-agent string.
+ * Sets the user-agent string using an integer code.
+ * <ul>
+ * <li>0 means the WebView should use an Android user-agent string</li>
+ * <li>1 means the WebView should use a desktop user-agent string</li>
+ * </ul>
+ * Other values are ignored. The default is an Android user-agent string,
+ * i.e. code value 0.
*
- * @param ua 0 if the WebView should use an Android user-agent string,
- * 1 if the WebView should use a desktop user-agent string
- * @deprecated Please use setUserAgentString instead.
+ * @param ua the integer code for the user-agent string
+ * @deprecated Please use {@link #setUserAgentString} instead.
*/
@Deprecated
public synchronized void setUserAgent(int ua) {
@@ -486,12 +508,17 @@
}
/**
- * Gets the user-agent as an int.
+ * Gets the user-agent as an integer code.
+ * <ul>
+ * <li>-1 means the WebView is using a custom user-agent string set with
+ * {@link #setUserAgentString}</li>
+ * <li>0 means the WebView should use an Android user-agent string</li>
+ * <li>1 means the WebView should use a desktop user-agent string</li>
+ * </ul>
*
- * @return 0 if the WebView is using an Android user-agent string,
- * 1 if the WebView is using a desktop user-agent string,
- * -1 if the WebView is using user defined user-agent string
- * @deprecated Please use getUserAgentString instead.
+ * @return the integer code for the user-agent string
+ * @see #setUserAgent
+ * @deprecated Please use {@link #getUserAgentString} instead.
*/
@Deprecated
public synchronized int getUserAgent() {
@@ -499,7 +526,9 @@
}
/**
- * Tells the WebView to use the wide viewport.
+ * Tells the WebView to use a wide viewport. The default is false.
+ *
+ * @param use whether to use a wide viewport
*/
public synchronized void setUseWideViewPort(boolean use) {
throw new MustOverrideException();
@@ -509,26 +538,28 @@
* Gets whether the WebView is using a wide viewport.
*
* @return true if the WebView is using a wide viewport
+ * @see #setUseWideViewPort
*/
public synchronized boolean getUseWideViewPort() {
throw new MustOverrideException();
}
/**
- * Tells the WebView whether it supports multiple windows. TRUE means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
+ * Sets whether the WebView whether supports multiple windows. If set to
+ * true, {@link WebChromeClient#onCreateWindow} must be implemented by the
+ * host application. The default is false.
+ *
+ * @param support whether to suport multiple windows
*/
public synchronized void setSupportMultipleWindows(boolean support) {
throw new MustOverrideException();
}
/**
- * Gets whether the WebView is supporting multiple windows.
+ * Gets whether the WebView supports multiple windows.
*
- * @return true if the WebView is supporting multiple windows. This means
- * that {@link WebChromeClient#onCreateWindow(WebView, boolean,
- * boolean, Message)} is implemented by the host application.
+ * @return true if the WebView supports multiple windows
+ * @see #setSupportMultipleWindows
*/
public synchronized boolean supportMultipleWindows() {
throw new MustOverrideException();
@@ -536,10 +567,9 @@
/**
* Sets the underlying layout algorithm. This will cause a relayout of the
- * WebView. The default is NARROW_COLUMNS.
+ * WebView. The default is {@link LayoutAlgorithm#NARROW_COLUMNS}.
*
- * @param l a LayoutAlgorithm enum specifying the algorithm to use
- * @see WebSettings.LayoutAlgorithm
+ * @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value
*/
public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
throw new MustOverrideException();
@@ -548,10 +578,8 @@
/**
* Gets the current layout algorithm.
*
- * @return a LayoutAlgorithm enum value describing the layout algorithm
- * being used
+ * @return the layout algorithm in use, as a {@link LayoutAlgorithm} value
* @see #setLayoutAlgorithm
- * @see WebSettings.LayoutAlgorithm
*/
public synchronized LayoutAlgorithm getLayoutAlgorithm() {
throw new MustOverrideException();
@@ -596,7 +624,7 @@
}
/**
- * Sets the sans-serif font family name.
+ * Sets the sans-serif font family name. The default is "sans-serif".
*
* @param font a font family name
*/
@@ -608,6 +636,7 @@
* Gets the sans-serif font family name.
*
* @return the sans-serif font family name as a string
+ * @see #setSansSerifFontFamily
*/
public synchronized String getSansSerifFontFamily() {
throw new MustOverrideException();
@@ -883,9 +912,9 @@
public abstract void setAllowFileAccessFromFileURLs(boolean flag);
/**
- * Tells the WebView to enable plugins.
+ * Sets whether the WebView should enable plugins. The default is false.
*
- * @param flag true if the WebView should load plugins
+ * @param flag true if plugins should be enabled
* @deprecated This method has been deprecated in favor of
* {@link #setPluginState}
*/
@@ -898,7 +927,8 @@
* Tells the WebView to enable, disable, or have plugins on demand. On
* demand mode means that if a plugin exists that can handle the embedded
* content, a placeholder icon will be shown instead of the plugin. When
- * the placeholder is clicked, the plugin will be enabled.
+ * the placeholder is clicked, the plugin will be enabled. The default is
+ * {@link PluginState#OFF}.
*
* @param state a PluginState value
*/
@@ -921,23 +951,27 @@
/**
* Sets the path to where database storage API databases should be saved.
- * Note that the WebCore Database Tracker only allows the path to be set once.
+ * In order for the database storage API to function correctly, this method
+ * must be called with a path to which the application can write. This
+ * method should only be called once: repeated calls are ignored.
*
- * @param databasePath a String path to the directory where databases should
- * be saved. May be the empty string but should never
- * be null.
+ * @param databasePath a path to the directory where databases should be
+ * saved.
*/
// This will update WebCore when the Sync runs in the C++ side.
+ // Note that the WebCore Database Tracker only allows the path to be set
+ // once.
public synchronized void setDatabasePath(String databasePath) {
throw new MustOverrideException();
}
/**
- * Sets the path where the Geolocation permissions database should be saved.
+ * Sets the path where the Geolocation databases should be saved. In order
+ * for Geolocation permissions and cached positions to be persisted, this
+ * method must be called with a path to which the application can write.
*
- * @param databasePath a String path to the directory where the Geolocation
- * permissions database should be saved. May be the
- * empty string but should never be null.
+ * @param databasePath a path to the directory where databases should be
+ * saved.
*/
// This will update WebCore when the Sync runs in the C++ side.
public synchronized void setGeolocationDatabasePath(String databasePath) {
@@ -945,7 +979,10 @@
}
/**
- * Tells the WebView to enable Application Caches API.
+ * Sets whether the Application Caches API should be enabled. The default
+ * is false. Note that in order for the Application Caches API to be
+ * enabled, a valid database path must also be supplied to
+ * {@link #setAppCachePath}.
*
* @param flag true if the WebView should enable Application Caches
*/
@@ -954,20 +991,22 @@
}
/**
- * Sets a custom path to the Application Caches files. The client
- * must ensure it exists before this call.
+ * Sets the path to the Application Caches files. In order for the
+ * Application Caches API to be enabled, this method must be called with a
+ * path to which the application can write. This method should only be
+ * called once: repeated calls are ignored.
*
* @param appCachePath a String path to the directory containing
- * Application Caches files. The appCache path can be
- * the empty string but should not be null. Passing
- * null for this parameter will result in a no-op.
+ * Application Caches files.
+ * @see setAppCacheEnabled
*/
public synchronized void setAppCachePath(String appCachePath) {
throw new MustOverrideException();
}
/**
- * Sets the maximum size for the Application Caches content.
+ * Sets the maximum size for the Application Caches content. The default is
+ * {@link Long#MAX_VALUE}.
*
* @param appCacheMaxSize the maximum size in bytes
*/
@@ -976,7 +1015,9 @@
}
/**
- * Sets whether the database storage API is enabled.
+ * Sets whether the database storage API is enabled. The default value is
+ * false. See also {@link #setDatabasePath} for how to correctly set up the
+ * database storage API.
*
* @param flag true if the WebView should use the database storage API
*/
@@ -985,7 +1026,7 @@
}
/**
- * Sets whether the DOM storage API is enabled.
+ * Sets whether the DOM storage API is enabled. The default value is false.
*
* @param flag true if the WebView should use the DOM storage API
*/
@@ -997,15 +1038,16 @@
* Gets whether the DOM Storage APIs are enabled.
*
* @return true if the DOM Storage APIs are enabled
+ * @see #setDomStorageEnabled
*/
public synchronized boolean getDomStorageEnabled() {
throw new MustOverrideException();
}
/**
- * Gets the path to where database storage API databases are saved for
- * the current WebView.
+ * Gets the path to where database storage API databases are saved.
*
* @return the String path to the database storage API databases
+ * @see #setDatabasePath
*/
public synchronized String getDatabasePath() {
throw new MustOverrideException();
@@ -1015,13 +1057,16 @@
* Gets whether the database storage API is enabled.
*
* @return true if the database storage API is enabled
+ * @see #setDatabaseEnabled
*/
public synchronized boolean getDatabaseEnabled() {
throw new MustOverrideException();
}
/**
- * Sets whether Geolocation is enabled.
+ * Sets whether Geolocation is enabled. The default is true. See also
+ * {@link #setGeolocationDatabasePath} for how to correctly set up
+ * Geolocation.
*
* @param flag whether Geolocation should be enabled
*/
@@ -1064,6 +1109,7 @@
* Gets whether plugins are enabled.
*
* @return true if plugins are enabled
+ * @see #setPluginsEnabled
* @deprecated This method has been replaced by {@link #getPluginState}
*/
@Deprecated
@@ -1072,9 +1118,10 @@
}
/**
- * Gets the current plugin state.
+ * Gets the current state regarding whether plugins are enabled.
*
- * @return a value corresponding to the enum PluginState
+ * @return the plugin state as a {@link PluginState} value
+ * @see #setPluginState
*/
public synchronized PluginState getPluginState() {
throw new MustOverrideException();
@@ -1135,8 +1182,8 @@
}
/**
- * Sets the WebView's user-agent string. If the string "ua" is null or empty,
- * it will use the system default user-agent string.
+ * Sets the WebView's user-agent string. If the string is null or empty,
+ * the system default value will be used.
*/
public synchronized void setUserAgentString(String ua) {
throw new MustOverrideException();
@@ -1144,6 +1191,9 @@
/**
* Gets the WebView's user-agent string.
+ *
+ * @return the WebView's user-agent string
+ * @see #setUserAgentString
*/
public synchronized String getUserAgentString() {
throw new MustOverrideException();
@@ -1151,7 +1201,8 @@
/**
* Tells the WebView whether it needs to set a node to have focus when
- * {@link WebView#requestFocus(int, android.graphics.Rect)} is called.
+ * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. The
+ * default value is true.
*
* @param flag whether the WebView needs to set a node
*/
@@ -1161,9 +1212,10 @@
/**
* Sets the priority of the Render thread. Unlike the other settings, this
- * one only needs to be called once per process. The default is NORMAL.
+ * one only needs to be called once per process. The default value is
+ * {@link RenderPriority#NORMAL}.
*
- * @param priority a RenderPriority
+ * @param priority the priority
*/
public synchronized void setRenderPriority(RenderPriority priority) {
throw new MustOverrideException();
@@ -1171,20 +1223,25 @@
/**
* Overrides the way the cache is used. The way the cache is used is based
- * on the navigation option. For a normal page load, the cache is checked
+ * on the navigation type. For a normal page load, the cache is checked
* and content is re-validated as needed. When navigating back, content is
- * not revalidated, instead the content is just pulled from the cache.
- * This function allows the client to override this behavior.
+ * not revalidated, instead the content is just retrieved from the cache.
+ * This method allows the client to override this behavior by specifying
+ * one of {@link #LOAD_DEFAULT}, {@link #LOAD_NORMAL},
+ * {@link #LOAD_CACHE_ELSE_NETWORK}, {@link #LOAD_NO_CACHE} or
+ * {@link #LOAD_CACHE_ONLY}. The default value is {@link #LOAD_DEFAULT}.
*
- * @param mode one of the LOAD_ values
+ * @param mode the mode to use
*/
public void setCacheMode(int mode) {
throw new MustOverrideException();
}
/**
- * Gets the current setting for overriding the cache mode. For a full
- * description, see the {@link #setCacheMode(int)} function.
+ * Gets the current setting for overriding the cache mode.
+ *
+ * @return the current setting for overriding the cache mode
+ * @see #setCacheMode
*/
public int getCacheMode() {
throw new MustOverrideException();
diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java
index 38b5e5c..d3ec603 100644
--- a/core/java/android/webkit/WebSyncManager.java
+++ b/core/java/android/webkit/WebSyncManager.java
@@ -37,9 +37,6 @@
// handler of the sync thread
protected Handler mHandler;
// database for the persistent storage
- // Note that this remains uninitialised as it is unused. We cannot remove
- // the member as it leaked into the public API via CookieSyncManager.
- // TODO: hide this member, ditto for mHandler.
protected WebViewDatabase mDataBase;
// Ref count for calls to start/stop sync
private int mStartSyncRefCount;
@@ -65,6 +62,7 @@
protected WebSyncManager(Context context, String name) {
mThreadName = name;
if (context != null) {
+ mDataBase = WebViewDatabase.getInstance(context);
mSyncThread = new Thread(this);
mSyncThread.setName(mThreadName);
mSyncThread.start();
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 119fcd3..2545cd8 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -35,8 +35,8 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewDebug;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -44,6 +44,7 @@
import android.view.inputmethod.InputConnection;
import android.widget.AbsoluteLayout;
+import java.io.BufferedWriter;
import java.io.File;
import java.util.Map;
@@ -263,7 +264,7 @@
@Widget
public class WebView extends AbsoluteLayout
implements ViewTreeObserver.OnGlobalFocusChangeListener,
- ViewGroup.OnHierarchyChangeListener {
+ ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
private static final String LOGTAG = "webview_proxy";
@@ -1004,6 +1005,7 @@
*
* @return the current scale
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public float getScale() {
checkThread();
return mProvider.getScale();
@@ -1094,6 +1096,7 @@
*
* @return the URL for the current page
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public String getUrl() {
checkThread();
return mProvider.getUrl();
@@ -1108,6 +1111,7 @@
*
* @return the URL that was originally requested for the current page
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public String getOriginalUrl() {
checkThread();
return mProvider.getOriginalUrl();
@@ -1119,6 +1123,7 @@
*
* @return the title for the current page
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public String getTitle() {
checkThread();
return mProvider.getTitle();
@@ -1161,6 +1166,7 @@
*
* @return the height of the HTML content
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public int getContentHeight() {
checkThread();
return mProvider.getContentHeight();
@@ -1172,6 +1178,7 @@
* @return the width of the HTML content
* @hide
*/
+ @ViewDebug.ExportedProperty(category = "webview")
public int getContentWidth() {
return mProvider.getContentWidth();
}
@@ -1652,6 +1659,24 @@
mProvider.debugDump();
}
+ /**
+ * See {@link ViewDebug.HierarchyHandler#dumpViewHierarchyWithProperties(BufferedWriter, int)}
+ * @hide
+ */
+ @Override
+ public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
+ mProvider.dumpViewHierarchyWithProperties(out, level);
+ }
+
+ /**
+ * See {@link ViewDebug.HierarchyHandler#findHierarchyView(String, int)}
+ * @hide
+ */
+ @Override
+ public View findHierarchyView(String className, int hashCode) {
+ return mProvider.findHierarchyView(className, hashCode);
+ }
+
//-------------------------------------------------------------------------
// Interface for WebView providers
//-------------------------------------------------------------------------
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 84a6129..5eefbe1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -117,6 +117,8 @@
import junit.framework.Assert;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -132,6 +134,7 @@
import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -679,6 +682,8 @@
// after resize.
static private final int EDIT_RECT_BUFFER = 10;
+ static private final long SELECTION_HANDLE_ANIMATION_MS = 150;
+
// true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
private boolean mAutoRedraw;
@@ -945,21 +950,20 @@
private Drawable mSelectHandleLeft;
private Drawable mSelectHandleRight;
private Drawable mSelectHandleCenter;
- private Point mSelectHandleLeftOffset;
- private Point mSelectHandleRightOffset;
- private Point mSelectHandleCenterOffset;
- private Point mSelectCursorLeft = new Point();
- private int mSelectCursorLeftLayerId;
- private QuadF mSelectCursorLeftTextQuad = new QuadF();
- private Point mSelectCursorRight = new Point();
- private int mSelectCursorRightLayerId;
- private QuadF mSelectCursorRightTextQuad = new QuadF();
+ private Point mSelectOffset;
+ private Point mSelectCursorBase = new Point();
+ private Rect mSelectHandleBaseBounds = new Rect();
+ private int mSelectCursorBaseLayerId;
+ private QuadF mSelectCursorBaseTextQuad = new QuadF();
+ private Point mSelectCursorExtent = new Point();
+ private Rect mSelectHandleExtentBounds = new Rect();
+ private int mSelectCursorExtentLayerId;
+ private QuadF mSelectCursorExtentTextQuad = new QuadF();
private Point mSelectDraggingCursor;
- private Point mSelectDraggingOffset;
private QuadF mSelectDraggingTextQuad;
private boolean mIsCaretSelection;
- static final int HANDLE_ID_LEFT = 0;
- static final int HANDLE_ID_RIGHT = 1;
+ static final int HANDLE_ID_BASE = 0;
+ static final int HANDLE_ID_EXTENT = 1;
// the color used to highlight the touch rectangles
static final int HIGHLIGHT_COLOR = 0x6633b5e5;
@@ -1049,6 +1053,7 @@
static final int EDIT_TEXT_SIZE_CHANGED = 150;
static final int SHOW_CARET_HANDLE = 151;
static final int UPDATE_CONTENT_BOUNDS = 152;
+ static final int SCROLL_HANDLE_INTO_VIEW = 153;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
@@ -2196,7 +2201,7 @@
}
// We grab a copy of the back/forward list because a client of WebView
// may have invalidated the history list by calling clearHistory.
- WebBackForwardList list = copyBackForwardList();
+ WebBackForwardListClassic list = copyBackForwardList();
final int currentIndex = list.getCurrentIndex();
final int size = list.getSize();
// We should fail saving the state if the list is empty or the index is
@@ -2210,7 +2215,7 @@
// arrays.
ArrayList<byte[]> history = new ArrayList<byte[]>(size);
for (int i = 0; i < size; i++) {
- WebHistoryItem item = list.getItemAtIndex(i);
+ WebHistoryItemClassic item = list.getItemAtIndex(i);
if (null == item) {
// FIXME: this shouldn't happen
// need to determine how item got set to null
@@ -2409,7 +2414,7 @@
*/
@Override
public WebBackForwardList restoreState(Bundle inState) {
- WebBackForwardList returnList = null;
+ WebBackForwardListClassic returnList = null;
if (inState == null) {
return returnList;
}
@@ -2417,7 +2422,7 @@
mCertificate = SslCertificate.restoreState(
inState.getBundle("certificate"));
- final WebBackForwardList list = mCallbackProxy.getBackForwardList();
+ final WebBackForwardListClassic list = mCallbackProxy.getBackForwardList();
final int index = inState.getInt("index");
// We can't use a clone of the list because we need to modify the
// shared copy, so synchronize instead to prevent concurrent
@@ -2438,7 +2443,7 @@
// the item and thus our history list cannot be rebuilt.
return null;
}
- WebHistoryItem item = new WebHistoryItem(data);
+ WebHistoryItem item = new WebHistoryItemClassic(data);
list.addHistoryItem(item);
}
// Grab the most recent copy to return to the caller.
@@ -2611,7 +2616,7 @@
*/
@Override
public boolean canGoBack() {
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
+ WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
synchronized (l) {
if (l.getClearPending()) {
return false;
@@ -2634,7 +2639,7 @@
*/
@Override
public boolean canGoForward() {
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
+ WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
synchronized (l) {
if (l.getClearPending()) {
return false;
@@ -2657,7 +2662,7 @@
*/
@Override
public boolean canGoBackOrForward(int steps) {
- WebBackForwardList l = mCallbackProxy.getBackForwardList();
+ WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
synchronized (l) {
if (l.getClearPending()) {
return false;
@@ -3305,6 +3310,7 @@
}
if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
scrollLayerTo(scrollX, scrollY);
+ animateHandles();
return;
}
mInOverScrollMode = false;
@@ -3325,6 +3331,8 @@
mWebViewPrivate.super_scrollTo(scrollX, scrollY);
+ animateHandles();
+
if (mOverScrollGlow != null) {
mOverScrollGlow.pullGlow(getScrollX(), getScrollY(), oldX, oldY, maxX, maxY);
}
@@ -3371,7 +3379,7 @@
*/
@Override
public String getTouchIconUrl() {
- WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
+ WebHistoryItemClassic h = mCallbackProxy.getBackForwardList().getCurrentItem();
return h != null ? h.getTouchIconUrl() : null;
}
@@ -3535,7 +3543,7 @@
* See {@link WebView#copyBackForwardList()}
*/
@Override
- public WebBackForwardList copyBackForwardList() {
+ public WebBackForwardListClassic copyBackForwardList() {
return mCallbackProxy.getBackForwardList().clone();
}
@@ -3819,17 +3827,14 @@
return;
}
if (mSelectingText) {
- if (mSelectCursorLeftLayerId == mCurrentScrollingLayerId) {
- mSelectCursorLeft.offset(dx, dy);
- mSelectCursorLeftTextQuad.offset(dx, dy);
+ if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) {
+ mSelectCursorBase.offset(dx, dy);
+ mSelectCursorBaseTextQuad.offset(dx, dy);
}
- if (mSelectCursorRightLayerId == mCurrentScrollingLayerId) {
- mSelectCursorRight.offset(dx, dy);
- mSelectCursorRightTextQuad.offset(dx, dy);
+ if (mSelectCursorExtentLayerId == mCurrentScrollingLayerId) {
+ mSelectCursorExtent.offset(dx, dy);
+ mSelectCursorExtentTextQuad.offset(dx, dy);
}
- } else if (mHandleAlpha.getAlpha() > 0) {
- // stop fading as we're not going to move with the layer.
- mHandleAlphaAnimator.end();
}
if (mAutoCompletePopup != null &&
mCurrentScrollingLayerId == mEditTextLayerId) {
@@ -4445,9 +4450,6 @@
}
private void onZoomAnimationStart() {
- if (!mSelectingText && mHandleAlpha.getAlpha() > 0) {
- mHandleAlphaAnimator.end();
- }
}
private void onZoomAnimationEnd() {
@@ -4480,34 +4482,63 @@
private class SelectionHandleAlpha {
private int mAlpha = 0;
+ private int mTargetAlpha = 0;
+
public void setAlpha(int alpha) {
mAlpha = alpha;
- if (mSelectHandleCenter != null) {
- mSelectHandleCenter.setAlpha(alpha);
- mSelectHandleLeft.setAlpha(alpha);
- mSelectHandleRight.setAlpha(alpha);
- // TODO: Use partial invalidate
- invalidate();
- }
+ // TODO: Use partial invalidate
+ invalidate();
}
public int getAlpha() {
return mAlpha;
}
+ public void setTargetAlpha(int alpha) {
+ mTargetAlpha = alpha;
+ }
+
+ public int getTargetAlpha() {
+ return mTargetAlpha;
+ }
+
}
private void startSelectingText() {
mSelectingText = true;
mShowTextSelectionExtra = true;
- mHandleAlphaAnimator.setIntValues(255);
- mHandleAlphaAnimator.start();
+ animateHandles();
}
+
+ private void animateHandle(boolean canShow, ObjectAnimator animator,
+ Point selectionPoint, int selectionLayerId,
+ SelectionHandleAlpha alpha) {
+ boolean isVisible = canShow && mSelectingText
+ && ((mSelectionStarted && mSelectDraggingCursor == selectionPoint)
+ || isHandleVisible(selectionPoint, selectionLayerId));
+ int targetValue = isVisible ? 255 : 0;
+ if (targetValue != alpha.getTargetAlpha()) {
+ alpha.setTargetAlpha(targetValue);
+ animator.setIntValues(targetValue);
+ animator.setDuration(SELECTION_HANDLE_ANIMATION_MS);
+ animator.start();
+ }
+ }
+
+ private void animateHandles() {
+ boolean canShowBase = mSelectingText;
+ boolean canShowExtent = mSelectingText && !mIsCaretSelection;
+ animateHandle(canShowBase, mBaseHandleAlphaAnimator, mSelectCursorBase,
+ mSelectCursorBaseLayerId, mBaseAlpha);
+ animateHandle(canShowExtent, mExtentHandleAlphaAnimator,
+ mSelectCursorExtent, mSelectCursorExtentLayerId,
+ mExtentAlpha);
+ }
+
private void endSelectingText() {
mSelectingText = false;
mShowTextSelectionExtra = false;
- mHandleAlphaAnimator.setIntValues(0);
- mHandleAlphaAnimator.start();
+ animateHandles();
}
private void ensureSelectionHandles() {
@@ -4518,66 +4549,87 @@
com.android.internal.R.drawable.text_select_handle_left);
mSelectHandleRight = mContext.getResources().getDrawable(
com.android.internal.R.drawable.text_select_handle_right);
- mHandleAlpha.setAlpha(mHandleAlpha.getAlpha());
- mSelectHandleCenterOffset = new Point(0,
- -mSelectHandleCenter.getIntrinsicHeight());
- mSelectHandleLeftOffset = new Point(0,
+ // All handles have the same height, so we can save effort with
+ // this assumption.
+ mSelectOffset = new Point(0,
-mSelectHandleLeft.getIntrinsicHeight());
- mSelectHandleRightOffset = new Point(
- -mSelectHandleLeft.getIntrinsicWidth() / 2,
- -mSelectHandleRight.getIntrinsicHeight());
}
}
+ private void drawHandle(Point point, int handleId, Rect bounds,
+ int alpha, Canvas canvas) {
+ int offset;
+ int width;
+ int height;
+ Drawable drawable;
+ boolean isLeft = nativeIsHandleLeft(mNativeClass, handleId);
+ if (isLeft) {
+ drawable = mSelectHandleLeft;
+ width = mSelectHandleLeft.getIntrinsicWidth();
+ height = mSelectHandleLeft.getIntrinsicHeight();
+ // Magic formula copied from TextView
+ offset = (width * 3) / 4;
+ } else {
+ drawable = mSelectHandleRight;
+ width = mSelectHandleRight.getIntrinsicWidth();
+ height = mSelectHandleRight.getIntrinsicHeight();
+ // Magic formula copied from TextView
+ offset = width / 4;
+ }
+ int x = contentToViewDimension(point.x);
+ int y = contentToViewDimension(point.y);
+ bounds.set(x - offset, y, x - offset + width, y + height);
+ drawable.setBounds(bounds);
+ drawable.setAlpha(alpha);
+ drawable.draw(canvas);
+ }
+
private void drawTextSelectionHandles(Canvas canvas) {
- if (mHandleAlpha.getAlpha() == 0) {
+ if (mBaseAlpha.getAlpha() == 0 && mExtentAlpha.getAlpha() == 0) {
return;
}
ensureSelectionHandles();
- if (mSelectingText) {
- int[] handles = new int[4];
- getSelectionHandles(handles);
- int start_x = contentToViewDimension(handles[0]);
- int start_y = contentToViewDimension(handles[1]);
- int end_x = contentToViewDimension(handles[2]);
- int end_y = contentToViewDimension(handles[3]);
-
- if (mIsCaretSelection) {
- // Caret handle is centered
- start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
- mSelectHandleCenter.setBounds(start_x, start_y,
- start_x + mSelectHandleCenter.getIntrinsicWidth(),
- start_y + mSelectHandleCenter.getIntrinsicHeight());
- } else {
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
- }
- }
-
if (mIsCaretSelection) {
+ // Caret handle is centered
+ int x = contentToViewDimension(mSelectCursorBase.x) -
+ (mSelectHandleCenter.getIntrinsicWidth() / 2);
+ int y = contentToViewDimension(mSelectCursorBase.y);
+ mSelectHandleBaseBounds.set(x, y,
+ x + mSelectHandleCenter.getIntrinsicWidth(),
+ y + mSelectHandleCenter.getIntrinsicHeight());
+ mSelectHandleCenter.setBounds(mSelectHandleBaseBounds);
+ mSelectHandleCenter.setAlpha(mBaseAlpha.getAlpha());
mSelectHandleCenter.draw(canvas);
} else {
- mSelectHandleLeft.draw(canvas);
- mSelectHandleRight.draw(canvas);
+ drawHandle(mSelectCursorBase, HANDLE_ID_BASE,
+ mSelectHandleBaseBounds, mBaseAlpha.getAlpha(), canvas);
+ drawHandle(mSelectCursorExtent, HANDLE_ID_EXTENT,
+ mSelectHandleExtentBounds, mExtentAlpha.getAlpha(), canvas);
}
}
+ private boolean isHandleVisible(Point selectionPoint, int layerId) {
+ boolean isVisible = true;
+ if (mIsEditingText) {
+ isVisible = mEditTextContentBounds.contains(selectionPoint.x,
+ selectionPoint.y);
+ }
+ if (isVisible) {
+ isVisible = nativeIsPointVisible(mNativeClass, layerId,
+ selectionPoint.x, selectionPoint.y);
+ }
+ return isVisible;
+ }
+
/**
* Takes an int[4] array as an output param with the values being
* startX, startY, endX, endY
*/
private void getSelectionHandles(int[] handles) {
- handles[0] = mSelectCursorLeft.x;
- handles[1] = mSelectCursorLeft.y;
- handles[2] = mSelectCursorRight.x;
- handles[3] = mSelectCursorRight.y;
+ handles[0] = mSelectCursorBase.x;
+ handles[1] = mSelectCursorBase.y;
+ handles[2] = mSelectCursorExtent.x;
+ handles[3] = mSelectCursorExtent.y;
}
// draw history
@@ -4812,6 +4864,43 @@
}
/**
+ * Sets use of the Geolocation mock client. Also resets that client. Called
+ * by DRT on UI thread, need to proxy to WebCore thread.
+ *
+ * debug only
+ */
+ public void setUseMockGeolocation() {
+ mWebViewCore.sendMessage(EventHub.SET_USE_MOCK_GEOLOCATION);
+ }
+
+ /**
+ * Called by DRT on WebCore thread.
+ *
+ * debug only
+ */
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
+ mWebViewCore.setMockGeolocationPosition(latitude, longitude, accuracy);
+ }
+
+ /**
+ * Called by DRT on WebCore thread.
+ *
+ * debug only
+ */
+ public void setMockGeolocationError(int code, String message) {
+ mWebViewCore.setMockGeolocationError(code, message);
+ }
+
+ /**
+ * Called by DRT on WebCore thread.
+ *
+ * debug only
+ */
+ public void setMockGeolocationPermission(boolean allow) {
+ mWebViewCore.setMockGeolocationPermission(allow);
+ }
+
+ /**
* Called by DRT on WebCore thread.
*
* debug only
@@ -5044,8 +5133,8 @@
ClipboardManager cm = (ClipboardManager)(mContext
.getSystemService(Context.CLIPBOARD_SERVICE));
if (cm.hasPrimaryClip()) {
- Point cursorPoint = new Point(contentToViewX(mSelectCursorLeft.x),
- contentToViewY(mSelectCursorLeft.y));
+ Point cursorPoint = new Point(contentToViewX(mSelectCursorBase.x),
+ contentToViewY(mSelectCursorBase.y));
Point cursorTop = calculateCaretTop();
cursorTop.set(contentToViewX(cursorTop.x),
contentToViewY(cursorTop.y));
@@ -5095,12 +5184,12 @@
* calculates the top of a caret.
*/
private Point calculateCaretTop() {
- float scale = scaleAlongSegment(mSelectCursorLeft.x, mSelectCursorLeft.y,
- mSelectCursorLeftTextQuad.p4, mSelectCursorLeftTextQuad.p3);
+ float scale = scaleAlongSegment(mSelectCursorBase.x, mSelectCursorBase.y,
+ mSelectCursorBaseTextQuad.p4, mSelectCursorBaseTextQuad.p3);
int x = Math.round(scaleCoordinate(scale,
- mSelectCursorLeftTextQuad.p1.x, mSelectCursorLeftTextQuad.p2.x));
+ mSelectCursorBaseTextQuad.p1.x, mSelectCursorBaseTextQuad.p2.x));
int y = Math.round(scaleCoordinate(scale,
- mSelectCursorLeftTextQuad.p1.y, mSelectCursorLeftTextQuad.p2.y));
+ mSelectCursorBaseTextQuad.p1.y, mSelectCursorBaseTextQuad.p2.y));
return new Point(x, y);
}
@@ -5111,50 +5200,12 @@
}
private void syncSelectionCursors() {
- mSelectCursorLeftLayerId =
- nativeGetHandleLayerId(mNativeClass, HANDLE_ID_LEFT,
- mSelectCursorLeft, mSelectCursorLeftTextQuad);
- mSelectCursorRightLayerId =
- nativeGetHandleLayerId(mNativeClass, HANDLE_ID_RIGHT,
- mSelectCursorRight, mSelectCursorRightTextQuad);
- }
-
- private void adjustSelectionCursors() {
- if (mIsCaretSelection) {
- syncSelectionCursors();
- return; // no need to swap left and right handles.
- }
-
- boolean wasDraggingLeft = (mSelectDraggingCursor == mSelectCursorLeft);
- int oldX = mSelectDraggingCursor.x;
- int oldY = mSelectDraggingCursor.y;
- int oldLeftX = mSelectCursorLeft.x;
- int oldLeftY = mSelectCursorLeft.y;
- int oldRightX = mSelectCursorRight.x;
- int oldRightY = mSelectCursorRight.y;
- syncSelectionCursors();
-
- boolean rightChanged = (oldRightX != mSelectCursorRight.x
- || oldRightY != mSelectCursorRight.y);
- boolean leftChanged = (oldLeftX != mSelectCursorLeft.x
- || oldLeftY != mSelectCursorLeft.y);
- if (leftChanged && rightChanged) {
- // Left and right switched places, so swap dragging cursor
- boolean draggingLeft = !wasDraggingLeft;
- mSelectDraggingCursor = (draggingLeft
- ? mSelectCursorLeft : mSelectCursorRight);
- mSelectDraggingTextQuad = (draggingLeft
- ? mSelectCursorLeftTextQuad : mSelectCursorRightTextQuad);
- mSelectDraggingOffset = (draggingLeft
- ? mSelectHandleLeftOffset : mSelectHandleRightOffset);
- }
- mSelectDraggingCursor.set(oldX, oldY);
- }
-
- private float distanceSquared(int x, int y, Point p) {
- float dx = p.x - x;
- float dy = p.y - y;
- return (dx * dx) + (dy * dy);
+ mSelectCursorBaseLayerId =
+ nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE,
+ mSelectCursorBase, mSelectCursorBaseTextQuad);
+ mSelectCursorExtentLayerId =
+ nativeGetHandleLayerId(mNativeClass, HANDLE_ID_EXTENT,
+ mSelectCursorExtent, mSelectCursorExtentTextQuad);
}
private boolean setupWebkitSelect() {
@@ -5169,18 +5220,11 @@
}
private void updateWebkitSelection() {
- int[] handles = null;
- if (mIsCaretSelection) {
- mSelectCursorRight.set(mSelectCursorLeft.x, mSelectCursorLeft.y);
- }
- if (mSelectingText) {
- handles = new int[4];
- getSelectionHandles(handles);
- } else {
- nativeSetTextSelection(mNativeClass, 0);
- }
+ int handleId = (mSelectDraggingCursor == mSelectCursorBase)
+ ? HANDLE_ID_BASE : HANDLE_ID_EXTENT;
mWebViewCore.removeMessages(EventHub.SELECT_TEXT);
- mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles);
+ mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT,
+ mSelectDraggingCursor.x, mSelectDraggingCursor.y, (Integer)handleId);
}
private void resetCaretTimer() {
@@ -5543,21 +5587,21 @@
Point caretTop = calculateCaretTop();
if (visibleRect.width() < mEditTextContentBounds.width()) {
// The whole edit won't fit in the width, so use the caret rect
- if (mSelectCursorLeft.x < caretTop.x) {
- showRect.left = Math.max(0, mSelectCursorLeft.x - buffer);
+ if (mSelectCursorBase.x < caretTop.x) {
+ showRect.left = Math.max(0, mSelectCursorBase.x - buffer);
showRect.right = caretTop.x + buffer;
} else {
showRect.left = Math.max(0, caretTop.x - buffer);
- showRect.right = mSelectCursorLeft.x + buffer;
+ showRect.right = mSelectCursorBase.x + buffer;
}
}
if (visibleRect.height() < mEditTextContentBounds.height()) {
// The whole edit won't fit in the height, so use the caret rect
- if (mSelectCursorLeft.y > caretTop.y) {
+ if (mSelectCursorBase.y > caretTop.y) {
showRect.top = Math.max(0, caretTop.y - buffer);
- showRect.bottom = mSelectCursorLeft.y + buffer;
+ showRect.bottom = mSelectCursorBase.y + buffer;
} else {
- showRect.top = Math.max(0, mSelectCursorLeft.y - buffer);
+ showRect.top = Math.max(0, mSelectCursorBase.y - buffer);
showRect.bottom = caretTop.y + buffer;
}
}
@@ -5801,28 +5845,19 @@
ensureSelectionHandles();
int shiftedY = y - getTitleHeight() + getScrollY();
int shiftedX = x + getScrollX();
- if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds()
+ if (mSelectHandleBaseBounds.contains(shiftedX, shiftedY)) {
+ mSelectionStarted = true;
+ mSelectDraggingCursor = mSelectCursorBase;
+ mSelectDraggingTextQuad = mSelectCursorBaseTextQuad;
+ if (mIsCaretSelection) {
+ mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+ hidePasteButton();
+ }
+ } else if (mSelectHandleExtentBounds
.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
- mSelectDraggingCursor = mSelectCursorLeft;
- mSelectDraggingOffset = mSelectHandleCenterOffset;
- mSelectDraggingTextQuad = mSelectCursorLeftTextQuad;
- mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
- hidePasteButton();
- } else if (mSelectHandleLeft != null
- && mSelectHandleLeft.getBounds()
- .contains(shiftedX, shiftedY)) {
- mSelectionStarted = true;
- mSelectDraggingOffset = mSelectHandleLeftOffset;
- mSelectDraggingCursor = mSelectCursorLeft;
- mSelectDraggingTextQuad = mSelectCursorLeftTextQuad;
- } else if (mSelectHandleRight != null
- && mSelectHandleRight.getBounds()
- .contains(shiftedX, shiftedY)) {
- mSelectionStarted = true;
- mSelectDraggingOffset = mSelectHandleRightOffset;
- mSelectDraggingCursor = mSelectCursorRight;
- mSelectDraggingTextQuad = mSelectCursorRightTextQuad;
+ mSelectDraggingCursor = mSelectCursorExtent;
+ mSelectDraggingTextQuad = mSelectCursorExtentTextQuad;
} else if (mIsCaretSelection) {
selectionDone();
}
@@ -5867,9 +5902,9 @@
}
if (deltaX != 0 || deltaY != 0) {
int handleX = contentX +
- viewToContentDimension(mSelectDraggingOffset.x);
+ viewToContentDimension(mSelectOffset.x);
int handleY = contentY +
- viewToContentDimension(mSelectDraggingOffset.y);
+ viewToContentDimension(mSelectOffset.y);
mSelectDraggingCursor.set(handleX, handleY);
boolean inCursorText =
mSelectDraggingTextQuad.containsPoint(handleX, handleY);
@@ -6006,12 +6041,15 @@
break;
}
case MotionEvent.ACTION_UP: {
- endScrollEdit();
- if (!mConfirmMove && mIsEditingText && mSelectionStarted &&
- mIsCaretSelection) {
- showPasteWindow();
- stopTouch();
- break;
+ if (mIsEditingText && mSelectionStarted) {
+ endScrollEdit();
+ mPrivateHandler.sendEmptyMessageDelayed(SCROLL_HANDLE_INTO_VIEW,
+ TEXT_SCROLL_FIRST_SCROLL_MS);
+ if (!mConfirmMove && mIsCaretSelection) {
+ showPasteWindow();
+ stopTouch();
+ break;
+ }
}
mLastTouchUpTime = eventTime;
if (mSentAutoScrollMessage) {
@@ -6118,6 +6156,10 @@
}
}
+ private static int getSelectionCoordinate(int coordinate, int min, int max) {
+ return Math.max(Math.min(coordinate, max), min);
+ }
+
private void beginScrollEdit() {
if (mLastEditScroll == 0) {
mLastEditScroll = SystemClock.uptimeMillis() -
@@ -6126,10 +6168,37 @@
}
}
+ private void scrollDraggedSelectionHandleIntoView() {
+ if (mSelectDraggingCursor == null) {
+ return;
+ }
+ int x = mSelectDraggingCursor.x;
+ int y = mSelectDraggingCursor.y;
+ if (!mEditTextContentBounds.contains(x,y)) {
+ int left = Math.min(0, x - mEditTextContentBounds.left - EDIT_RECT_BUFFER);
+ int right = Math.max(0, x - mEditTextContentBounds.right + EDIT_RECT_BUFFER);
+ int deltaX = left + right;
+ int above = Math.min(0, y - mEditTextContentBounds.top - EDIT_RECT_BUFFER);
+ int below = Math.max(0, y - mEditTextContentBounds.bottom + EDIT_RECT_BUFFER);
+ int deltaY = above + below;
+ if (deltaX != 0 || deltaY != 0) {
+ int scrollX = getTextScrollX() + deltaX;
+ int scrollY = getTextScrollY() + deltaY;
+ scrollX = clampBetween(scrollX, 0, getMaxTextScrollX());
+ scrollY = clampBetween(scrollY, 0, getMaxTextScrollY());
+ scrollEditText(scrollX, scrollY);
+ }
+ }
+ }
+
private void endScrollEdit() {
mLastEditScroll = 0;
}
+ private static int clampBetween(int value, int min, int max) {
+ return Math.max(min, Math.min(value, max));
+ }
+
private static int getTextScrollDelta(float speed, long deltaT) {
float distance = speed * deltaT;
int intDistance = (int)Math.floor(distance);
@@ -6145,10 +6214,10 @@
*/
private void scrollEditWithCursor() {
if (mLastEditScroll != 0) {
- int x = viewToContentX(mLastTouchX + getScrollX() + mSelectDraggingOffset.x);
+ int x = viewToContentX(mLastTouchX + getScrollX() + mSelectOffset.x);
float scrollSpeedX = getTextScrollSpeed(x, mEditTextContentBounds.left,
mEditTextContentBounds.right);
- int y = viewToContentY(mLastTouchY + getScrollY() + mSelectDraggingOffset.y);
+ int y = viewToContentY(mLastTouchY + getScrollY() + mSelectOffset.y);
float scrollSpeedY = getTextScrollSpeed(y, mEditTextContentBounds.top,
mEditTextContentBounds.bottom);
if (scrollSpeedX == 0.0f && scrollSpeedY == 0.0f) {
@@ -6158,24 +6227,27 @@
long timeSinceLastUpdate = currentTime - mLastEditScroll;
int deltaX = getTextScrollDelta(scrollSpeedX, timeSinceLastUpdate);
int deltaY = getTextScrollDelta(scrollSpeedY, timeSinceLastUpdate);
+ int scrollX = getTextScrollX() + deltaX;
+ scrollX = clampBetween(scrollX, 0, getMaxTextScrollX());
+ int scrollY = getTextScrollY() + deltaY;
+ scrollY = clampBetween(scrollY, 0, getMaxTextScrollY());
+
mLastEditScroll = currentTime;
- if (deltaX == 0 && deltaY == 0) {
+ if (scrollX == getTextScrollX() && scrollY == getTextScrollY()) {
// By probability no text scroll this time. Try again later.
mPrivateHandler.sendEmptyMessageDelayed(SCROLL_EDIT_TEXT,
TEXT_SCROLL_FIRST_SCROLL_MS);
} else {
- int scrollX = getTextScrollX() + deltaX;
- scrollX = Math.min(getMaxTextScrollX(), scrollX);
- scrollX = Math.max(0, scrollX);
- int scrollY = getTextScrollY() + deltaY;
- scrollY = Math.min(getMaxTextScrollY(), scrollY);
- scrollY = Math.max(0, scrollY);
- scrollEditText(scrollX, scrollY);
- int cursorX = mSelectDraggingCursor.x;
- int cursorY = mSelectDraggingCursor.y;
- mSelectDraggingCursor.set(x - deltaX, y - deltaY);
+ int selectionX = getSelectionCoordinate(x,
+ mEditTextContentBounds.left, mEditTextContentBounds.right);
+ int selectionY = getSelectionCoordinate(y,
+ mEditTextContentBounds.top, mEditTextContentBounds.bottom);
+ int oldX = mSelectDraggingCursor.x;
+ int oldY = mSelectDraggingCursor.y;
+ mSelectDraggingCursor.set(selectionX, selectionY);
updateWebkitSelection();
- mSelectDraggingCursor.set(cursorX, cursorY);
+ scrollEditText(scrollX, scrollY);
+ mSelectDraggingCursor.set(oldX, oldY);
}
}
}
@@ -6231,10 +6303,10 @@
// scrolling. The rectangle is in document coordinates.
final int maxX = mScrollingLayerRect.right;
final int maxY = mScrollingLayerRect.bottom;
- final int resultX = Math.max(0,
- Math.min(mScrollingLayerRect.left + contentX, maxX));
- final int resultY = Math.max(0,
- Math.min(mScrollingLayerRect.top + contentY, maxY));
+ final int resultX = clampBetween(maxX, 0,
+ mScrollingLayerRect.left + contentX);
+ final int resultY = clampBetween(maxY, 0,
+ mScrollingLayerRect.top + contentY);
if (resultX != mScrollingLayerRect.left
|| resultY != mScrollingLayerRect.top
@@ -6335,10 +6407,10 @@
int x = Math.round(newX);
int y = Math.round(newY);
if (mIsEditingText) {
- x = Math.max(mEditTextContentBounds.left,
- Math.min(mEditTextContentBounds.right, x));
- y = Math.max(mEditTextContentBounds.top,
- Math.min(mEditTextContentBounds.bottom, y));
+ x = clampBetween(x, mEditTextContentBounds.left,
+ mEditTextContentBounds.right);
+ y = clampBetween(y, mEditTextContentBounds.top,
+ mEditTextContentBounds.bottom);
}
mSelectDraggingCursor.set(x, y);
}
@@ -6401,9 +6473,12 @@
private long mTrackballUpTime = 0;
private long mLastCursorTime = 0;
private Rect mLastCursorBounds;
- private SelectionHandleAlpha mHandleAlpha = new SelectionHandleAlpha();
- private ObjectAnimator mHandleAlphaAnimator =
- ObjectAnimator.ofInt(mHandleAlpha, "alpha", 0);
+ private SelectionHandleAlpha mBaseAlpha = new SelectionHandleAlpha();
+ private SelectionHandleAlpha mExtentAlpha = new SelectionHandleAlpha();
+ private ObjectAnimator mBaseHandleAlphaAnimator =
+ ObjectAnimator.ofInt(mBaseAlpha, "alpha", 0);
+ private ObjectAnimator mExtentHandleAlphaAnimator =
+ ObjectAnimator.ofInt(mExtentAlpha, "alpha", 0);
// Set by default; BrowserActivity clears to interpret trackball data
// directly for movement. Currently, the framework only passes
@@ -7437,7 +7512,7 @@
mEditTextLayerId = initData.mNodeLayerId;
nativeMapLayerRect(mNativeClass, mEditTextLayerId,
mEditTextContentBounds);
- mEditTextContent.set(initData.mContentRect);
+ mEditTextContent.set(initData.mClientRect);
relocateAutoCompletePopup();
}
break;
@@ -7518,6 +7593,10 @@
scrollEditWithCursor();
break;
+ case SCROLL_HANDLE_INTO_VIEW:
+ scrollDraggedSelectionHandleIntoView();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -7553,8 +7632,8 @@
.contains(x, y);
} else {
isPressingHandle =
- mSelectHandleLeft.getBounds().contains(x, y)
- || mSelectHandleRight.getBounds().contains(x, y);
+ mSelectHandleBaseBounds.contains(x, y)
+ || mSelectHandleExtentBounds.contains(x, y);
}
return isPressingHandle;
}
@@ -7901,8 +7980,10 @@
if (data.mSelectTextPtr != 0 &&
(data.mStart != data.mEnd ||
- (mFieldPointer == nodePointer && mFieldPointer != 0))) {
- mIsCaretSelection = (data.mStart == data.mEnd);
+ (mFieldPointer == nodePointer && mFieldPointer != 0) ||
+ (nodePointer == 0 && data.mStart == 0 && data.mEnd == 0))) {
+ mIsEditingText = (mFieldPointer == nodePointer) && nodePointer != 0;
+ mIsCaretSelection = (data.mStart == data.mEnd && nodePointer != 0);
if (mIsCaretSelection &&
(mInputConnection == null ||
mInputConnection.getEditable().length() == 0)) {
@@ -7911,11 +7992,10 @@
} else {
if (!mSelectingText) {
setupWebkitSelect();
- } else if (!mSelectionStarted) {
- syncSelectionCursors();
} else {
- adjustSelectionCursors();
+ syncSelectionCursors();
}
+ animateHandles();
if (mIsCaretSelection) {
resetCaretTimer();
}
@@ -7931,8 +8011,10 @@
float maxScrollX = getMaxTextScrollX();
float scrollPercentX = ((float)scrollX)/maxScrollX;
mEditTextContent.offsetTo(-scrollX, -scrollY);
- mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SCROLL_TEXT_INPUT, 0,
+ mWebViewCore.removeMessages(EventHub.SCROLL_TEXT_INPUT);
+ mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0,
scrollY, (Float)scrollPercentX);
+ animateHandles();
}
private void beginTextBatch() {
@@ -8518,6 +8600,54 @@
WebViewCore.setShouldMonitorWebCoreThread();
}
+ @Override
+ public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
+ int layer = getBaseLayer();
+ if (layer != 0) {
+ try {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ ViewStateSerializer.dumpLayerHierarchy(layer, stream, level);
+ stream.close();
+ byte[] buf = stream.toByteArray();
+ out.write(new String(buf, "ascii"));
+ } catch (IOException e) {}
+ }
+ }
+
+ @Override
+ public View findHierarchyView(String className, int hashCode) {
+ if (mNativeClass == 0) return null;
+ Picture pic = new Picture();
+ if (!nativeDumpLayerContentToPicture(mNativeClass, className, hashCode, pic)) {
+ return null;
+ }
+ return new PictureWrapperView(getContext(), pic, mWebView);
+ }
+
+ private static class PictureWrapperView extends View {
+ Picture mPicture;
+ WebView mWebView;
+
+ public PictureWrapperView(Context context, Picture picture, WebView parent) {
+ super(context);
+ mPicture = picture;
+ mWebView = parent;
+ setWillNotDraw(false);
+ setRight(mPicture.getWidth());
+ setBottom(mPicture.getHeight());
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawPicture(mPicture);
+ }
+
+ @Override
+ public boolean post(Runnable action) {
+ return mWebView.post(action);
+ }
+ }
+
private native void nativeCreate(int ptr, String drawableDir, boolean isHighEndGfx);
private native void nativeDebugDump();
private static native void nativeDestroy(int ptr);
@@ -8538,6 +8668,8 @@
int scrollingLayer);
private native int nativeGetBaseLayer(int nativeInstance);
private native void nativeCopyBaseContentToPicture(Picture pict);
+ private native boolean nativeDumpLayerContentToPicture(int nativeInstance,
+ String className, int layerId, Picture pict);
private native boolean nativeHasContent();
private native void nativeStopGL(int ptr);
private native void nativeDiscardAllTextures();
@@ -8581,4 +8713,7 @@
private static native int nativeSetHwAccelerated(int instance, boolean hwAccelerated);
private static native void nativeFindMaxVisibleRect(int instance, int layerId,
Rect visibleContentRect);
+ private static native boolean nativeIsHandleLeft(int instance, int handleId);
+ private static native boolean nativeIsPointVisible(int instance,
+ int layerId, int contentX, int contentY);
}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 6aff10a..64a5918 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -204,35 +204,6 @@
}
/**
- * Notify the host application that an SSL error occurred while loading a
- * resource, but the WebView chose to proceed anyway based on a
- * decision retained from a previous response to onReceivedSslError().
- * @hide
- */
- public void onProceededAfterSslError(WebView view, SslError error) {
- }
-
- /**
- * Notify the host application to handle a SSL client certificate
- * request (display the request to the user and ask whether to
- * proceed with a client certificate or not). The host application
- * has to call either handler.cancel() or handler.proceed() as the
- * connection is suspended and waiting for the response. The
- * default behavior is to cancel, returning no client certificate.
- *
- * @param view The WebView that is initiating the callback.
- * @param handler A ClientCertRequestHandler object that will
- * handle the user's response.
- * @param host_and_port The host and port of the requesting server.
- *
- * @hide
- */
- public void onReceivedClientCertRequest(WebView view,
- ClientCertRequestHandler handler, String host_and_port) {
- handler.cancel();
- }
-
- /**
* Notify the host application to handle an authentication request. The
* default behavior is to cancel the request.
*
diff --git a/core/java/android/webkit/WebViewClientClassicExt.java b/core/java/android/webkit/WebViewClientClassicExt.java
new file mode 100644
index 0000000..a873585
--- /dev/null
+++ b/core/java/android/webkit/WebViewClientClassicExt.java
@@ -0,0 +1,53 @@
+/*
+ * 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 android.webkit;
+
+import android.net.http.SslError;
+
+/**
+ * Adds WebViewClassic specific extension methods to the WebViewClient callback class.
+ * These are not part of the public WebView API, so the class is hidden.
+ * @hide
+ */
+public class WebViewClientClassicExt extends WebViewClient {
+
+ /**
+ * Notify the host application that an SSL error occurred while loading a
+ * resource, but the WebView chose to proceed anyway based on a
+ * decision retained from a previous response to onReceivedSslError().
+ */
+ public void onProceededAfterSslError(WebView view, SslError error) {
+ }
+
+ /**
+ * Notify the host application to handle a SSL client certificate
+ * request (display the request to the user and ask whether to
+ * proceed with a client certificate or not). The host application
+ * has to call either handler.cancel() or handler.proceed() as the
+ * connection is suspended and waiting for the response. The
+ * default behavior is to cancel, returning no client certificate.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param handler A ClientCertRequestHandler object that will
+ * handle the user's response.
+ * @param host_and_port The host and port of the requesting server.
+ */
+ public void onReceivedClientCertRequest(WebView view,
+ ClientCertRequestHandler handler, String host_and_port) {
+ handler.cancel();
+ }
+}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 728ddbf..7fb3afe 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -132,6 +132,8 @@
private int mRestoredX = 0;
private int mRestoredY = 0;
+ private MockGeolocation mMockGeolocation = new MockGeolocation(this);
+
private DeviceMotionAndOrientationManager mDeviceMotionAndOrientationManager =
new DeviceMotionAndOrientationManager(this);
private DeviceMotionService mDeviceMotionService;
@@ -619,8 +621,6 @@
*/
private native void nativeNotifyAnimationStarted(int nativeClass);
- private native boolean nativeFocusBoundsChanged(int nativeClass);
-
private native boolean nativeKey(int nativeClass, int keyCode,
int unichar, int repeatCount, boolean isShift, boolean isAlt,
boolean isSym, boolean isDown);
@@ -960,7 +960,7 @@
public int mMaxLength;
public Rect mContentBounds;
public int mNodeLayerId;
- public Rect mContentRect;
+ public Rect mClientRect;
}
// mAction of TouchEventData can be MotionEvent.getAction() which uses the
@@ -1199,6 +1199,7 @@
static final int SET_INITIAL_FOCUS = 224;
static final int SAVE_VIEW_STATE = 225;
+ static final int SET_USE_MOCK_GEOLOCATION = 226;
// Private handler for WebCore messages.
private Handler mHandler;
@@ -1306,13 +1307,8 @@
} else {
xPercent = ((Float) msg.obj).floatValue();
}
- Rect contentBounds = new Rect();
nativeScrollFocusedTextInput(mNativeClass, xPercent,
- msg.arg2, contentBounds);
- Message.obtain(
- mWebViewClassic.mPrivateHandler,
- WebViewClassic.UPDATE_CONTENT_BOUNDS,
- contentBounds).sendToTarget();
+ msg.arg2);
break;
case LOAD_URL: {
@@ -1660,6 +1656,10 @@
(Set<String>) msg.obj);
break;
+ case SET_USE_MOCK_GEOLOCATION:
+ setUseMockGeolocation();
+ break;
+
case SET_USE_MOCK_DEVICE_ORIENTATION:
setUseMockDeviceOrientation();
break;
@@ -1708,13 +1708,9 @@
nativeInsertText(mNativeClass, (String) msg.obj);
break;
case SELECT_TEXT: {
- int[] args = (int[]) msg.obj;
- if (args == null) {
- nativeClearTextSelection(mNativeClass);
- } else {
- nativeSelectText(mNativeClass, args[0],
- args[1], args[2], args[3]);
- }
+ int handleId = (Integer) msg.obj;
+ nativeSelectText(mNativeClass, handleId,
+ msg.arg1, msg.arg2);
break;
}
case SELECT_WORD_AT: {
@@ -2192,7 +2188,6 @@
// only non-null if it is for the first picture set after the first layout
ViewState mViewState;
boolean mFirstLayoutForNonStandardLoad;
- boolean mFocusSizeChanged;
}
DrawData mLastDrawData = null;
@@ -2247,7 +2242,6 @@
private void webkitDraw(DrawData draw) {
if (mWebViewClassic != null) {
- draw.mFocusSizeChanged = nativeFocusBoundsChanged(mNativeClass);
draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight);
if (mSettings.getUseWideViewPort()) {
draw.mMinPrefWidth = Math.max(
@@ -2330,7 +2324,6 @@
Log.w(LOGTAG, "Cannot pauseUpdatePicture, core destroyed or not initialized!");
return;
}
- core.nativeSetIsPaused(core.mNativeClass, true);
core.mDrawIsPaused = true;
}
}
@@ -2348,7 +2341,6 @@
Log.w(LOGTAG, "Cannot resumeUpdatePicture, core destroyed!");
return;
}
- core.nativeSetIsPaused(core.mNativeClass, false);
core.mDrawIsPaused = false;
// always redraw on resume to reenable gif animations
core.mDrawIsScheduled = false;
@@ -2363,13 +2355,13 @@
//////////////////////////////////////////////////////////////////////////
private void restoreState(int index) {
- WebBackForwardList list = mCallbackProxy.getBackForwardList();
+ WebBackForwardListClassic list = mCallbackProxy.getBackForwardList();
int size = list.getSize();
for (int i = 0; i < size; i++) {
list.getItemAtIndex(i).inflate(mBrowserFrame.mNativeFrame);
}
mBrowserFrame.mLoadInitFromJava = true;
- list.restoreIndex(mBrowserFrame.mNativeFrame, index);
+ WebBackForwardListClassic.restoreIndex(mBrowserFrame.mNativeFrame, index);
mBrowserFrame.mLoadInitFromJava = false;
}
@@ -2855,7 +2847,7 @@
* Scroll the focused textfield to (xPercent, y) in document space
*/
private native void nativeScrollFocusedTextInput(int nativeClass,
- float xPercent, int y, Rect contentBounds);
+ float xPercent, int y);
// these must be in document space (i.e. not scaled/zoomed).
private native void nativeSetScrollOffset(int nativeClass,
@@ -3063,6 +3055,22 @@
mDeviceMotionAndOrientationManager.setUseMock();
}
+ private void setUseMockGeolocation() {
+ mMockGeolocation.setUseMock();
+ }
+
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
+ mMockGeolocation.setPosition(latitude, longitude, accuracy);
+ }
+
+ public void setMockGeolocationError(int code, String message) {
+ mMockGeolocation.setError(code, message);
+ }
+
+ public void setMockGeolocationPermission(boolean allow) {
+ mMockGeolocation.setPermission(allow);
+ }
+
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
mDeviceMotionAndOrientationManager.setMockOrientation(canProvideAlpha, alpha,
@@ -3089,7 +3097,6 @@
sShouldMonitorWebCoreThread = true;
}
- private native void nativeSetIsPaused(int nativeClass, boolean isPaused);
private native void nativePause(int nativeClass);
private native void nativeResume(int nativeClass);
private native void nativeFreeMemory(int nativeClass);
@@ -3135,7 +3142,7 @@
private native String nativeGetText(int nativeClass,
int startX, int startY, int endX, int endY);
private native void nativeSelectText(int nativeClass,
- int startX, int startY, int endX, int endY);
+ int handleId, int x, int y);
private native void nativeClearTextSelection(int nativeClass);
private native boolean nativeSelectWordAt(int nativeClass, int x, int y);
private native void nativeSelectAll(int nativeClass);
diff --git a/core/java/android/webkit/WebViewDatabaseClassic.java b/core/java/android/webkit/WebViewDatabaseClassic.java
index 9b1d4cb..c804b90 100644
--- a/core/java/android/webkit/WebViewDatabaseClassic.java
+++ b/core/java/android/webkit/WebViewDatabaseClassic.java
@@ -100,6 +100,7 @@
private boolean mInitialized = false;
WebViewDatabaseClassic(final Context context) {
+ JniUtil.setContext(context);
new Thread() {
@Override
public void run() {
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 867ee54..ad28b17 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -37,6 +37,7 @@
import android.webkit.WebView.HitTestResult;
import android.webkit.WebView.PictureListener;
+import java.io.BufferedWriter;
import java.io.File;
import java.util.Map;
@@ -238,6 +239,10 @@
public void debugDump();
+ public void dumpViewHierarchyWithProperties(BufferedWriter out, int level);
+
+ public View findHierarchyView(String className, int hashCode);
+
//-------------------------------------------------------------------------
// Provider glue methods
//-------------------------------------------------------------------------
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 0a71c5a..421a324 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -225,26 +225,53 @@
}
@Override
+ public int getCompoundPaddingLeft() {
+ int padding = super.getCompoundPaddingLeft();
+ if (!isLayoutRtl()) {
+ final Drawable buttonDrawable = mButtonDrawable;
+ if (buttonDrawable != null) {
+ padding += buttonDrawable.getIntrinsicWidth();
+ }
+ }
+ return padding;
+ }
+
+ @Override
+ public int getCompoundPaddingRight() {
+ int padding = super.getCompoundPaddingRight();
+ if (isLayoutRtl()) {
+ final Drawable buttonDrawable = mButtonDrawable;
+ if (buttonDrawable != null) {
+ padding += buttonDrawable.getIntrinsicWidth();
+ }
+ }
+ return padding;
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final Drawable buttonDrawable = mButtonDrawable;
if (buttonDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
- final int height = buttonDrawable.getIntrinsicHeight();
+ final int drawableHeight = buttonDrawable.getIntrinsicHeight();
+ final int drawableWidth = buttonDrawable.getIntrinsicWidth();
- int y = 0;
-
+ int top = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
- y = getHeight() - height;
+ top = getHeight() - drawableHeight;
break;
case Gravity.CENTER_VERTICAL:
- y = (getHeight() - height) / 2;
+ top = (getHeight() - drawableHeight) / 2;
break;
}
+ int bottom = top + drawableHeight;
+ int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
+ int right = isLayoutRtl() ? getWidth() : drawableWidth;
- buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height);
+ buttonDrawable.setBounds(left, top, right, bottom);
buttonDrawable.draw(canvas);
}
}
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index d019d8c..1893620 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -603,6 +603,12 @@
*/
public int gravity = -1;
+ @Override
+ protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
+ width = a.getLayoutDimension(widthAttr, MATCH_PARENT);
+ height = a.getLayoutDimension(heightAttr, MATCH_PARENT);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index ada7dd1..f23e1aa 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -94,7 +94,7 @@
private View mReferenceView = null;
private View mReferenceViewInSelectedRow = null;
- private int mGravity = Gravity.LEFT;
+ private int mGravity = Gravity.START;
private final Rect mTempRect = new Rect();
@@ -300,9 +300,18 @@
final int columnWidth = mColumnWidth;
final int horizontalSpacing = mHorizontalSpacing;
+ final boolean isLayoutRtl = isLayoutRtl();
+
int last;
- int nextLeft = mListPadding.left +
- ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
+ int nextLeft;
+
+ if (isLayoutRtl) {
+ nextLeft = getWidth() - mListPadding.right - columnWidth -
+ ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
+ } else {
+ nextLeft = mListPadding.left +
+ ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
+ }
if (!mStackFromBottom) {
last = Math.min(startPos + mNumColumns, mItemCount);
@@ -311,7 +320,8 @@
startPos = Math.max(0, startPos - mNumColumns + 1);
if (last - startPos < mNumColumns) {
- nextLeft += (mNumColumns - (last - startPos)) * (columnWidth + horizontalSpacing);
+ final int deltaLeft = (mNumColumns - (last - startPos)) * (columnWidth + horizontalSpacing);
+ nextLeft += (isLayoutRtl ? -1 : +1) * deltaLeft;
}
}
@@ -330,7 +340,7 @@
final int where = flow ? -1 : pos - startPos;
child = makeAndAddView(pos, y, flow, nextLeft, selected, where);
- nextLeft += columnWidth;
+ nextLeft += (isLayoutRtl ? -1 : +1) * columnWidth;
if (pos < last - 1) {
nextLeft += horizontalSpacing;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index cf28da4..f259597 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -193,15 +193,6 @@
}
}
- /**
- * @hide
- */
- @Override
- public int getResolvedLayoutDirection(Drawable dr) {
- return (dr == mDrawable) ?
- getResolvedLayoutDirection() : super.getResolvedLayoutDirection(dr);
- }
-
@Override
public boolean hasOverlappingRendering() {
return (getBackground() != null);
@@ -675,6 +666,7 @@
d.setState(getDrawableState());
}
d.setLevel(mLevel);
+ d.setLayoutDirection(getLayoutDirection());
mDrawableWidth = d.getIntrinsicWidth();
mDrawableHeight = d.getIntrinsicHeight();
applyColorMod();
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index f3f18d5..1c6a406 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -478,6 +478,9 @@
d.setCallback(this);
}
mIndeterminateDrawable = d;
+ if (mIndeterminateDrawable != null) {
+ mIndeterminateDrawable.setLayoutDirection(getLayoutDirection());
+ }
if (mIndeterminate) {
mCurrentDrawable = d;
postInvalidate();
@@ -517,6 +520,7 @@
if (d != null) {
d.setCallback(this);
+ d.setLayoutDirection(getLayoutDirection());
// Make sure the ProgressBar is always tall enough
int drawableHeight = d.getMinimumHeight();
@@ -975,15 +979,6 @@
}
}
- /**
- * @hide
- */
- @Override
- public int getResolvedLayoutDirection(Drawable who) {
- return (who == mProgressDrawable || who == mIndeterminateDrawable) ?
- getResolvedLayoutDirection() : super.getResolvedLayoutDirection(who);
- }
-
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
updateDrawableBounds(w, h);
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index f217c9c..338b8d66 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -297,33 +297,6 @@
public LayoutParams(MarginLayoutParams source) {
super(source);
}
-
- /**
- * <p>Fixes the child's width to
- * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the child's
- * height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
- * when not specified in the XML file.</p>
- *
- * @param a the styled attributes set
- * @param widthAttr the width attribute to fetch
- * @param heightAttr the height attribute to fetch
- */
- @Override
- protected void setBaseAttributes(TypedArray a,
- int widthAttr, int heightAttr) {
-
- if (a.hasValue(widthAttr)) {
- width = a.getLayoutDimension(widthAttr, "layout_width");
- } else {
- width = WRAP_CONTENT;
- }
-
- if (a.hasValue(heightAttr)) {
- height = a.getLayoutDimension(heightAttr, "layout_height");
- } else {
- height = WRAP_CONTENT;
- }
- }
}
/**
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index ad4d7423..331d208 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1657,13 +1657,15 @@
}
/**
+ * Equivalent to calling {@link
+ * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}.
+ *
* @param viewId The id of the view whose text should change
- * @param start The id of a drawable to place before the text (relative to the
+ * @param start The id of a drawable to place before the text (relative to the
* layout direction), or 0
* @param top The id of a drawable to place above the text, or 0
* @param end The id of a drawable to place after the text, or 0
- * @param bottom The id of a drawable to place below the text, or 0
- * @hide
+ * @param bottom The id of a drawable to place below the text, or 0
*/
public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) {
addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 36d1ee0..510a794 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -349,7 +349,7 @@
public void setGravity(int gravity) {
if (mGravity != gravity) {
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
- gravity |= Gravity.LEFT;
+ gravity |= Gravity.START;
}
mGravity = gravity;
requestLayout();
@@ -453,7 +453,7 @@
/**
* Creates and positions all views for this Spinner.
*
- * @param delta Change in the selected position. +1 moves selection is moving to the right,
+ * @param delta Change in the selected position. +1 means selection is moving to the right,
* so views are scrolling to the left. -1 means selection is moving to the left.
*/
@Override
@@ -485,7 +485,9 @@
View sel = makeAndAddView(mSelectedPosition);
int width = sel.getMeasuredWidth();
int selectedOffset = childrenLeft;
- switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+ final int layoutDirection = getResolvedLayoutDirection();
+ final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
+ switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.CENTER_HORIZONTAL:
selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2);
break;
@@ -932,19 +934,18 @@
@Override
public void show() {
final Drawable background = getBackground();
- int bgOffset = 0;
+ int hOffset = 0;
if (background != null) {
background.getPadding(mTempRect);
- bgOffset = -mTempRect.left;
+ hOffset = isLayoutRtl() ? mTempRect.right : -mTempRect.left;
} else {
mTempRect.left = mTempRect.right = 0;
}
final int spinnerPaddingLeft = Spinner.this.getPaddingLeft();
+ final int spinnerPaddingRight = Spinner.this.getPaddingRight();
+ final int spinnerWidth = Spinner.this.getWidth();
if (mDropDownWidth == WRAP_CONTENT) {
- final int spinnerWidth = Spinner.this.getWidth();
- final int spinnerPaddingRight = Spinner.this.getPaddingRight();
-
int contentWidth = measureContentWidth(
(SpinnerAdapter) mAdapter, getBackground());
final int contentWidthLimit = mContext.getResources()
@@ -952,17 +953,20 @@
if (contentWidth > contentWidthLimit) {
contentWidth = contentWidthLimit;
}
-
setContentWidth(Math.max(
contentWidth, spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight));
} else if (mDropDownWidth == MATCH_PARENT) {
- final int spinnerWidth = Spinner.this.getWidth();
- final int spinnerPaddingRight = Spinner.this.getPaddingRight();
setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight);
} else {
setContentWidth(mDropDownWidth);
}
- setHorizontalOffset(bgOffset + spinnerPaddingLeft);
+
+ if (isLayoutRtl()) {
+ hOffset += spinnerWidth - spinnerPaddingRight - getWidth();
+ } else {
+ hOffset += spinnerPaddingLeft;
+ }
+ setHorizontalOffset(hOffset);
setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
super.show();
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 471f259..8f5dc2c 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -469,12 +469,6 @@
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
-
if (mOnLayout == null) {
mOnLayout = makeLayout(mTextOn);
}
@@ -490,34 +484,6 @@
mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
- switch (widthMode) {
- case MeasureSpec.AT_MOST:
- widthSize = Math.min(widthSize, switchWidth);
- break;
-
- case MeasureSpec.UNSPECIFIED:
- widthSize = switchWidth;
- break;
-
- case MeasureSpec.EXACTLY:
- // Just use what we were given
- break;
- }
-
- switch (heightMode) {
- case MeasureSpec.AT_MOST:
- heightSize = Math.min(heightSize, switchHeight);
- break;
-
- case MeasureSpec.UNSPECIFIED:
- heightSize = switchHeight;
- break;
-
- case MeasureSpec.EXACTLY:
- // Just use what we were given
- break;
- }
-
mSwitchWidth = switchWidth;
mSwitchHeight = switchHeight;
@@ -651,7 +617,7 @@
mVelocityTracker.computeCurrentVelocity(1000);
float xvel = mVelocityTracker.getXVelocity();
if (Math.abs(xvel) > mMinFlingVelocity) {
- newState = xvel > 0;
+ newState = isLayoutRtl() ? (xvel < 0) : (xvel > 0);
} else {
newState = getTargetCheckedState();
}
@@ -669,13 +635,25 @@
}
private boolean getTargetCheckedState() {
- return mThumbPosition >= getThumbScrollRange() / 2;
+ if (isLayoutRtl()) {
+ return mThumbPosition <= getThumbScrollRange() / 2;
+ } else {
+ return mThumbPosition >= getThumbScrollRange() / 2;
+ }
+ }
+
+ private void setThumbPosition(boolean checked) {
+ if (isLayoutRtl()) {
+ mThumbPosition = checked ? 0 : getThumbScrollRange();
+ } else {
+ mThumbPosition = checked ? getThumbScrollRange() : 0;
+ }
}
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
- mThumbPosition = checked ? getThumbScrollRange() : 0;
+ setThumbPosition(checked);
invalidate();
}
@@ -683,10 +661,19 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- mThumbPosition = isChecked() ? getThumbScrollRange() : 0;
+ setThumbPosition(isChecked());
- int switchRight = getWidth() - getPaddingRight();
- int switchLeft = switchRight - mSwitchWidth;
+ int switchRight;
+ int switchLeft;
+
+ if (isLayoutRtl()) {
+ switchLeft = getPaddingLeft();
+ switchRight = switchLeft + mSwitchWidth;
+ } else {
+ switchRight = getWidth() - getPaddingRight();
+ switchLeft = switchRight - mSwitchWidth;
+ }
+
int switchTop = 0;
int switchBottom = 0;
switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) {
@@ -761,7 +748,22 @@
}
@Override
+ public int getCompoundPaddingLeft() {
+ if (!isLayoutRtl()) {
+ return super.getCompoundPaddingLeft();
+ }
+ int padding = super.getCompoundPaddingLeft() + mSwitchWidth;
+ if (!TextUtils.isEmpty(getText())) {
+ padding += mSwitchPadding;
+ }
+ return padding;
+ }
+
+ @Override
public int getCompoundPaddingRight() {
+ if (isLayoutRtl()) {
+ return super.getCompoundPaddingRight();
+ }
int padding = super.getCompoundPaddingRight() + mSwitchWidth;
if (!TextUtils.isEmpty(getText())) {
padding += mSwitchPadding;
diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java
index 6331b6d..513f180 100644
--- a/core/java/android/widget/TableLayout.java
+++ b/core/java/android/widget/TableLayout.java
@@ -741,11 +741,7 @@
@Override
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
this.width = MATCH_PARENT;
- if (a.hasValue(heightAttr)) {
- this.height = a.getLayoutDimension(heightAttr, "layout_height");
- } else {
- this.height = WRAP_CONTENT;
- }
+ this.height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
}
}
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index 01c4c2c..fb548df 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -502,19 +502,8 @@
@Override
protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
- // We don't want to force users to specify a layout_width
- if (a.hasValue(widthAttr)) {
- width = a.getLayoutDimension(widthAttr, "layout_width");
- } else {
- width = MATCH_PARENT;
- }
-
- // We don't want to force users to specify a layout_height
- if (a.hasValue(heightAttr)) {
- height = a.getLayoutDimension(heightAttr, "layout_height");
- } else {
- height = WRAP_CONTENT;
- }
+ width = a.getLayoutDimension(widthAttr, MATCH_PARENT);
+ height = a.getLayoutDimension(heightAttr, WRAP_CONTENT);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 01617da..25f0131 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1542,7 +1542,6 @@
/**
* Returns the start padding of the view, plus space for the start
* Drawable if any.
- * @hide
*/
public int getCompoundPaddingStart() {
resolveDrawables();
@@ -1558,7 +1557,6 @@
/**
* Returns the end padding of the view, plus space for the end
* Drawable if any.
- * @hide
*/
public int getCompoundPaddingEnd() {
resolveDrawables();
@@ -1656,7 +1654,6 @@
/**
* Returns the total start padding of the view, including the start
* Drawable if any.
- * @hide
*/
public int getTotalPaddingStart() {
return getCompoundPaddingStart();
@@ -1665,7 +1662,6 @@
/**
* Returns the total end padding of the view, including the end
* Drawable if any.
- * @hide
*/
public int getTotalPaddingEnd() {
return getCompoundPaddingEnd();
@@ -1868,7 +1864,6 @@
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
- * @hide
*/
public void setCompoundDrawablesRelative(Drawable start, Drawable top,
Drawable end, Drawable bottom) {
@@ -1990,7 +1985,6 @@
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
- * @hide
*/
@android.view.RemotableViewMethod
public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end,
@@ -2014,7 +2008,6 @@
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
- * @hide
*/
public void setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable start, Drawable top,
Drawable end, Drawable bottom) {
@@ -2061,7 +2054,6 @@
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
- * @hide
*/
public Drawable[] getCompoundDrawablesRelative() {
final Drawables dr = mDrawables;
@@ -4586,23 +4578,6 @@
}
}
- /**
- * @hide
- */
- @Override
- public int getResolvedLayoutDirection(Drawable who) {
- if (who == null) return View.LAYOUT_DIRECTION_LTR;
- if (mDrawables != null) {
- final Drawables drawables = mDrawables;
- if (who == drawables.mDrawableLeft || who == drawables.mDrawableRight ||
- who == drawables.mDrawableTop || who == drawables.mDrawableBottom ||
- who == drawables.mDrawableStart || who == drawables.mDrawableEnd) {
- return getResolvedLayoutDirection();
- }
- }
- return super.getResolvedLayoutDirection(who);
- }
-
@Override
public boolean hasOverlappingRendering() {
return (getBackground() != null || mText instanceof Spannable || hasSelection());
@@ -5634,7 +5609,6 @@
physicalWidth, false);
}
- /** @hide */
@Override
public void onResolvedLayoutDirectionReset() {
if (mLayoutAlignment != null) {
@@ -8180,7 +8154,6 @@
return mEditor.mInBatchEditControllers;
}
- /** @hide */
@Override
public void onResolvedTextDirectionChanged() {
if (hasPasswordTransformationMethod()) {
@@ -8216,13 +8189,8 @@
}
}
- /**
- * Subclasses will need to override this method to implement their own way of resolving
- * drawables depending on the layout direction.
- *
- * A call to the super method will be required from the subclasses implementation.
- */
- protected void resolveDrawables() {
+ @Override
+ public void onResolveDrawables(int layoutDirection) {
// No need to resolve twice
if (mResolvedDrawables) {
return;
@@ -8238,7 +8206,7 @@
}
Drawables dr = mDrawables;
- switch(getResolvedLayoutDirection()) {
+ switch(layoutDirection) {
case LAYOUT_DIRECTION_RTL:
if (dr.mDrawableStart != null) {
dr.mDrawableRight = dr.mDrawableStart;
@@ -8270,9 +8238,25 @@
}
break;
}
+ updateDrawablesLayoutDirection(dr, layoutDirection);
mResolvedDrawables = true;
}
+ private void updateDrawablesLayoutDirection(Drawables dr, int layoutDirection) {
+ if (dr.mDrawableLeft != null) {
+ dr.mDrawableLeft.setLayoutDirection(layoutDirection);
+ }
+ if (dr.mDrawableRight != null) {
+ dr.mDrawableRight.setLayoutDirection(layoutDirection);
+ }
+ if (dr.mDrawableTop != null) {
+ dr.mDrawableTop.setLayoutDirection(layoutDirection);
+ }
+ if (dr.mDrawableBottom != null) {
+ dr.mDrawableBottom.setLayoutDirection(layoutDirection);
+ }
+ }
+
protected void resetResolvedDrawables() {
mResolvedDrawables = false;
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index fafc113..6fc0773 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -24,6 +24,7 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.LocaleUtil;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -33,6 +34,8 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import java.util.Locale;
+
/**
* A toast is a view containing a quick little message for the user. The toast class
* helps you create and show those.
@@ -371,7 +374,11 @@
handleHide();
mView = mNextView;
mWM = WindowManagerImpl.getDefault();
- final int gravity = mGravity;
+ // We can resolve the Gravity here by using the Locale for getting
+ // the layout direction
+ final int layoutDirection = LocaleUtil.getLayoutDirectionFromLocale(
+ Locale.getDefault());
+ final int gravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
mParams.gravity = gravity;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight = 1.0f;
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 6a0cd36..1a76461 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -58,14 +58,14 @@
void noteBluetoothOff();
void noteFullWifiLockAcquired(int uid);
void noteFullWifiLockReleased(int uid);
- void noteScanWifiLockAcquired(int uid);
- void noteScanWifiLockReleased(int uid);
+ void noteWifiScanStarted(int uid);
+ void noteWifiScanStopped(int uid);
void noteWifiMulticastEnabled(int uid);
void noteWifiMulticastDisabled(int uid);
void noteFullWifiLockAcquiredFromSource(in WorkSource ws);
void noteFullWifiLockReleasedFromSource(in WorkSource ws);
- void noteScanWifiLockAcquiredFromSource(in WorkSource ws);
- void noteScanWifiLockReleasedFromSource(in WorkSource ws);
+ void noteWifiScanStartedFromSource(in WorkSource ws);
+ void noteWifiScanStoppedFromSource(in WorkSource ws);
void noteWifiMulticastEnabledFromSource(in WorkSource ws);
void noteWifiMulticastDisabledFromSource(in WorkSource ws);
void noteNetworkInterfaceType(String iface, int type);
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
index 216d985..78b4466 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
@@ -24,6 +24,7 @@
oneway interface IAppWidgetHost {
void updateAppWidget(int appWidgetId, in RemoteViews views);
void providerChanged(int appWidgetId, in AppWidgetProviderInfo info);
+ void providersChanged();
void viewDataChanged(int appWidgetId, int viewId);
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5157385..650d06b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -159,8 +159,8 @@
= new SparseArray<ArrayList<StopwatchTimer>>();
final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
- final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
+ final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
// Last partial timers we use for distributing CPU usage.
final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
@@ -2174,28 +2174,28 @@
getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
}
- int mWifiScanLockNesting = 0;
+ int mWifiScanNesting = 0;
- public void noteScanWifiLockAcquiredLocked(int uid) {
- if (mWifiScanLockNesting == 0) {
- mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
- if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: "
+ public void noteWifiScanStartedLocked(int uid) {
+ if (mWifiScanNesting == 0) {
+ mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(SystemClock.elapsedRealtime());
}
- mWifiScanLockNesting++;
- getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
+ mWifiScanNesting++;
+ getUidStatsLocked(uid).noteWifiScanStartedLocked();
}
- public void noteScanWifiLockReleasedLocked(int uid) {
- mWifiScanLockNesting--;
- if (mWifiScanLockNesting == 0) {
- mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG;
- if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: "
+ public void noteWifiScanStoppedLocked(int uid) {
+ mWifiScanNesting--;
+ if (mWifiScanNesting == 0) {
+ mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(SystemClock.elapsedRealtime());
}
- getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
+ getUidStatsLocked(uid).noteWifiScanStoppedLocked();
}
int mWifiMulticastNesting = 0;
@@ -2236,17 +2236,17 @@
}
}
- public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) {
+ public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
- noteScanWifiLockAcquiredLocked(ws.get(i));
+ noteWifiScanStartedLocked(ws.get(i));
}
}
- public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) {
+ public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
- noteScanWifiLockReleasedLocked(ws.get(i));
+ noteWifiScanStoppedLocked(ws.get(i));
}
}
@@ -2360,8 +2360,8 @@
boolean mFullWifiLockOut;
StopwatchTimer mFullWifiLockTimer;
- boolean mScanWifiLockOut;
- StopwatchTimer mScanWifiLockTimer;
+ boolean mWifiScanStarted;
+ StopwatchTimer mWifiScanTimer;
boolean mWifiMulticastEnabled;
StopwatchTimer mWifiMulticastTimer;
@@ -2405,8 +2405,8 @@
mWifiRunningTimers, mUnpluggables);
mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
mFullWifiLockTimers, mUnpluggables);
- mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
- mScanWifiLockTimers, mUnpluggables);
+ mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
+ mWifiScanTimers, mUnpluggables);
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mUnpluggables);
mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
@@ -2518,22 +2518,22 @@
}
@Override
- public void noteScanWifiLockAcquiredLocked() {
- if (!mScanWifiLockOut) {
- mScanWifiLockOut = true;
- if (mScanWifiLockTimer == null) {
- mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
- mScanWifiLockTimers, mUnpluggables);
+ public void noteWifiScanStartedLocked() {
+ if (!mWifiScanStarted) {
+ mWifiScanStarted = true;
+ if (mWifiScanTimer == null) {
+ mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
+ mWifiScanTimers, mUnpluggables);
}
- mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
+ mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
}
}
@Override
- public void noteScanWifiLockReleasedLocked() {
- if (mScanWifiLockOut) {
- mScanWifiLockOut = false;
- mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
+ public void noteWifiScanStoppedLocked() {
+ if (mWifiScanStarted) {
+ mWifiScanStarted = false;
+ mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
}
}
@@ -2614,11 +2614,11 @@
}
@Override
- public long getScanWifiLockTime(long batteryRealtime, int which) {
- if (mScanWifiLockTimer == null) {
+ public long getWifiScanTime(long batteryRealtime, int which) {
+ if (mWifiScanTimer == null) {
return 0;
}
- return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
+ return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
}
@Override
@@ -2698,9 +2698,9 @@
active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
active |= mFullWifiLockOut;
}
- if (mScanWifiLockTimer != null) {
- active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false);
- active |= mScanWifiLockOut;
+ if (mWifiScanTimer != null) {
+ active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
+ active |= mWifiScanStarted;
}
if (mWifiMulticastTimer != null) {
active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
@@ -2791,8 +2791,8 @@
if (mFullWifiLockTimer != null) {
mFullWifiLockTimer.detach();
}
- if (mScanWifiLockTimer != null) {
- mScanWifiLockTimer.detach();
+ if (mWifiScanTimer != null) {
+ mWifiScanTimer.detach();
}
if (mWifiMulticastTimer != null) {
mWifiMulticastTimer.detach();
@@ -2860,9 +2860,9 @@
} else {
out.writeInt(0);
}
- if (mScanWifiLockTimer != null) {
+ if (mWifiScanTimer != null) {
out.writeInt(1);
- mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
+ mWifiScanTimer.writeToParcel(out, batteryRealtime);
} else {
out.writeInt(0);
}
@@ -2954,12 +2954,12 @@
} else {
mFullWifiLockTimer = null;
}
- mScanWifiLockOut = false;
+ mWifiScanStarted = false;
if (in.readInt() != 0) {
- mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK,
- mScanWifiLockTimers, mUnpluggables, in);
+ mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
+ mWifiScanTimers, mUnpluggables, in);
} else {
- mScanWifiLockTimer = null;
+ mWifiScanTimer = null;
}
mWifiMulticastEnabled = false;
if (in.readInt() != 0) {
@@ -5118,9 +5118,9 @@
if (in.readInt() != 0) {
u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
}
- u.mScanWifiLockOut = false;
+ u.mWifiScanStarted = false;
if (in.readInt() != 0) {
- u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
+ u.mWifiScanTimer.readSummaryFromParcelLocked(in);
}
u.mWifiMulticastEnabled = false;
if (in.readInt() != 0) {
@@ -5310,9 +5310,9 @@
} else {
out.writeInt(0);
}
- if (u.mScanWifiLockTimer != null) {
+ if (u.mWifiScanTimer != null) {
out.writeInt(1);
- u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL);
} else {
out.writeInt(0);
}
@@ -5537,7 +5537,7 @@
mWindowTimers.clear();
mWifiRunningTimers.clear();
mFullWifiLockTimers.clear();
- mScanWifiLockTimers.clear();
+ mWifiScanTimers.clear();
mWifiMulticastTimers.clear();
sNumSpeedSteps = in.readInt();
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index d1c2d2e..5093b4d 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -444,6 +444,16 @@
if ((mConnection != null) && (mSrcContext != null)) {
mSrcContext.unbindService(mConnection);
}
+ try {
+ // Send the DISCONNECTED, although it may not be received
+ // but its the best we can do.
+ Message msg = Message.obtain();
+ msg.what = CMD_CHANNEL_DISCONNECTED;
+ msg.replyTo = mSrcMessenger;
+ mDstMessenger.send(msg);
+ } catch(Exception e) {
+ }
+ // Tell source we're disconnected.
if (mSrcHandler != null) {
replyDisconnected(STATUS_SUCCESSFUL);
}
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 1391ac3..0ea7b83 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -80,9 +80,9 @@
* and invoke <code>halting</code>. Any message subsequently received by the state
* machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
*
- * <p>If it is desirable to completely stop the state machine call <code>quit</code>. This
- * will exit the current state and its parent and then exit from the controlling thread
- * and no further messages will be processed.</p>
+ * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
+ * <code>abort</code>. These will call <code>exit</code> of the current state and its parents, call
+ * <code>onQuiting</code> and then exit Thread/Loopers.</p>
*
* <p>In addition to <code>processMessage</code> each <code>State</code> has
* an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
@@ -362,7 +362,7 @@
}
@Override
- void halting() {
+ void onHalting() {
Log.d(TAG, "halting");
synchronized (this) {
this.notifyAll();
@@ -423,10 +423,10 @@
private String mName;
/** Message.what value when quitting */
- public static final int SM_QUIT_CMD = -1;
+ private static final int SM_QUIT_CMD = -1;
/** Message.what value when initializing */
- public static final int SM_INIT_CMD = -2;
+ private static final int SM_INIT_CMD = -2;
/**
* Convenience constant that maybe returned by processMessage
@@ -443,11 +443,10 @@
public static final boolean NOT_HANDLED = false;
/**
+ * StateMachine logging record.
* {@hide}
- *
- * The information maintained for a processed message.
*/
- public static class ProcessedMessageInfo {
+ public static class LogRec {
private long mTime;
private int mWhat;
private String mInfo;
@@ -456,12 +455,13 @@
/**
* Constructor
- * @param message
+ *
+ * @param msg
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
- ProcessedMessageInfo(Message msg, String info, State state, State orgState) {
+ LogRec(Message msg, String info, State state, State orgState) {
update(msg, info, state, orgState);
}
@@ -473,7 +473,7 @@
*/
public void update(Message msg, String info, State state, State orgState) {
mTime = System.currentTimeMillis();
- mWhat = msg.what;
+ mWhat = (msg != null) ? msg.what : 0;
mInfo = info;
mState = state;
mOrgState = orgState;
@@ -517,8 +517,7 @@
/**
* @return as string
*/
- @Override
- public String toString() {
+ public String toString(StateMachine sm) {
StringBuilder sb = new StringBuilder();
sb.append("time=");
Calendar c = Calendar.getInstance();
@@ -529,10 +528,15 @@
sb.append(" orgState=");
sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
sb.append(" what=");
- sb.append(mWhat);
- sb.append("(0x");
- sb.append(Integer.toHexString(mWhat));
- sb.append(")");
+ String what = sm.getWhatToString(mWhat);
+ if (TextUtils.isEmpty(what)) {
+ sb.append(mWhat);
+ sb.append("(0x");
+ sb.append(Integer.toHexString(mWhat));
+ sb.append(")");
+ } else {
+ sb.append(what);
+ }
if ( ! TextUtils.isEmpty(mInfo)) {
sb.append(" ");
sb.append(mInfo);
@@ -542,21 +546,21 @@
}
/**
- * A list of messages recently processed by the state machine.
+ * A list of log records including messages recently processed by the state machine.
*
- * The class maintains a list of messages that have been most
+ * The class maintains a list of log records including messages
* recently processed. The list is finite and may be set in the
* constructor or by calling setSize. The public interface also
- * includes size which returns the number of recent messages,
- * count which is the number of message processed since the
- * the last setSize, get which returns a processed message and
- * add which adds a processed messaged.
+ * includes size which returns the number of recent records,
+ * count which is the number of records processed since the
+ * the last setSize, get which returns a record and
+ * add which adds a record.
*/
- private static class ProcessedMessages {
+ private static class LogRecords {
private static final int DEFAULT_SIZE = 20;
- private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();
+ private Vector<LogRec> mLogRecords = new Vector<LogRec>();
private int mMaxSize = DEFAULT_SIZE;
private int mOldestIndex = 0;
private int mCount = 0;
@@ -564,39 +568,39 @@
/**
* private constructor use add
*/
- private ProcessedMessages() {
+ private LogRecords() {
}
/**
- * Set size of messages to maintain and clears all current messages.
+ * Set size of messages to maintain and clears all current records.
*
- * @param maxSize number of messages to maintain at anyone time.
+ * @param maxSize number of records to maintain at anyone time.
*/
- void setSize(int maxSize) {
+ synchronized void setSize(int maxSize) {
mMaxSize = maxSize;
mCount = 0;
- mMessages.clear();
+ mLogRecords.clear();
}
/**
- * @return the number of recent messages.
+ * @return the number of recent records.
*/
- int size() {
- return mMessages.size();
+ synchronized int size() {
+ return mLogRecords.size();
}
/**
- * @return the total number of messages processed since size was set.
+ * @return the total number of records processed since size was set.
*/
- int count() {
+ synchronized int count() {
return mCount;
}
/**
- * Clear the list of Processed Message Info.
+ * Clear the list of records.
*/
- void cleanup() {
- mMessages.clear();
+ synchronized void cleanup() {
+ mLogRecords.clear();
}
/**
@@ -604,7 +608,7 @@
* record and size()-1 is the newest record. If the index is to
* large null is returned.
*/
- ProcessedMessageInfo get(int index) {
+ synchronized LogRec get(int index) {
int nextIndex = mOldestIndex + index;
if (nextIndex >= mMaxSize) {
nextIndex -= mMaxSize;
@@ -612,7 +616,7 @@
if (nextIndex >= size()) {
return null;
} else {
- return mMessages.get(nextIndex);
+ return mLogRecords.get(nextIndex);
}
}
@@ -625,12 +629,12 @@
* @param orgState is the first state the received the message but
* did not processes the message.
*/
- void add(Message msg, String messageInfo, State state, State orgState) {
+ synchronized void add(Message msg, String messageInfo, State state, State orgState) {
mCount += 1;
- if (mMessages.size() < mMaxSize) {
- mMessages.add(new ProcessedMessageInfo(msg, messageInfo, state, orgState));
+ if (mLogRecords.size() < mMaxSize) {
+ mLogRecords.add(new LogRec(msg, messageInfo, state, orgState));
} else {
- ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
+ LogRec pmi = mLogRecords.get(mOldestIndex);
mOldestIndex += 1;
if (mOldestIndex >= mMaxSize) {
mOldestIndex = 0;
@@ -652,8 +656,8 @@
/** The current message */
private Message mMsg;
- /** A list of messages that this state machine has processed */
- private ProcessedMessages mProcessedMessages = new ProcessedMessages();
+ /** A list of log records including messages this state machine has processed */
+ private LogRecords mLogRecords = new LogRecords();
/** true if construction of the state machine has not been completed */
private boolean mIsConstructionCompleted;
@@ -814,15 +818,18 @@
*/
if (destState != null) {
if (destState == mQuittingState) {
+ /**
+ * Call onQuitting to let subclasses cleanup.
+ */
+ mSm.onQuitting();
cleanupAfterQuitting();
-
} else if (destState == mHaltingState) {
/**
- * Call halting() if we've transitioned to the halting
+ * Call onHalting() if we've transitioned to the halting
* state. All subsequent messages will be processed in
* in the halting state which invokes haltedProcessMessage(msg);
*/
- mSm.halting();
+ mSm.onHalting();
}
}
}
@@ -831,7 +838,6 @@
* Cleanup all the static variables and the looper after the SM has been quit.
*/
private final void cleanupAfterQuitting() {
- mSm.quitting();
if (mSm.mSmThread != null) {
// If we made the thread then quit looper which stops the thread.
getLooper().quit();
@@ -841,7 +847,7 @@
mSm.mSmHandler = null;
mSm = null;
mMsg = null;
- mProcessedMessages.cleanup();
+ mLogRecords.cleanup();
mStateStack = null;
mTempStateStack = null;
mStateInfo.clear();
@@ -892,36 +898,38 @@
if (mDbg) {
Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
}
- while (!curStateInfo.state.processMessage(msg)) {
- /**
- * Not processed
- */
- curStateInfo = curStateInfo.parentStateInfo;
- if (curStateInfo == null) {
- /**
- * No parents left so it's not handled
- */
- mSm.unhandledMessage(msg);
- if (isQuit(msg)) {
- transitionTo(mQuittingState);
- }
- break;
- }
- if (mDbg) {
- Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
- }
- }
- /**
- * Record that we processed the message
- */
- if (mSm.recordProcessedMessage(msg)) {
- if (curStateInfo != null) {
- State orgState = mStateStack[mStateStackTopIndex].state;
- mProcessedMessages.add(msg, mSm.getMessageInfo(msg), curStateInfo.state,
- orgState);
- } else {
- mProcessedMessages.add(msg, mSm.getMessageInfo(msg), null, null);
+ if (isQuit(msg)) {
+ transitionTo(mQuittingState);
+ } else {
+ while (!curStateInfo.state.processMessage(msg)) {
+ /**
+ * Not processed
+ */
+ curStateInfo = curStateInfo.parentStateInfo;
+ if (curStateInfo == null) {
+ /**
+ * No parents left so it's not handled
+ */
+ mSm.unhandledMessage(msg);
+ break;
+ }
+ if (mDbg) {
+ Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
+ }
+ }
+
+ /**
+ * Record that we processed the message
+ */
+ if (mSm.recordLogRec(msg)) {
+ if (curStateInfo != null) {
+ State orgState = mStateStack[mStateStackTopIndex].state;
+ mLogRecords.add(msg, mSm.getLogRecString(msg), curStateInfo.state,
+ orgState);
+ } else {
+ mLogRecords.add(msg, mSm.getLogRecString(msg), null, null);
+ }
}
}
}
@@ -1141,13 +1149,19 @@
mDeferredMessages.add(newMsg);
}
- /** @see StateMachine#deferMessage(Message) */
+ /** @see StateMachine#quit() */
private final void quit() {
if (mDbg) Log.d(TAG, "quit:");
sendMessage(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
}
- /** @see StateMachine#isQuit(Message) */
+ /** @see StateMachine#quitNow() */
+ private final void quitNow() {
+ if (mDbg) Log.d(TAG, "abort:");
+ sendMessageAtFrontOfQueue(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
+ }
+
+ /** Validate that the message was sent by quit or abort. */
private final boolean isQuit(Message msg) {
return (msg.what == SM_QUIT_CMD) && (msg.obj == mSmHandlerObj);
}
@@ -1162,26 +1176,6 @@
mDbg = dbg;
}
- /** @see StateMachine#setProcessedMessagesSize(int) */
- private final void setProcessedMessagesSize(int maxSize) {
- mProcessedMessages.setSize(maxSize);
- }
-
- /** @see StateMachine#getProcessedMessagesSize() */
- private final int getProcessedMessagesSize() {
- return mProcessedMessages.size();
- }
-
- /** @see StateMachine#getProcessedMessagesCount() */
- private final int getProcessedMessagesCount() {
- return mProcessedMessages.count();
- }
-
- /** @see StateMachine#getProcessedMessageInfo(int) */
- private final ProcessedMessageInfo getProcessedMessageInfo(int index) {
- return mProcessedMessages.get(index);
- }
-
}
private SmHandler mSmHandler;
@@ -1282,8 +1276,8 @@
/**
* transition to halt state. Upon returning
* from processMessage we will exit all current
- * states, execute the halting() method and then
- * all subsequent messages haltedProcessMesage
+ * states, execute the onHalting() method and then
+ * for all subsequent messages haltedProcessMessage
* will be called.
*/
protected final void transitionToHaltingState() {
@@ -1303,7 +1297,6 @@
mSmHandler.deferMessage(msg);
}
-
/**
* Called when message wasn't handled
*
@@ -1325,7 +1318,7 @@
* transitionToHalting. All subsequent messages will invoke
* {@link StateMachine#haltedProcessMessage(Message)}
*/
- protected void halting() {
+ protected void onHalting() {
}
/**
@@ -1334,7 +1327,7 @@
* ignored. In addition, if this StateMachine created the thread, the thread will
* be stopped after this method returns.
*/
- protected void quitting() {
+ protected void onQuitting() {
}
/**
@@ -1345,33 +1338,77 @@
}
/**
- * Set size of messages to maintain and clears all current messages.
+ * Set number of log records to maintain and clears all current records.
*
* @param maxSize number of messages to maintain at anyone time.
*/
- public final void setProcessedMessagesSize(int maxSize) {
- mSmHandler.setProcessedMessagesSize(maxSize);
+ public final void setLogRecSize(int maxSize) {
+ mSmHandler.mLogRecords.setSize(maxSize);
}
/**
- * @return number of messages processed
+ * @return number of log records
*/
- public final int getProcessedMessagesSize() {
- return mSmHandler.getProcessedMessagesSize();
+ public final int getLogRecSize() {
+ return mSmHandler.mLogRecords.size();
}
/**
- * @return the total number of messages processed
+ * @return the total number of records processed
*/
- public final int getProcessedMessagesCount() {
- return mSmHandler.getProcessedMessagesCount();
+ public final int getLogRecCount() {
+ return mSmHandler.mLogRecords.count();
}
/**
- * @return a processed message information
+ * @return a log record
*/
- public final ProcessedMessageInfo getProcessedMessageInfo(int index) {
- return mSmHandler.getProcessedMessageInfo(index);
+ public final LogRec getLogRec(int index) {
+ return mSmHandler.mLogRecords.get(index);
+ }
+
+ /**
+ * Add the string to LogRecords.
+ *
+ * @param string
+ */
+ protected void addLogRec(String string) {
+ mSmHandler.mLogRecords.add(null, string, null, null);
+ }
+
+ /**
+ * Add the string and state to LogRecords
+ *
+ * @param string
+ * @param state current state
+ */
+ protected void addLogRec(String string, State state) {
+ mSmHandler.mLogRecords.add(null, string, state, null);
+ }
+
+ /**
+ * @return true if msg should be saved in the log, default is true.
+ */
+ protected boolean recordLogRec(Message msg) {
+ return true;
+ }
+
+ /**
+ * Return a string to be logged by LogRec, default
+ * is an empty string. Override if additional information is desired.
+ *
+ * @param msg that was processed
+ * @return information to be logged as a String
+ */
+ protected String getLogRecString(Message msg) {
+ return "";
+ }
+
+ /**
+ * @return the string for msg.what
+ */
+ protected String getWhatToString(int what) {
+ return null;
}
/**
@@ -1548,43 +1585,23 @@
}
/**
- * Conditionally quit the looper and stop execution.
- *
- * This sends the SM_QUIT_MSG to the state machine and
- * if not handled by any state's processMessage then the
- * state machine will be stopped and no further messages
- * will be processed.
+ * Quit the state machine after all currently queued up messages are processed.
*/
- public final void quit() {
- // mSmHandler can be null if the state machine has quit.
+ protected final void quit() {
+ // mSmHandler can be null if the state machine is already stopped.
if (mSmHandler == null) return;
mSmHandler.quit();
}
/**
- * @return ture if msg is quit
+ * Quit the state machine immediately all currently queued messages will be discarded.
*/
- protected final boolean isQuit(Message msg) {
- return mSmHandler.isQuit(msg);
- }
+ protected final void quitNow() {
+ // mSmHandler can be null if the state machine is already stopped.
+ if (mSmHandler == null) return;
- /**
- * @return true if msg should be saved in ProcessedMessage, default is true.
- */
- protected boolean recordProcessedMessage(Message msg) {
- return true;
- }
-
- /**
- * Return message info to be logged by ProcessedMessageInfo, default
- * is an empty string. Override if additional information is desired.
- *
- * @param msg that was processed
- * @return information to be logged as a String
- */
- protected String getMessageInfo(Message msg) {
- return "";
+ mSmHandler.quitNow();
}
/**
@@ -1629,9 +1646,9 @@
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(getName() + ":");
- pw.println(" total messages=" + getProcessedMessagesCount());
- for (int i=0; i < getProcessedMessagesSize(); i++) {
- pw.printf(" msg[%d]: %s\n", i, getProcessedMessageInfo(i));
+ pw.println(" total records=" + getLogRecCount());
+ for (int i=0; i < getLogRecSize(); i++) {
+ pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString(this));
pw.flush();
}
pw.println("curState=" + getCurrentState().getName());
diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/core/java/com/android/internal/widget/LockSettingsService.java
index 24c7161..2fb81ac 100644
--- a/core/java/com/android/internal/widget/LockSettingsService.java
+++ b/core/java/com/android/internal/widget/LockSettingsService.java
@@ -24,6 +24,7 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Binder;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.os.UserId;
import android.provider.Settings;
import android.provider.Settings.Secure;
@@ -303,12 +304,15 @@
}
private void writeToDb(String key, String value, int userId) {
+ writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId);
+ }
+
+ private void writeToDb(SQLiteDatabase db, String key, String value, int userId) {
ContentValues cv = new ContentValues();
cv.put(COLUMN_KEY, key);
cv.put(COLUMN_USERID, userId);
cv.put(COLUMN_VALUE, value);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
@@ -359,6 +363,16 @@
@Override
public void onCreate(SQLiteDatabase db) {
createTable(db);
+ initializeDefaults(db);
+ }
+
+ private void initializeDefaults(SQLiteDatabase db) {
+ // Get the lockscreen default from a system property, if available
+ boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default",
+ false);
+ if (lockScreenDisable) {
+ writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+ }
}
@Override
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index b5a2f98..1f2b4ba 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -170,6 +170,7 @@
external/skia/include/core \
external/skia/include/effects \
external/skia/include/images \
+ external/skia/include/ports \
external/skia/src/ports \
external/skia/include/utils \
external/sqlite/dist \
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 35f82a8..023e6d1 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -30,14 +30,6 @@
namespace android {
//--------------------------------------------------------------------------------------------------
-#define TYPEFACE_ARABIC "/system/fonts/DroidNaskh-Regular-SystemUI.ttf"
-#define TYPE_FACE_HEBREW_REGULAR "/system/fonts/DroidSansHebrew-Regular.ttf"
-#define TYPE_FACE_HEBREW_BOLD "/system/fonts/DroidSansHebrew-Bold.ttf"
-#define TYPEFACE_BENGALI "/system/fonts/Lohit-Bengali.ttf"
-#define TYPEFACE_DEVANAGARI_REGULAR "/system/fonts/DroidSansDevanagari-Regular.ttf"
-#define TYPEFACE_TAMIL_REGULAR "/system/fonts/DroidSansTamil-Regular.ttf"
-#define TYPEFACE_TAMIL_BOLD "/system/fonts/DroidSansTamil-Bold.ttf"
-#define TYPEFACE_THAI "/system/fonts/DroidSansThai.ttf"
ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
@@ -763,7 +755,7 @@
// Set the correct Typeface depending on the script
switch (script) {
case HB_Script_Arabic:
- typeface = getCachedTypeface(&mArabicTypeface, TYPEFACE_ARABIC);
+ typeface = getCachedTypeface(&mArabicTypeface, kArabic_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Arabic Typeface");
#endif
@@ -774,7 +766,7 @@
switch (typeface->style()) {
case SkTypeface::kBold:
case SkTypeface::kBoldItalic:
- typeface = getCachedTypeface(&mHebrewBoldTypeface, TYPE_FACE_HEBREW_BOLD);
+ typeface = getCachedTypeface(&mHebrewBoldTypeface, kHebrewBold_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Hebrew Bold/BoldItalic Typeface");
#endif
@@ -783,14 +775,14 @@
case SkTypeface::kNormal:
case SkTypeface::kItalic:
default:
- typeface = getCachedTypeface(&mHebrewRegularTypeface, TYPE_FACE_HEBREW_REGULAR);
+ typeface = getCachedTypeface(&mHebrewRegularTypeface, kHebrewRegular_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Hebrew Regular/Italic Typeface");
#endif
break;
}
} else {
- typeface = getCachedTypeface(&mHebrewRegularTypeface, TYPE_FACE_HEBREW_REGULAR);
+ typeface = getCachedTypeface(&mHebrewRegularTypeface, kHebrewRegular_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Hebrew Regular Typeface");
#endif
@@ -798,21 +790,21 @@
break;
case HB_Script_Bengali:
- typeface = getCachedTypeface(&mBengaliTypeface, TYPEFACE_BENGALI);
+ typeface = getCachedTypeface(&mBengaliTypeface, kBengali_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Bengali Typeface");
#endif
break;
case HB_Script_Thai:
- typeface = getCachedTypeface(&mThaiTypeface, TYPEFACE_THAI);
+ typeface = getCachedTypeface(&mThaiTypeface, kThai_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Thai Typeface");
#endif
break;
case HB_Script_Devanagari:
- typeface = getCachedTypeface(&mDevanagariRegularTypeface, TYPEFACE_DEVANAGARI_REGULAR);
+ typeface = getCachedTypeface(&mDevanagariRegularTypeface, kDevanagari_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Devanagari Regular Typeface");
#endif
@@ -823,7 +815,7 @@
switch (typeface->style()) {
case SkTypeface::kBold:
case SkTypeface::kBoldItalic:
- typeface = getCachedTypeface(&mTamilBoldTypeface, TYPEFACE_TAMIL_BOLD);
+ typeface = getCachedTypeface(&mTamilBoldTypeface, kTamilBold_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Tamil Bold Typeface");
#endif
@@ -832,14 +824,14 @@
case SkTypeface::kNormal:
case SkTypeface::kItalic:
default:
- typeface = getCachedTypeface(&mTamilRegularTypeface, TYPEFACE_TAMIL_REGULAR);
+ typeface = getCachedTypeface(&mTamilRegularTypeface, kTamilRegular_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Tamil Regular Typeface");
#endif
break;
}
} else {
- typeface = getCachedTypeface(&mTamilRegularTypeface, TYPEFACE_TAMIL_REGULAR);
+ typeface = getCachedTypeface(&mTamilRegularTypeface, kTamilRegular_FallbackScript);
#if DEBUG_GLYPHS
ALOGD("Using Tamil Regular Typeface");
#endif
@@ -957,9 +949,9 @@
delete[] mShaperItem.log_clusters;
}
-SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, const char path[]) {
+SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, FallbackScripts fallbackEnum) {
if (!*typeface) {
- *typeface = SkTypeface::CreateFromFile(path);
+ *typeface = SkCreateTypefaceForScript(fallbackEnum);
// CreateFromFile(path) can return NULL if the path is non existing
if (!*typeface) {
#if DEBUG_GLYPHS
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index cb15a2a..4f7ecdf 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -32,6 +32,7 @@
#include <SkTemplates.h>
#include <SkUtils.h>
#include <SkAutoKern.h>
+#include "SkTypeface_android.h"
#include <unicode/ubidi.h>
#include <unicode/ushape.h>
@@ -238,7 +239,7 @@
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
Vector<jchar>* const outGlyphs);
- SkTypeface* getCachedTypeface(SkTypeface** typeface, const char path[]);
+ SkTypeface* getCachedTypeface(SkTypeface** typeface, FallbackScripts fallbackEnum);
HB_Face getCachedHBFace(SkTypeface* typeface);
void ensureShaperItemGlyphArrays(size_t size);
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index dacbe41..8b85a7b7 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -157,6 +157,7 @@
return false;
}
+ bool ret = false;
for (int i = start; i < start + count; i++) {
// XXX this thinks it knows that surrogates are never mirrored
@@ -165,10 +166,10 @@
if (c1 != c2) {
data[i] = c2;
- return true;
+ ret = true;
}
}
- return false;
+ return ret;
}
static jchar getMirror(JNIEnv* env, jobject obj, jchar c)
diff --git a/core/res/res/layout/global_actions_item.xml b/core/res/res/layout/global_actions_item.xml
index 694301e..009f37b 100644
--- a/core/res/res/layout/global_actions_item.xml
+++ b/core/res/res/layout/global_actions_item.xml
@@ -27,11 +27,11 @@
android:paddingBottom="6dip"
>
<ImageView android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
android:layout_gravity="center"
android:layout_marginRight="16dip"
- />
+ android:scaleType="center"/>
<LinearLayout
android:orientation="vertical"
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index e574219..8402b36 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -33,11 +33,12 @@
android:orientation="horizontal">
<ImageView
android:id="@+android:id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:layout_gravity="center"
- android:minWidth="48dp"
- android:paddingRight="@dimen/preference_item_padding_inner" />
+ android:scaleType="centerCrop"
+ android:layout_marginRight="@dimen/preference_item_padding_inner"
+ />
</LinearLayout>
<RelativeLayout
diff --git a/core/res/res/layout/wifi_p2p_dialog.xml b/core/res/res/layout/wifi_p2p_dialog.xml
index 8234187..86dcbfa 100644
--- a/core/res/res/layout/wifi_p2p_dialog.xml
+++ b/core/res/res/layout/wifi_p2p_dialog.xml
@@ -37,8 +37,10 @@
style="@style/wifi_item_label" />
<EditText android:id="@+id/wifi_p2p_wps_pin"
- android:inputType="textNoSuggestions"
- style="@style/wifi_item_content" />
+ android:singleLine="true"
+ android:maxLines="8"
+ android:inputType="number"
+ style="@style/wifi_item_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7002578..9a1497d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -934,8 +934,10 @@
<string name="deleteText" msgid="7070985395199629156">"vee uit"</string>
<string name="inputMethod" msgid="1653630062304567879">"Invoermetode"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Teksaksies"</string>
- <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Bergingspasie word min"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sommige stelselfunksies werk moontlik nie"</string>
+ <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
+ <skip />
+ <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
+ <skip />
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1033,6 +1035,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> stuur \'n groot aantal SMS-boodskappe. Wil jy hierdie program toelaat om voort te gaan om boodskappe te stuur?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Laat toe"</string>
<string name="sms_control_no" msgid="625438561395534982">"Weier"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Stuur SMS na kortkode?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Stuur \'n premium-SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil graag \'n SMS stuur aan <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, wat lyk asof dit \'n SMS-kortkode is.<p>Die stuur van SMS\'e na sommige kortkodes kan veroorsaak dat jou selfoonrekening gedebiteer word vir premiumdienste.<p>Wil jy hierdie program toelaat om die boodskap te stuur?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil graag \'n SMS stuur aan <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, wat \'n betaalde SMS-kortkode is.<p><b>As jy \'n boodskap na hierdie bestemming stuur, sal jou selfoonrekening gedebiteer word vir betaalde dienste.</b><p>Wil jy hierdie program toelaat om die boodskap te stuur?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Stuur boodskap"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Moenie stuur nie"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Gee kwaadwillige program aan"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kaart verwyder"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Die mobielnetwerk sal nie beskikbaar wees nie totdat jy weer begin met \'n geldige SIM-kaart."</string>
<string name="sim_done_button" msgid="827949989369963775">"Klaar"</string>
@@ -1289,5 +1298,6 @@
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-klank"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Stelsel"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-oudio"</string>
- <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klaar"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4cd27e0..df4bb57 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ቁጥራቸው ብዙ የሆኑ የኤስ.ኤም.ኤስ. መልዕክቶችን እየላከ ነው። ይሄ መተግበሪያ መልዕክቶችን መላኩን እንዲቀጥል መፍቀድ ትፈልጋለህ?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"ፍቀድ"</string>
<string name="sms_control_no" msgid="625438561395534982">"ከልክል"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ኤስ.ኤም.ኤስ. ለአጭር ኮድ ይላክ?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"ከፍ ያለ ኤስ.ኤም.ኤስ. ይላክ?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> የጽሑፍ መልዕክት ለ<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> መላክ ይፈልጋል፣ ይሄ ደግሞ የኤስ.ኤም.ኤስ. አጭር ኮድ ሆኖ ተገኝቷል።<p>የጽሑፍ መልዕክቶች ለሆኑ አጭር ኮዶች መላክ የተንቀሳቃሽ መለያህ ከፍ ላሉ አገልግሎቶች ሊያስከፍለው ይችላል።<p>ይሄ መተግበሪያ መልዕክቱ እንዲልክ መፍቀድ ትፈልጋለህ?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> የጽሑፍ መልዕክት ለ<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> መላክ ይፈልጋል፣ ይሄ ደግሞ ከፍ ያለ የኤስ.ኤም.ኤስ. አጭር ኮድ ነው።<p><b>መልዕክት ወደዚህ ቦታ መላክ የተንቀሳቃሽ መለያህ ከፍ ላሉ አገልግሎቶች ያስከፍለዋል።</b><p>ይሄ መተግበሪያ መልዕክቱ እንዲልክ መፍቀድ ትፈልጋለህ?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"መልዕክት ላክ"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"አትላክ"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"ተንኮል አዘል መተግበሪያ ሪፖርት አድርግ"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM ካርድ ተወግዷል"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"በትክክል የገባ SIM ካርድ ድጋሚ እስኪያስጀምሩ የተንቀሳቃሽ ስልክ አውታረመረብ አይገኝም።"</string>
<string name="sim_done_button" msgid="827949989369963775">"ተከናውኗል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index fc7d09f..d2bb302 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يرسل عددًا كبيرًا من الرسائل القصيرة SMS. هل تريد السماح لهذا التطبيق بالاستمرار في إرسال الرسائل؟"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"السماح"</string>
<string name="sms_control_no" msgid="625438561395534982">"رفض"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"إرسال رسالة SMS إلى رمز قصير؟"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"هل تريد إرسال رسالة قصيرة SMS مميزة؟"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يريد إرسال رسالة نصية إلى <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>، والذي يُعد رمزًا قصيرًا لرسالة قصيرة SMS.<p>قد يؤدي إرسال رسائل نصية إلى بعض الرموز القصيرة إلى تحصيل رسوم من حساب جوالك للخدمات المميزة.<p>هل تريد السماح لهذا التطبيق بإرسال الرسالة؟"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> يريد إرسال رسالة نصية إلى <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>، والذي يُعد رمزًا قصيرًا لرسالة قصيرة SMS مميزة.<p><b>سيؤدي إرسال رسالة إلى هذه الوجهة إلى تحصيل رسوم من حساب جوالك للخدمات المميزة.</b><p>هل تريد السماح لهذا التطبيق بإرسال الرسالة؟"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"إرسال رسالة"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"عدم الإرسال"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"الإبلاغ عن تطبيق ضار"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"تمت إزالة بطاقة SIM"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"لن تكون شبكة الجوال متاحة حتى تتم إعادة التشغيل وإدخال بطاقة SIM صالحة."</string>
<string name="sim_done_button" msgid="827949989369963775">"تم"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ec18743..6bd482a 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> дасылае вялікую колькасць SMS-паведамленняў. Дазволіць гэтаму прыкладанню працягваць адпраўляць паведамленні?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Дазволіць"</string>
<string name="sms_control_no" msgid="625438561395534982">"Забараніць"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Адправiць SMS на кароткі нумар?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Адправiць платнае SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b&gt спрабуе адправiць тэкставае паведамленне на нумар <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, які, здаецца, з\'яўляецца кароткім нумарам для SMS.<p>Дасыланне тэкставых паведамленняў на кароткія нумары можа прывесці да спісання сродкаў з вашага мабільнага рахунку за платныя паслугі.</b><p>Жадаеце дазволіць гэтаму прыкладанню даслаць паведамленне?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Прыкладанне <b><xliff:g id="APP_NAME">%1$s</xliff:g></b&g спрабуе адправiць тэкставае паведамленне на нумар <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, які з\'яўляецца платным кароткім нумарам для SMS.<p><b>Адпраўка паведамлення гэтаму атрымальніку прывядзе да спісання сродкаў з вашага мабільнага рахунку за платныя паслугі.</b><p>Жадаеце дазволіць гэтаму прыкладанню даслаць паведамленне?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Адправiць паведамленне"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не адпраўляць"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Павед. аб шкодн. прыкладаннях"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта выдаленая"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мабільная сетка будзе недаступная да перазагрузкі з дзеючай SIM-картай."</string>
<string name="sim_done_button" msgid="827949989369963775">"Гатова"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Дынамікі станцыi"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аўдыёвыхад"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Сістэма"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-аўдыё"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Гатова"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index a123a48..2e9d3f1 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> изпраща голям брой SMS съобщения. Искате ли да разрешите на това приложение да продължи да го прави?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Разрешаване"</string>
<string name="sms_control_no" msgid="625438561395534982">"Отказване"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Да се изпрати ли SMS до кратък код?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Да се изпрати ли импулсен SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> иска да изпрати текстово съобщение до <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, което изглежда е кратък код на SMS.<p>Изпращането на съобщения до някои такива кодове може да доведе до таксуване на мобилната ви сметка за услуги, които се плащат допълнително.<p>Искате ли да разрешите на това приложение да изпрати съобщението?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> иска да изпрати текстово съобщение до <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, което е кратък код за импулсен SMS.<p><b>Изпращането до тази точка ще доведе до таксуване на мобилната ви сметка за услуги, които се плащат допълнително.</b><p>Искате ли да разрешите на това приложение да изпрати съобщението?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Изпращане на съобщението"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Да не се изпраща"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Сигнал за злонам. приложение"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM картата е премахната"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Няма да имате достъп до мобилната мрежа, докато не рестартирате с поставена валидна SIM карта."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Докинг станц.: Високогов."</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Звук през Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3340d0c..4324e4c 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> està enviant molts missatges SMS. Vols permetre que aquesta aplicació continuï enviant missatges?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permet"</string>
<string name="sms_control_no" msgid="625438561395534982">"Denega"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Vols enviar SMS a codi curt?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vols enviar el SMS prèmium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vol enviar un missatge de text a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que sembla que és un codi SMS curt.<p>Si envies missatges de text a codis curts, pot ser que es carreguin serveis prèmium al teu compte mòbil.<p>Vols permetre que aquesta aplicació enviï el missatge?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vol enviar un missatge de text a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que és un codi curt SMS prèmium.<p><b>Si envies un missatge a aquesta destinació, es carregaran els serveis prèmium al teu compte mòbil.</b><p>Vols permetre que aquesta aplicació enviï el missatge?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Envia el missatge"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"No enviïs"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Informa d\'una aplic. maliciosa"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Extracció de la targeta SIM"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La xarxa de telefonia mòbil no estarà disponible fins que no reiniciïs amb una targeta SIM vàlida inserida."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fet"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 6320ec1..a67c3c9 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>odesílá velký počet SMS zpráv. Chcete aplikaci povolit, aby zprávy odesílala i nadále?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Povolit"</string>
<string name="sms_control_no" msgid="625438561395534982">"Odmítnout"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Odeslat SMS?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Odeslat zprávu Premium SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikace<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odeslat zprávu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, což je zřejmě číslo služby SMS.<p>Za odesílání zpráv na určitá čísla mohou být na mobilní účet naúčtovány poplatky za prémiové služby.<p>Chcete aplikaci povolit odeslání zprávy?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce poslat zprávu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, což je číslo služby Premium SMS.<p><b>Pokud zprávu odešlete na toto číslo, budou vám na mobilní účet naúčtovány poplatky za prémiové služby.</b><p>Chcete aplikaci povolit odeslání zprávy?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Odeslat zprávu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Neodesílat"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Nahlásit škodlivou aplikaci"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM karta odebrána"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilní síť bude dostupná až poté, co vložíte platnou SIM kartu a restartujete zařízení."</string>
<string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth Audio"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 63456c0..e6f1f86 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sender et stort antal sms-beskeder. Vil du tillade, at denne app fortsat sender beskeder?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Tillad"</string>
<string name="sms_control_no" msgid="625438561395534982">"Afvis"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Send sms til shortcode?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vil du sende en premium-sms?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil du sende en sms til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som ser ud til at være en premium-sms-shortcode.&.<p>Hvis du sender en sms til nogle shortcodes, kan det medføre, at din mobilkonto bliver debiteret for premium-tjenester.<p>Vil du tillade, at denne app sender beskeden?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil du sende en sms til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som er en premium-sms-shortcode.<p><b>Hvis du sender en besked til denne destination, bliver din mobilkonto debiteret for premium-tjenester.</b><p>Vil du tillade, at denne app sender beskeden?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Send besked"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Send ikke"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportér ondsindet app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort blev fjernet"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobile netværk er utilgængeligt, indtil du genstarter med et gyldigt SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Afslut"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockstationens højttalere"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Udfør"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3fee27f..570dfa3 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sendet eine große Anzahl SMS. Möchten Sie zulassen, dass die App weiterhin Nachrichten sendet?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Zulassen"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nicht zulassen"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS an Kurzwahl senden?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium-SMS senden?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> versucht, eine SMS an <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> zu senden. Dabei scheint es sich um eine SMS-Kurzwahl zu handeln.<p>Wenn Sie SMS an eine Kurzwahl senden, werden Ihnen für Ihr Mobilfunkkonto möglicherweise Premiumdienste in Rechnung gestellt.<p>Möchten Sie zulassen, dass die App die Nachricht sendet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> versucht, eine SMS an die Premium-SMS-Kurzwahl <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> zu senden.<p><b>Wenn Sie eine Nachricht an diese Zieladresse senden, werden Ihnen für Ihr Mobilfunkkonto Premiumdienste in Rechnung gestellt.</b><p>Möchten Sie zulassen, dass die App die Nachricht sendet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Nachricht senden"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nicht senden"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Schädliche App melden"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-Karte entfernt"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Das Mobilfunknetz ist erst wieder verfügbar, wenn Sie einen Neustart mit einer gültigen SIM-Karte durchführen."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fertig"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 481b6cb..aa41a3e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> στέλνει έναν μεγάλο αριθμό μηνυμάτων SMS. Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να συνεχίσει να στέλνει μηνύματα;"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Αποδοχή"</string>
<string name="sms_control_no" msgid="625438561395534982">"Άρνηση"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Να αποσταλεί SMS στον κωδικό;"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Να σταλεί SMS ειδικής χρέωσης;"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ζητά την έγκρισή σας για την αποστολή μηνύματος κειμένου στον αριθμό <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ο οποίος φαίνεται ότι είναι κωδικός για την αποστολή SMS με ειδική χρέωση.<p>Η αποστολή μηνύματος σε αυτόν τον αριθμό θα χρεωθεί στον λογαριασμό του κινητού σας ως παροχή υπηρεσιών.<p>Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να στείλει το μήνυμα;"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> θέλει να στείλει ένα μήνυμα κειμένου στον αριθμό <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ο οποίος είναι ένας κωδικός αποστολής SMS με ειδική χρέωση.<p><b>Η αποστολή μηνύματος σε αυτόν τον αριθμό θα χρεωθεί στον λογαριασμό του κινητού σας ως παροχή υπηρεσιών.</b><p>Θέλετε να επιτρέψετε σε αυτήν την εφαρμογή να στείλει το μήνυμα;"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Αποστολή μηνύματος"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Να μην αποσταλεί"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Αναφορά κακόβουλης εφαρμογής"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Η κάρτα SIM αφαιρέθηκε"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Το δίκτυο κινητής τηλεφωνίας δεν θα είναι διαθέσιμο μέχρι να κάνετε επανεκκίνηση αφού τοποθετήσετε μια έγκυρη κάρτα SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Τέλος"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 6596393..bdcf659 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is sending a large number of SMS messages. Do you want to allow this app to continue sending messages?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Allow"</string>
<string name="sms_control_no" msgid="625438561395534982">"Deny"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Send SMS to short code?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Send premium SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, which appears to be an SMS short code.<p>Sending text messages to some short codes may cause your mobile account to be billed for premium services.<p>do you want to allow this app to send the message?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, which is a premium SMS short code.<p><b>Sending a message to this destination will cause your mobile account to be billed for premium services.</b><p>Do you want to allow this app to send the message?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Send message"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Don\'t send"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Report malicious app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM card removed"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"The mobile network will be unavailable until you restart with a valid SIM card inserted."</string>
<string name="sim_done_button" msgid="827949989369963775">"Done"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 9971e8d..0ae2da3 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está enviando una gran cantidad de mensajes SMS. ¿Quieres permitir que está aplicación siga enviando mensajes?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
<string name="sms_control_no" msgid="625438561395534982">"Rechazar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"¿Enviar SMS premium?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"¿Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, y parece que se trata de un SMS premium.<p>Al enviar mensajes de texto a estos números, es posible que se facturen servicios premium en tu cuenta móvil.<p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, y se trata de un SMS premium.<p><b>Al enviar un mensaje a este destino, se podrán facturar servicios premium en tu cuenta móvil.</b><p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensaje"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"No enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Notificar aplicación malintencionada"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La red para celulares no estará disponible hasta que reinicies, luego de insertar una tarjeta SIM válida."</string>
<string name="sim_done_button" msgid="827949989369963775">"Finalizado"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 59e34f0..4d5b7d0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está enviando un gran número de mensajes SMS. ¿Quieres permitir que está aplicación siga enviando mensajes?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
<string name="sms_control_no" msgid="625438561395534982">"Denegar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"¿Enviar SMS premium?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"¿Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> y parece que se trata de un SMS premium.<p>Al enviar mensajes de texto a estos números, es posible que se facturen servicios premium en tu cuenta móvil.<p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> quiere enviar un mensaje de texto a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> y se trata de un SMS premium.<p><b>Al enviar un mensaje a este destino, se podrán facturar servicios premium en tu cuenta móvil.</b><p>¿Quieres permitir que esta aplicación envíe el mensaje?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensaje"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"No enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Notificar aplicación malintencionada"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La red móvil no estará disponible hasta que reinicies el dispositivo con una tarjeta SIM válida."</string>
<string name="sim_done_button" msgid="827949989369963775">"Listo"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index ad27378..4597ae7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> saadab suurel hulgal SMS-sõnumeid. Kas tahate lubada sellel rakendusel ka edaspidi sõnumeid saata?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Luba"</string>
<string name="sms_control_no" msgid="625438561395534982">"Keela"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kas saata SMS lühinumbrile?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Kas saata tasuline SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tahab saata tekstsõnumi adressaadile <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, mis paistab olevat SMS-i lühinumber.<p>Mõnele lühinumbrile saadetud sõnumi eest võidakse teie mobiilikontole esitada arve tasuliste teenuste eest.<p>Kas lubate rakendusel selle sõnumi saata?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tahab saata tekstsõnumi adressaadile <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, mis on tasulise SMS-i lühinumber.<p><b>Kui saadate sõnumi sellele adressaadile, esitatakse teie mobiilikontole arve tasuliste teenuste eest.</b><p>Kas lubate rakendusel sõnumi saata?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Saada sõnum"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ära saada"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Teata pahatahtlikust rakend."</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kaart eemaldatud"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobiilsidevõrk ei ole saadaval, kuni sisestate kehtiva SIM-kaardi ja taaskäivitate seadme."</string>
<string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d9df2a2..fbc1126 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -934,8 +934,10 @@
<string name="deleteText" msgid="7070985395199629156">"حذف"</string>
<string name="inputMethod" msgid="1653630062304567879">"روش ورودی"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"عملکردهای متنی"</string>
- <string name="low_internal_storage_view_title" msgid="5576272496365684834">"فضای ذخیرهسازی رو به اتمام است"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
+ <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
+ <skip />
+ <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
+ <skip />
<string name="ok" msgid="5970060430562524910">"تأیید"</string>
<string name="cancel" msgid="6442560571259935130">"لغو"</string>
<string name="yes" msgid="5362982303337969312">"تأیید"</string>
@@ -1033,6 +1035,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> در حال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"اجازه دادن"</string>
<string name="sms_control_no" msgid="625438561395534982">"ردکردن"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"پیامک به کد کوتاه ارسال شود؟"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"پیامک ممتاز ارسال شود؟"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> میخواهد یک پیام نوشتاری را به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ارسال کند که به نظر میرسد یک کد کوتاه پیامک است.<p>ارسال پیامهای نوشتاری به برخی از کدهای کوتاه ممکن است باعث شود برای حساب تلفن همراه شما بابت استفاده از سرویسهای ممتاز صورتحساب ارسال شود.<p>آیا به این برنامه اجازه میدهید پیام ارسال کند؟"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> میخواهد یک پیام نوشتاری را به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ارسال کند که یک کد کوتاه پیامک ممتاز است.<p><b>ارسال پیام به این مقصد ممکن است باعث شود برای حساب تلفن همراه شما بابت استفاده از سرویسهای ممتاز صورتحساب ارسال شود.</b><p>آیا به این برنامه اجازه میدهید پیامک ارسال کند؟"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"ارسال پیام"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"ارسال نشود"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"گزارش برنامه مخرب"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"سیم کارت برداشته شد"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"تا وقتی که با یک سیمکارت معتبر راهاندازی مجدد نکنید شبکه تلفن همراه غیر قابل دسترس خواهد بود."</string>
<string name="sim_done_button" msgid="827949989369963775">"انجام شد"</string>
@@ -1288,6 +1297,8 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"بلندگوهای جایگاه اتصال"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صدای HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"سیستم"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"بلوتوثهای صوتی"</string>
- <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"انجام شد"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0318203..7ffdce3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> lähettää suuria määriä tekstiviestejä. Annetaanko tämän sovelluksen jatkaa tekstiviestien lähettämistä?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Salli"</string>
<string name="sms_control_no" msgid="625438561395534982">"Kiellä"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Lähetetäänkö viesti?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Lähetä maksullinen viesti?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> haluaa lähettää tekstiviestin kohteeseen <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, joka voi olla maksullinen numero.<p><b>Jos lähetät viestin tähän kohteeseen, sinua saatetaan veloittaa maksullisten palveluiden käytöstä.</b><p>Annetaanko sovelluksen lähettää viesti?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> haluaa lähettää tekstiviestin kohteeseen <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, joka on maksullinen numero.<p><b>Jos lähetät viestin tähän kohteeseen, sinua veloitetaan maksullisten palveluiden käytöstä.</b><p>Annetaanko sovelluksen lähettää viesti?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Lähetä viesti"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Älä lähetä"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ilmoita haittasovelluksesta"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kortti poistettu"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobiiliverkko ei ole käytettävissä, ennen kuin käynnistät uudelleen kelvollisella laitteeseen kytketyllä SIM-kortilla."</string>
<string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4a7a9c7..3b6162e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> envoie un grand nombre de SMS. Autorisez-vous cette application à poursuivre l\'envoi des messages ?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Autoriser"</string>
<string name="sms_control_no" msgid="625438561395534982">"Refuser"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Envoyer SMS au numéro abrégé ?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Envoyer un SMS premium ?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> essaie d\'envoyer un SMS à <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Il s\'agit apparemment d\'un numéro abrégé.<p>L\'envoi de SMS à de tels numéros peut entraîner la facturation de services premium sur votre compte mobile.<p>Autorisez-vous cette application à envoyer ce message ?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> essaie d\'envoyer un SMS à <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Il s\'agit apparemment d\'un numéro abrégé de type premium.<p><b>L\'envoi de SMS à ce destinataire entraînera la facturation de services premium sur votre compte mobile.</b><p>Autorisez-vous cette application à envoyer le message ?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Envoyer le message"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne pas envoyer"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Signaler appli malveillante"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Carte SIM retirée"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Le réseau mobile ne sera pas disponible avant le redémarrage avec une carte SIM valide insérée."</string>
<string name="sim_done_button" msgid="827949989369963775">"OK"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Haut-parleurs de la station d\'accueil"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Système"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"OK"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 56a29bf..946ae69 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> बड़ी संख्या में SMS संदेश भेज रहा है. क्या आप इस एप्लिकेशन को संदेश भेजना जारी रखने देना चाहते हैं?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"अनुमति दें"</string>
<string name="sms_control_no" msgid="625438561395534982">"अस्वीकार करें"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"शॉर्ट कोड पर SMS भेजें?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"प्रीमियम SMS भेजें?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> को एक पाठ संदेश भेजना चाहता है, जो एक SMS शॉर्ट कोड लगता है.<p>कुछ शॉर्ट कोड को पाठ संदेश भेजने से आपके मोबाइल खाते पर प्रीमियम सेवाओं का शुल्क लिया जा सकता है.<p>क्या आप इस एप्लिकेशन को यह संदेश भेजने देना चाहते हैं?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> को एक पाठ संदेश भेजना चाहता है, जो एक प्रीमियम SMS शॉर्ट कोड है.<p><b>इस गंतव्य पर कोई संदेश भेजने से आपके मोबाइल खाते पर प्रीमियम सेवाओं का शुल्क लिया जाएगा.</b><p>क्या आप इस एप्लिकेशन को संदेश भेजने देना चाहते हैं?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"संदेश भेजें"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"न भेजें"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"दुर्भावनापूर्ण एप्लि. की रिपोर्ट करें"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"सिमकार्ड निकाला गया"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"मान्य सिम कार्ड डालकर पुन: प्रारंभ करने तक मोबाइल नेटवर्क अनुपलब्ध रहेगा."</string>
<string name="sim_done_button" msgid="827949989369963775">"पूर्ण"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"डॉक स्पीकर"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ऑडियो"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्टम"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ऑडियो"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"पूर्ण"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 80dc095..618ec08 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> šalje veliki broj SMS poruka. Želite li dopustiti ovoj aplikaciji da nastavi slati poruke?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Dopusti"</string>
<string name="sms_control_no" msgid="625438561395534982">"Odbij"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Poslati SMS na skraćeni broj?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Poslati premium SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati tekstnu poruku na <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, a čini se da je to skraćeni SMS broj.<p>Slanje tekstnih poruka na neke skraćene interne brojeve može dovesti do naplate premium usluga na vašem računu mobilnog uređaja.<p>Želite li dopustiti aplikaciji da pošalje poruku?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati tekstnu poruku na <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, a to je skraćeni premium SMS broj.<p><b>Slanje poruke na taj broj dovest će do naplate premium usluga na vašem računu mobilnog uređaja.</b><p>Želite li dopustiti toj aplikaciji da pošalje poruku?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Pošalji poruku"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne šalji"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Prijavi zlonamjerne aplikacije"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kartica uklonjena"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilna mreža bit će nedostupna do ponovnog pokretanja s umetnutom važećom SIM karticom."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvučnici postolja"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sustav"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth zvuk"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index dad7dc6..0b86668 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></ b> nagyszámú SMS üzenetet küld. Engedélyezi, hogy ez az alkalmazás továbbra is üzeneteket küldjön?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Engedélyezés"</string>
<string name="sms_control_no" msgid="625438561395534982">"Elutasítás"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS küldése a rövid kódra?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Elküldi az emelt díjas SMS-t?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> szöveges üzenetet szeretne küldeni a(z) <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> címre, ami egy SMS rövid kódja.<p>Az egyes rövid kódokra küldött üzenetek miatt mobilszámláján emelt díjas szolgáltatások lesznek kiszámlázva.</b><p>Engedélyezi, hogy az alkalmazás elküldje az üzenetet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> szöveges üzenetet szeretne küldeni a(z) <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> címre, ami egy emelt díjas SMS rövid kódja.<p>Az ide küldött üzenet miatt mobilszámláján emelt díjas szolgáltatások lesznek kiszámlázva.</b><p>Engedélyezi, hogy az alkalmazás elküldje az üzenetet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Üzenet küldése"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nincs küldés"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rosszindulatú alk. bejelentése"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kártya eltávolítva"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A mobilhálózat nem lesz elérhető, amíg újra nem indítja egy érvényes SIM kártya behelyezése után."</string>
<string name="sim_done_button" msgid="827949989369963775">"Kész"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkolóegység hangszórója"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audió"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Rendszer"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth hang"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d8ec0c9..5671f15 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sedang mengirim pesan SMS dalam jumlah besar. Izinkan aplikasi ini untuk melanjutkan pengiriman pesan?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Izinkan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Tolak"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kirim SMS ke kode singkat?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Kirim SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> akan mengirim pesan teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang akan muncul sebagai kode singkat SMS.<p>Mengirim pesan teks ke beberapa kode singkat menyebabkan Anda dikenakan biaya layanan premium pada akun seluler Anda.<p>Izinkan aplikasi ini mengirim pesan?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> akan mengirim pesan teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kode singkat SMS premium.<p><b>Mengirim pesan ke tujuan ini menyebabkan Anda dikenakan biaya layanan premium pada akun seluler Anda.</b><p>Izinkan aplikasi ini mengirim pesan?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Kirim pesan"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Jangan kirim"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Laporkan aplikasi berbahaya"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kartu SIM dihapus"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Jaringan seluler tidak akan tersedia sampai Anda memulai lagi dengan memasukkan kartu SIM yang valid."</string>
<string name="sim_done_button" msgid="827949989369963775">"Selesai"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index dfa1133..f30d63d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sta inviando molti SMS. Vuoi consentire all\'applicazione di continuare a inviare messaggi?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Consenti"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nega"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Inviare SMS a codice breve?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Inviare SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vorrebbe inviare un messaggio di testo a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, che sembra essere un codice breve SMS.<p>L\'invio di messaggi di testo ad alcuni codici brevi potrebbe comportare l\'addebito di servizi premium sul tuo account per cellulari.<p>Vuoi consentire a questa applicazione di inviare il messaggio?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vorrebbe inviare un messaggio di testo a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, che è un codice breve SMS premium.<p><b>L\'invio di un messaggio a questa destinazione comporterà l\'addebito di servizi premium sul tuo account per cellulari.</b><p>Vuoi consentire a questa applicazione di inviare il messaggio?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Invia messaggio"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Non inviare"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Segnala applicazione dannosa"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Scheda SIM rimossa"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"La rete mobile non sarà disponibile finché non eseguirai il riavvio con una scheda SIM valida inserita."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fine"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6e83f63..a842118 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> שולח מספר רב של הודעות SMS. האם ברצונך לאפשר ליישום זה להמשיך לשלוח הודעות?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"אפשר"</string>
<string name="sms_control_no" msgid="625438561395534982">"דחה"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"לשלוח SMS לקוד קצר?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"לשלוח SMS פרימיום?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> רוצה לשלוח הודעת טקסט אל <b> <xliff:g id="DEST_ADDRESS">%2$s</xliff:g> </ b>, שנראה כמו קוד SMS קצר. <p> שליחת הודעות טקסט לקודים קצרים מסוימים עשויה לגרום לחיוב חשבון הנייד שלך בשירותי פרימיום. <p> האם ברצונך לאפשר ליישום זה לשלוח את ההודעה?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b> <xliff:g id="APP_NAME">%1$s</xliff:g> </ b> רוצה לשלוח הודעת טקסט ל-<b> <xliff:g id="DEST_ADDRESS">%2$s</xliff:g> </ b>, שהוא קוד פרימיום קצר של SMS. <b> <p> שליחת הודעה ליעד זה תגרום לחיוב חשבון הנייד שלך בשירותי פרימיום. </ b> <p> האם ברצונך לאפשר ליישום זה לשלוח את ההודעה?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"שלח הודעה"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"אל תשלח"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"דווח על יישום זדוני"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"כרטיס ה-SIM הוסר"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"הרשת הסלולרית לא תהיה זמינה עד שתפעיל מחדש לאחר הכנסת כרטיס SIM חוקי."</string>
<string name="sim_done_button" msgid="827949989369963775">"סיום"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 303db08..fe120d2 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が大量のSMSメッセージを送信しています。このアプリにこのままメッセージの送信を許可しますか?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"許可する"</string>
<string name="sms_control_no" msgid="625438561395534982">"許可しない"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ショートコードへのSMSの送信"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"プレミアムSMSを送信しますか?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が、SMSショートコードと思われる<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>にテキストメッセージを送信しようとしています。<p>一部のショートコードにテキストメッセージを送信すると、プレミアムサービスの料金がモバイルアカウントが請求される場合があります。<p>このアプリにメッセージの送信を許可しますか?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>が、プレミアムSMSショートコード<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>にテキストメッセージを送信しようとしています。<p><b>この宛先にメッセージを送信すると、プレミアムサービスの料金がモバイルアカウントに請求されます。</b><p>このアプリにメッセージの送信を許可しますか?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"メッセージを送信"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"送信しない"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"悪意のあるアプリを報告"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIMカードが取り外されました"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"有効なSIMカードを挿入して再起動するまでは、モバイルネットワークは利用できません。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完了"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ホルダーのスピーカー"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMIオーディオ"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"システム"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth音声"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完了"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ffd8c03..9269f95 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) SMS 메시지를 대량으로 보내고 있습니다. 해당 앱이 메시지를 계속 보내도록 하시겠습니까?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"허용"</string>
<string name="sms_control_no" msgid="625438561395534982">"거부"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"SMS를 단축 코드로 보내시겠습니까?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"프리미엄 SMS를 보내시겠습니까?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) SMS 단축 코드로 추정되는 문자 메시지를 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(으)로 보내려 합니다.<p>문자 메시지를 단축 코드로 보내면 사용자의 모바일 계정에 프리미엄 서비스 요금이 청구될 수 있습니다.<p>해당 앱이 메시지를 보내도록 하시겠습니까?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) 문자 메시지를 프리미엄 SMS 단축 코드인 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(으)로 보내려 합니다.<p><b>메시지를 보내면 사용자의 모바일 계정에 프리미엄 서비스 요금이 청구됩니다.</b><p>해당 앱이 메시지를 보내도록 하시겠습니까?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"메시지 보내기"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"보내지 않음"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"악성 앱 신고"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM 카드 제거됨"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"유효한 SIM 카드를 삽입하여 다시 시작할 때까지 모바일 네트워크를 사용할 수 없습니다."</string>
<string name="sim_done_button" msgid="827949989369963775">"완료"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"도크 스피커"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 오디오"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"시스템"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"블루투스 오디오"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"완료"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b6a4b23..0971b80 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> siunčiama daug SMS pranešimų. Ar norite leisti šiai programai toliau siųsti pranešimus?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Leisti"</string>
<string name="sms_control_no" msgid="625438561395534982">"Uždrausti"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Siųsti SMS trumpuoju numeriu?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Siųsti brangesnį SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prašoma išsiųsti teksto pranešimą <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, o tai yra trumpasis SMS numeris.<p><b>Siųsdami pranešimus kai kuriais trumpaisiais numeriais galite būti apmokestinti mobiliojo ryšio sąskaitoje už brangesnes paslaugas.</b><p>Ar norite leisti šiai programai siųsti pranešimą?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Naudojant <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prašoma išsiųsti teksto pranešimą <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, o tai yra brangesnis trumpasis SMS numeris.<p><b>Siųsdami pranešimą šiam gavėjui mobiliojo ryšio sąskaitoje būsite apmokestinti už brangesnes paslaugas.</b><p>Ar norite leisti šiai programai siųsti pranešimą?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Siųsti pranešimą"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nesiųsti"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Pranešti apie kenkėj. programą"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kortelė pašalinta"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilusis tinklas bus nepasiekiamas, kol nepaleisite iš naujo įdėję tinkamą SIM kortelę."</string>
<string name="sim_done_button" msgid="827949989369963775">"Atlikta"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f497083..bd76a09 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sūta daudz īsziņu. Vai vēlaties, lai šī lietotne turpinātu sūtīt ziņojumus?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Atļaut"</string>
<string name="sms_control_no" msgid="625438561395534982">"Aizliegt"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Vai sūtīt īsziņu uz īso kodu?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vai nosūtīt īpašo īsziņu?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vēlas nosūtīt īsziņu uz adresi <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kas, iespējams, ir īsziņas īsais kods.<p><b>Sūtot īsziņas uz dažiem īsajiem kodiem, no jūsu mobilā konta var tikt iekasēta maksa par paaugstinātas maksas pakalpojumiem.</b><p>Vai vēlaties atļaut šai lietotnei sūtīt šo ziņojumu?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vēlas nosūtīt īsziņu uz adresi <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kas, iespējams, ir paaugstinātas maksas īsziņas īsais kods.<p><b>Sūtot ziņojumu uz šo galamērķi, no jūsu mobilā konta tiks iekasēta maksa par paaugstinātas maksas pakalpojumiem.</b><p>Vai vēlaties atļaut šai lietotnei sūtīt šo ziņojumu?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Sūtīt ziņojumu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nesūtīt"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ziņot par ļaunprātīgu lietotni"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM karte ir izņemta."</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilais tīkls nebūs pieejams līdz brīdim, kad restartēsiet ierīci ar ievietotu derīgu SIM karti."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gatavs"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index e861fdd6..38c6a27 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sedang menghantar banyak mesej SMS. Adakah anda mahu membenarkan apl ini terus menghantar mesej?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Benarkan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nafikan"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Hantar SMS ke kod pendek?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Hantar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingin menghantar mesej teks kepada <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kod pendek SMS.<p>Menghantar mesej teks ke sesetengah kod pendek boleh menyebabkan akaun mudah alih anda dikenakan bayaran perkhidmatan premium.<p>Adakah anda mahu membenarkan apl ini menghantar mesej itu?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingin menghantar mesej teks ke <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, yang merupakan kod pendek SMS premium.<p><b>Menghantar mesej ke destinasi ini akan menyebabkan akaun mudah alih anda dikenakan bayaran untuk perkhidmatan premium.</b><p>Adakah anda mahu membenarkan apl ini menghantar mesej itu?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Hantar mesej"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Jangan hantar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Laporkan aplikasi hasad"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kad SIM dikeluarkan"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Rangkaian mudah alih tidak akan tersedia sehingga anda mula semula dengan kad SIM yang sah dimasukkan."</string>
<string name="sim_done_button" msgid="827949989369963775">"Selesai"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pembesar suara dok"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 16e054d..a4ed927 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sender et stort antall SMS. Vil du la appen fortsette å sende ut meldinger?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Tillat"</string>
<string name="sms_control_no" msgid="625438561395534982">"Sperr"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Vil du sende SMS til kortkoden?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Vil du sende premium-SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil sende en tekstmelding til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som ser ut til å være en SMS-kortkode.<p>Hvis du sender en melding til denne destinasjonen, kan mobilkontoen din komme til å belastes for premium-tjenester.<p>Vil du la denne meldingen sendes av appen?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vil sende en tekstmelding til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, som er en premium SMS-kortkode.<p><b>Hvis du sender en melding til denne destinasjonen, belastes mobilkontoen din for premium-tjenester.</b><p>Vil du la denne meldingen sendes av appen?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Send melding"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ikke send"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportér skadelig app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort er fjernet"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobile nettverket forblir utilgjengelig inntil du starter på nytt med et gyldig SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Fullført"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ac6ec6c..36c309e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> verzendt moment een groot aantal sms-berichten. Wilt u toestaan dat deze app berichten blijft verzenden?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Sms verzenden naar shortcode?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium-sms verzenden?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil een sms-bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Dit is waarschijnlijk een sms-shortcode.<p>Als u sms-berichten naar bepaalde shortcodes verzendt, worden mogelijk kosten voor premiumservices in rekening gebracht op uw mobiele account.<p>Wilt u toestaan dat deze app het bericht verzendt?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil een sms-bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>. Dit is premium sms-shortcode.<p><b>Als u een bericht naar deze bestemming verzendt, kosten voor premiumservices in rekening gebracht op uw mobiele account.</b><p>Wilt u toestaan dat deze app het bericht verzendt?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Bericht verzenden"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Niet verzenden"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Kwaadaardige app melden"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Simkaart verwijderd"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Het mobiele netwerk is niet beschikbaar totdat u het apparaat opnieuw start met een geldige simkaart."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gereed"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockluidsprekers"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systeem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-audio"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 9b5c91c..f536b6f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wysyła wiele SMS-ów. Chcesz pozwolić tej aplikacji dalej wysyłać SMS-y?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Pozwól"</string>
<string name="sms_control_no" msgid="625438561395534982">"Odmów"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Wysłać droższego SMS-a?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Wysłać droższego SMS-a?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce wysłać SMS-a pod numer <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, który wygląda na dodatkowo płatny.<p>Może to spowodować doliczenie do Twojego rachunku za komórkę opłaty za usługę dodatkową.<p>Chcesz pozwolić tej aplikacji na wysłanie SMS-a?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce wysłać SMS-a pod numer <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, który jest dodatkowo płatny.<p><b>To spowoduje doliczenie do Twojego rachunku za komórkę opłaty za usługę dodatkową.</b><p>Chcesz pozwolić tej aplikacji na wysłanie SMS-a?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Wyślij wiadomość"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nie wysyłaj"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Zgłoś złośliwą aplikację"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM wyjęta"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Sieć komórkowa będzie niedostępna do chwili ponownego uruchomienia urządzenia z użyciem ważnej karty SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Gotowe"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index aaa57a3..63da834 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> está a enviar um grande número de mensagens SMS. Pretende autorizar que a aplicação continue a enviar mensagens?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
<string name="sms_control_no" msgid="625438561395534982">"Recusar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Enviar SMS ao código pequeno?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pretende enviar um SMS para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que parece ser um código SMS pequeno.<p>Enviar esta mensagem a alguns códigos pequenos pode fazer com que sejam faturados serviços premium na sua conta de telemóvel.<p>Pretende autorizar que a aplicação envie a mensagem?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pretende enviar um SMS a <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que é um pequeno código de SMS premium.<p><b>Enviar uma mensagem para este destino irá fazer com que sejam faturados serviços premium na sua conta de telemóvel.</b><p>Pretende autorizar que a aplicação envie a mensagem?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensagem"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Não enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Comunicar aplicação maliciosa"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A rede de telemóvel estará indisponível até que reinicie o aparelho com um cartão SIM válido inserido."</string>
<string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 27a9c7c..c7b92b7 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> envia uma grande quantidade de mensagens SMS. Deseja permitir que este aplicativo continue enviando mensagens?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string>
<string name="sms_control_no" msgid="625438561395534982">"Negar"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Enviar SMS para código curto?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Enviar SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> deseja enviar uma mensagem de texto para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que parece ser um código curto SMS.<p>O envio de mensagens de texto a alguns códigos curtos pode fazer com que a conta seja cobrada por serviços premium.<p>Deseja permitir que este aplicativo envie a mensagem?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> deseja enviar uma mensagem de texto para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, que é um código curto SMS premium.<p><b>O envio de uma mensagem a esse destino fará com que a conta seja cobrada por serviços premium.</b><p>Deseja permitir que este aplicativo envie a mensagem?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Enviar mensagem"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Não enviar"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Denunciar aplicativo malicioso"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"A rede móvel ficará indisponível até que você reinicie com um cartão SIM válido inserido."</string>
<string name="sim_done_button" msgid="827949989369963775">"Concluído"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 3a229f7..50e0210 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1576,6 +1576,20 @@
<skip />
<!-- no translation found for sms_control_no (625438561395534982) -->
<skip />
+ <!-- no translation found for sms_short_code_confirm_title (1666863092640877318) -->
+ <skip />
+ <!-- no translation found for sms_premium_short_code_confirm_title (3811263856304367838) -->
+ <skip />
+ <!-- no translation found for sms_short_code_confirm_message (5616409294907295407) -->
+ <skip />
+ <!-- no translation found for sms_premium_short_code_confirm_message (6214083016284738667) -->
+ <skip />
+ <!-- no translation found for sms_short_code_confirm_allow (8957573662645722940) -->
+ <skip />
+ <!-- no translation found for sms_short_code_confirm_deny (6374609298084435887) -->
+ <skip />
+ <!-- no translation found for sms_short_code_confirm_report (2588793956061677070) -->
+ <skip />
<!-- no translation found for sim_removed_title (6227712319223226185) -->
<skip />
<!-- no translation found for sim_removed_message (2333164559970958645) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ff66810..be52015 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -934,8 +934,10 @@
<string name="deleteText" msgid="7070985395199629156">"ştergeţi"</string>
<string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acţiuni pentru text"</string>
- <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spaţiul de stocare aproape ocupat"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcţii de sistem să nu funcţioneze"</string>
+ <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
+ <skip />
+ <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
+ <skip />
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Anulaţi"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1033,6 +1035,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> trimite un număr mare de mesaje SMS. Permiteţi acestei aplicaţii să trimită în continuare mesaje?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Permiteţi"</string>
<string name="sms_control_no" msgid="625438561395534982">"Refuzaţi"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Trimiteţi SMS la codul scurt?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Trimiteţi SMS premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj text la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, care pare a fi un cod scurt SMS.<p>Trimiterea de mesaje text la unele coduri scurte poate determina taxarea contului dvs. mobil pentru servicii premium.<p>Permiteţi acestei aplicaţii să trimită mesajul?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj text la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, care este un cod scurt SMS premium.<p><b>Trimiterea unui mesaj la această destinaţie va determina taxarea contului dvs. mobil pentru servicii premium.</b><p>Permiteţi acestei aplicaţii să trimită mesajul?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Trimiteţi mesajul"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Nu trimiteţi"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Raport. aplic.rău intenţionată"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Card SIM eliminat"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Reţeaua mobilă va fi indisponibilă până când reporniţi cu o cartelă SIM validă introdusă."</string>
<string name="sim_done_button" msgid="827949989369963775">"Terminat"</string>
@@ -1288,6 +1297,8 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Difuz. dispozit. andocare"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ieşire audio HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
- <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminat"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b238e16..e534989 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> отправляет большое количество SMS. Разрешить приложению и дальше отправлять сообщения?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Разрешить"</string>
<string name="sms_control_no" msgid="625438561395534982">"Запретить"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Отправить SMS?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Отправить SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> собирается отправить SMS-сообщение на короткий номер <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b><p> За отправку сообщений на некоторые короткие номера с вашего счета могут списываться дополнительные средства.<p>Разрешить отправку?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> собирается отправить SMS на короткий номер <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>.<p><b> Если это произойдет, с вашего счета будут списаны дополнительные средства.</b><p>Разрешить отправку?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Отправить сообщение"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не отправлять"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Сообщить о вредоносном ПО"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта удалена"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Пока вы не вставите действующую SIM-карту, мобильная сеть будет недоступна."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динамики док-станции"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Воспроизведение звука через Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 86fc758..051d6ad 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> posiela veľký počet správ SMS. Chcete tejto aplikácií povoliť, aby aj naďalej posielala správy?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Povoliť"</string>
<string name="sms_control_no" msgid="625438561395534982">"Odmietnuť"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Odoslať SMS na skrátené číslo?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Odoslať prémiovú správu SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odoslať textovú správu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ktoré sa zdá byť skráteným číslom SMS.<p>Odoslanie správy na skrátené číslo môže spôsobiť, že na účet vášho mobilného zariadenia budú účtované poplatky za prémiové služby.<p>Chcete aplikácií povoliť túto správu odoslať?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> chce odoslať textovú správu na číslo <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ktoré je prémiovým skráteným číslom SMS.<p><b>Odoslanie správy na toto číslo spôsobí, že na účet vášho mobilného zariadenia budú účtované poplatky za prémiové služby.</b><p>Chcete aplikácii povoliť túto správu odoslať?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Odoslať správu"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Neodoslať"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Nahlásiť škodlivú aplikáciu"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM bola odobraná"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilná sieť nebude k dispozícii, kým nevložíte platnú kartu SIM a zariadenie nereštartujete."</string>
<string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index a7aca87..ff91e43 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pošilja veliko SMS-ov. Ali želite dovoliti, da jih še naprej pošilja?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Dovoli"</string>
<string name="sms_control_no" msgid="625438561395534982">"Zavrni"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Pošljem SMS na kratko štev.?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Pošljem SMS za plačlj. stor.?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati SMS na številko <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kar je videti kot kratka številka za plačljive storitve SMS.<p>S pošiljanjem sporočil na to številko bo vaš račun za mobilni telefon bremenjen za plačljive storitve.<p>Ali želite aplikaciji dovoliti, da pošlje sporočilo?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> želi poslati SMS na številko <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, kar je kratka številka za plačljive storitve SMS.<p><b>S pošiljanjem sporočil na to številko bo vaš račun za mobilni telefon bremenjen za plačljive storitve.</b><p>Ali želite aplikaciji dovoliti, da pošlje sporočilo?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Pošlji sporočilo"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ne pošlji"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Prijavi zlonamerno aplikacijo"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kartica SIM odstranjena"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mobilno omrežje ne bo na voljo, dokler naprave vnovič ne zaženete z veljavno kartico SIM."</string>
<string name="sim_done_button" msgid="827949989369963775">"Dokončano"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvočniki stojala"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvok HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Zvok prek Bluetootha"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c0e9a62..8c0a55a 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> шаље велики број SMS порука. Желите ли да дозволите овој апликацији да настави са слањем порука?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Дозволи"</string>
<string name="sms_control_no" msgid="625438561395534982">"Одбиј"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Пошаљи SMS на кратак кôд?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Желите да пошаљете премијум SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жели да вам пошаље текстуалну поруку на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, која можда представља кратак кôд SMS-а.<p>Слање порука на неке кратке кодове може да се наплаћује као премијум услуга са налога за мобилни уређај.<p>Желите ли да дозволите овој апликацији да пошаље поруку?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жели да вам пошаље текстуалну поруку на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, која представља кратак кôд премијум SMS-а.<p><b>Ако се пошаље порука на ово одредиште, биће вам наплаћена премијум услуга са налога за мобилни уређај.</b><p>Желите ли да дозволите овој апликацији да пошаље поруку?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Пошаљи поруку"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не шаљи"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Пријави злонамерну апликацију"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM картица је уклоњена"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мобилна мрежа неће бити доступна док не покренете систем поново уз уметање важеће SIM картице."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Звучници базне станице"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Систем"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth аудио"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4e10801..ad141a7 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> skickar ett stort antal SMS. Vill du tillåta att appen fortsätter att skicka meddelanden?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Tillåt"</string>
<string name="sms_control_no" msgid="625438561395534982">"Neka"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Skicka SMS till kortkod?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Skicka premium-SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vill skicka ett SMS till <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> som verkar vara en kortkod för SMS.<p>När du skickar SMS till kortkoder kan mobilkontot debiteras för premiumtjänster.<p>Vill du tillåta att appen skickar meddelandet?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vill skicka ett SMS till <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> som är en kortkod för SMS.<p><b>Om du skickar ett meddelande till den här mottagaren kommer ditt mobilkonto att debiteras för premiumtjänster.</b><p>Vill du tillåta att appen skickar meddelandet?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Skicka meddelande"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Skicka inte"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Rapportera skadlig app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kortet togs bort"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Det mobila nätverket kommer inte att vara tillgängligt förrän du startar om med ett giltigt SIM-kort."</string>
<string name="sim_done_button" msgid="827949989369963775">"Klar"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockningsstationens högtalare"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ljud"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ljud"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klar"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5701a00..1ac94da 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -934,8 +934,10 @@
<string name="deleteText" msgid="7070985395199629156">"futa"</string>
<string name="inputMethod" msgid="1653630062304567879">"Mbinu ya uingizaji"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Vitendo vya maandishi"</string>
- <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhafadhi inakwisha"</string>
- <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Baadhi ya vipengee vya mfumo huenda visifanye kazi"</string>
+ <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
+ <skip />
+ <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
+ <skip />
<string name="ok" msgid="5970060430562524910">"Sawa"</string>
<string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
<string name="yes" msgid="5362982303337969312">"Sawa"</string>
@@ -1033,6 +1035,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> inatuma idadi kubwa ya jumbe za SMS. Je, unataka kuruhusu programu hii kuendelea kutuma jumbe?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Ruhusu"</string>
<string name="sms_control_no" msgid="625438561395534982">"Kataza"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Tuma SMS kwa msimbo mfupi?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Tuma SMS ya ada?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ingependa kutuma ujumbe kwa <b>i<xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ambayo inaonekana kama msimbo mfupi wa ujumbe mfupi.<p>Kutuma ujumbe mfupi kwa baadhi ya misimbo mifupi kunaweza kusababisha akaunti yako ya simu kulipishwa huduma ya ada.<p>Je, unataka kuruhusu programu hii kutuma ujumbe?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingetaka kutuma ujumbe wa maandishi kwa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, ambayo ni msimbo mfupi wa SMS ya ada.<p><b>Kutuma ujumbe mahali hapa kutasababisha akaunti yako ya simu kulipishwa kwa huduma ya ada.</b><p>Je, unataka kuruhusu programu hii kutuma ujumbe?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Tuma ujumbe"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Usitume"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Ripoti programu hasidi"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kadi ya SIM imeondolewa"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"mtandao wa simu hutapatika hadi uanzishe upya na SIM kadi halali iliyoingizwa."</string>
<string name="sim_done_button" msgid="827949989369963775">"Kwisha"</string>
@@ -1289,5 +1298,6 @@
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Sauti ya HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Mfumo"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string>
- <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kwisha"</string>
+ <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b6b3c88..e33f866 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> กำลังส่งข้อความ SMS จำนวนมาก คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความต่อหรือไม่"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"อนุญาต"</string>
<string name="sms_control_no" msgid="625438561395534982">"ปฏิเสธ"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"ส่ง SMS เป็นรหัสสั้นหรือไม่"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"ส่ง SMS พรีเมียมหรือไม่"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ต้องการส่งข้อความให้กับ <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ซึ่งเป็น SMS รหัสสั้น<p>การส่งข้อความเป็นรหัสสั้นบางอย่างอาจทำให้มีการเรียกเก็บเงินในบัญชีมือถือของคุณสำหรับบริการพรีเมียม<p>คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความหรือไม่"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ต้องการส่งข้อความให้กับ <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ซึ่งเป็น SMS รหัสสั้นแบบพรีเมียม<p><b>การส่งข้อความไปยังปลายทางนี้จะทำให้มีการเรียกเก็บเงินในบัญชีมือถือของคุณสำหรับบริการพรีเมียม</b><p>คุณต้องการอนุญาตให้แอปพลิเคชันนี้ส่งข้อความหรือไม่"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"ส่งข้อความ"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"ไม่ส่ง"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"รายงานแอปที่เป็นอันตราย"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"นำซิมการ์ดออกแล้ว"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"เครือข่ายมือถือจะไม่สามารถใช้งานได้จนกว่าคุณจะรีสตาร์ทโดยใส่ซิมการ์ดที่ถูกต้องแล้ว"</string>
<string name="sim_done_button" msgid="827949989369963775">"เสร็จสิ้น"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ลำโพงแท่นชาร์จ"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"เสียง HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"ระบบ"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"เสียงบลูทูธ"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"เสร็จสิ้น"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 85ea80b..b3b0745 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay nagpapadala ng maraming mensaheng SMS. Gusto mo bang payagan ang app na ito na magpatuloy sa pagpapadala ng mga mensahe?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Payagan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Tanggihan"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Magpadala SMS sa short code?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Ipadala ang premium na SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay gustong magpadala ng text message sa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, na lumilitaw na isang SMS na short code.<p>Ang pagpapadala ng mga text message sa ilang short code ay maaaring magdulot ng pagsingil sa iyong mobile account para sa mga premium na serbisyo.<p>Gusto mo bang payagan ang app na ito na ipadala ang mensahe?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ay gustong magpadala ng text message sa <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, na isang premium na SMS na short code.<p><b>Ang pagpapadala ng mensahe sa patutunguhang ito ay magdudulot ng pagsingil sa iyong mobile account para sa mga premium na serbisyo.</b><p>Gusto mo bang payagan ang app na ito na ipadala ang mensahe?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Ipadala ang mensahe"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Huwag ipadala"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Mag-ulat ng nakakapahamak na app"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Naalis ang SIM card"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Hindi magiging available ang mobile network hanggang mag-restart ka gamit ang isang may-bisang SIM card"</string>
<string name="sim_done_button" msgid="827949989369963775">"Tapos na"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Mga speaker ng dock"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio sa Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 697bce6..02e10f8 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> çok sayıda SMS mesajı gönderiyor. Bu uygulamanın mesaj göndermeye devam etmesine izin veriyor musunuz?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"İzin ver"</string>
<string name="sms_control_no" msgid="625438561395534982">"Reddet"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Kısa koda SMS gönderilsin mi?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Premium SMS gönderilsin mi?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>, SMS kısa koduna sahip olduğu anlaşılan <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> hedefine bir kısa mesaj göndermek istiyor.<p>Bazı kısa kodlara kısa mesaj göndermek mobil hesabınızın premium hizmetle faturalandırılmasına neden olabilir.</b><p>Bu uygulamanın mesaj göndermesine izin vermek istiyor musunuz?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> premium SMS kısa koduna sahip <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> hedefine kısa mesaj göndermek istiyor.<p><b>Bu hedefe mesaj göndermek mobil hesabınızın premium hizmetle faturalandırılmasına neden olur.</b><p>Bu uygulamanın mesaj göndermesine izin vermek istiyor musunuz?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Mesajı gönder"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Gönderme"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Kötü amaçlı uygulamayı bildir"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM kart çıkarıldı"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Geçerli bir SIM kart yerleştirilmiş olarak yeniden başlatana kadar mobil ağ kullanılamayacak."</string>
<string name="sim_done_button" msgid="827949989369963775">"Tamamlandı"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Yuva hoparlörleri"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ses"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ses"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 9dd7c73..8742590 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> надсилає велику кількість SMS-повідомлень. Дозволити цій програмі й надалі надсилати повідомлення?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Дозволити"</string>
<string name="sms_control_no" msgid="625438561395534982">"Відмовити"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Надіслати SMS на короткий код?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Надіслати спеціальне SMS?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> хоче надіслати текстове повідомлення на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, яка є коротким кодом SMS.<p><b>Якщо надсилати текстові повідомлення на певні короткі коди, з вашого мобільного рахунку буде стягнено плату за спеціальні послуги.</b><p>Дозволити цій програмі надіслати повідомлення?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"Програма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> хоче надіслати текстове повідомлення на адресу <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, яка є коротким кодом спеціальних SMS.<p><b>Якщо надіслати повідомлення на цю адресу, з вашого мобільного рахунку буде стягнено плату за спеціальні послуги.</b><p>Дозволити цій програмі надіслати повідомлення?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Надіслати повідомлення"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Не надсилати"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Повідом. про шкідливу програму"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карту вилучено"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мобільна мережа буде недоступна, поки ви не здійсните перезапуск, вставивши дійсну SIM-карту."</string>
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 925d06b..1f10e3b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> đang gửi rất nhiều tin nhắn SMS. Bạn có muốn cho phép ứng dụng này tiếp tục gửi tin nhắn không?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Cho phép"</string>
<string name="sms_control_no" msgid="625438561395534982">"Từ chối"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Gửi SMS cho mã ngắn?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Gửi tin nhắn SMS trả phí?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> muốn gửi tin nhắn văn bản cho <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, dường như là một mã ngắn SMS.<p>Việc gửi tin nhắn văn bản cho một số mã ngắn có thể khiến cho tài khoản di động của bạn bị lập hóa đơn cho dịch vụ trả phí.<p>Bạn có muốn cho phép ứng dụng này gửi tin nhắn không?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> muốn gửi tin nhắn văn bản cho <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, là một mã ngắn SMS trả phí.<p><b>Gửi tin nhắn tới địa chỉ này sẽ khiến cho tài khoản di động của bạn bị lập hóa đơn cho dịch vụ trả phí.</b><p>Bạn có muốn cho phép ứng dụng này gửi tin nhắn không?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Gửi tin nhắn"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Không gửi"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Báo cáo ứng dụng độc hại"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Đã xóa thẻ SIM"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Mạng di động sẽ không khả dụng cho đến khi bạn khởi động lại với thẻ SIM hợp lệ được lắp."</string>
<string name="sim_done_button" msgid="827949989369963775">"Xong"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Loa đế"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Âm thanh HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Hệ thống"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Âm thanh Bluetooth"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Xong"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6b915ae..639bc03 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>在发送大量短信。是否允许该应用继续发送短信?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"允许"</string>
<string name="sms_control_no" msgid="625438561395534982">"拒绝"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"是否向短码发送短信?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"是否发送付费短信?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>想要向 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(这似乎是一个短信短码)发送短信。<p>向某些短码发送短信可能会导致您的移动帐户因使用付费服务而扣费。<p>是否允许该应用发送短信?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>想要向 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>(这是一个付费短信短码)发送短信。<p><b>向该地址发送短信会导致您的移动帐户因使用付费服务而扣费</b>。<p>是否允许该应用发送短信?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"发送短信"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"不发送"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"举报恶意应用"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"已移除 SIM 卡"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"移动网络不可用。请插入有效的 SIM 卡并重新启动。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完成"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"基座扬声器"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音频"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系统"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"蓝牙音频"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 546d039..b43e2c5 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在傳送大量簡訊。您要允許這個應用程式繼續傳送簡訊嗎?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"允許"</string>
<string name="sms_control_no" msgid="625438561395534982">"拒絕"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"傳送簡訊給短碼?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"傳送付費簡訊?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」想要傳送簡訊給簡訊短碼 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>。<p>將簡訊傳送給對方之後,系統即會從您的行動帳戶收取付費服務的費用。<p>您要允許這個應用程式傳送簡訊嗎?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"<b></b>「<xliff:g id="APP_NAME">%1$s</xliff:g>」想要傳送簡訊給付費簡訊短碼 <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>。<p><b>將簡訊傳送給對方之後,系統即會從您的行動帳戶收取付費服務的費用。</b><p>您要允許這個應用程式傳送簡訊嗎?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"傳送簡訊"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"不要傳送"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"檢舉惡意應用程式"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM 卡已移除"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"您必須先插入有效的 SIM 卡再重新啟動手機,才能使用行動網路。"</string>
<string name="sim_done_button" msgid="827949989369963775">"完成"</string>
@@ -1288,6 +1295,7 @@
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"座架喇叭"</string>
<string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音訊"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"系統"</string>
- <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"藍牙音訊"</string>
+ <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+ <skip />
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6f16ab5..c0c798d 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1033,6 +1033,13 @@
<string name="sms_control_message" msgid="3867899169651496433">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithumela inombolo enkulu yemilayezo ye-SMS. Ufuna ukuvumela lolu hlelo lokusebenza ukuqhubeka ukuthumela imilayezo?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Vumela"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nqaba"</string>
+ <string name="sms_short_code_confirm_title" msgid="1666863092640877318">"Thumela i-SMS kukhodi emfushane?"</string>
+ <string name="sms_premium_short_code_confirm_title" msgid="3811263856304367838">"Ukuthumela i-SMS ye-premium?"</string>
+ <string name="sms_short_code_confirm_message" msgid="5616409294907295407">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okubonakala sengathi ikhodi ye-SMS emfushane.<p>Ukuthumela umlayezo wombhalo kungabangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.<p>Ufuna ukuvumela uhlelo lokusebenza ukuthumela umlayezo?"</string>
+ <string name="sms_premium_short_code_confirm_message" msgid="6214083016284738667">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithanda ukuthumela umlayezo wombhalo ku-<b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>, okuyikhodi emfushane ye-SMS ye-premium.<p><b>Ukuthumela umlayezo kule ndawo kuzobangela i-akhawunti yeselula yakho ukuthi ikhokheliswe amasevisi e-premium.</b><p>Ufuna ukuvumela lolu hlelo lokusebenza ukuthumela umlayezo?"</string>
+ <string name="sms_short_code_confirm_allow" msgid="8957573662645722940">"Thumela umlayezo"</string>
+ <string name="sms_short_code_confirm_deny" msgid="6374609298084435887">"Ungathumeli"</string>
+ <string name="sms_short_code_confirm_report" msgid="2588793956061677070">"Bika uhlelo lokusebenza olungalungile"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Ikhadi le-SIM likhishiwe"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Inethiwekhi yeselula ngeke itholakale kuwena kuze kube uqala kabusha ufake ikhadi le-SIM elifanele."</string>
<string name="sim_done_button" msgid="827949989369963775">"Kwenziwe"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f623d48..254561c 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -65,6 +65,11 @@
master volume stream and nothing else . -->
<bool name="config_useMasterVolume">false</bool>
+ <!-- Flag indicating that the media framework should support playing of sounds on volume
+ key usage. This adds noticeable additional overhead to volume key processing, so
+ is disableable for products for which it is irrelevant. -->
+ <bool name="config_useVolumeKeySounds">true</bool>
+
<!-- Array of integer pairs controlling the rate at which the master volume changes
in response to volume up and down key events.
The first integer of each pair is compared against the current master volume
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 946bfe6..a82df87 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -260,6 +260,7 @@
<java-symbol type="bool" name="skip_restoring_network_selection" />
<java-symbol type="bool" name="split_action_bar_is_narrow" />
<java-symbol type="bool" name="config_useMasterVolume" />
+ <java-symbol type="bool" name="config_useVolumeKeySounds" />
<java-symbol type="bool" name="config_enableWallpaperService" />
<java-symbol type="bool" name="config_sendAudioBecomingNoisy" />
<java-symbol type="bool" name="config_enableScreenshotChord" />
@@ -814,6 +815,13 @@
<java-symbol type="string" name="sms_control_title" />
<java-symbol type="string" name="sms_control_no" />
<java-symbol type="string" name="sms_control_yes" />
+ <java-symbol type="string" name="sms_premium_short_code_confirm_message" />
+ <java-symbol type="string" name="sms_premium_short_code_confirm_title" />
+ <java-symbol type="string" name="sms_short_code_confirm_allow" />
+ <java-symbol type="string" name="sms_short_code_confirm_deny" />
+ <java-symbol type="string" name="sms_short_code_confirm_message" />
+ <java-symbol type="string" name="sms_short_code_confirm_report" />
+ <java-symbol type="string" name="sms_short_code_confirm_title" />
<java-symbol type="string" name="submit" />
<java-symbol type="string" name="sync_binding_label" />
<java-symbol type="string" name="sync_do_nothing" />
@@ -1138,6 +1146,7 @@
<java-symbol type="xml" name="password_kbd_symbols_shift" />
<java-symbol type="xml" name="power_profile" />
<java-symbol type="xml" name="time_zones_by_country" />
+ <java-symbol type="xml" name="sms_short_codes" />
<java-symbol type="raw" name="accessibility_gestures" />
<java-symbol type="raw" name="incognito_mode_start_page" />
@@ -3649,4 +3658,16 @@
<public type="style" name="Widget.DeviceDefault.MediaRouteButton" id="0x010301d7" />
<public type="style" name="Widget.DeviceDefault.Light.MediaRouteButton" id="0x010301d8" />
+<!-- ===============================================================
+ Resources added in version 17 of the platform (Jelly Bean MRx?)
+ =============================================================== -->
+ <public type="attr" name="supportsRtl" id="0x010103ae" />
+ <public type="attr" name="textDirection"/>
+ <public type="attr" name="textAlignment"/>
+ <public type="attr" name="layoutDirection" />
+ <public type="attr" name="paddingStart"/>
+ <public type="attr" name="paddingEnd"/>
+ <public type="attr" name="layout_marginStart"/>
+ <public type="attr" name="layout_marginEnd"/>
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index da4d37a..269e10b 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2923,6 +2923,22 @@
<!-- See SMS_DIALOG. This is a button choice to disallow sending the SMSes. [CHAR LIMIT=30] -->
<string name="sms_control_no">Deny</string>
+ <!-- SMS short code verification dialog. --> <skip />
+ <!-- The dialog title for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_title">Send SMS to short code?</string>
+ <!-- The dialog title for the SMS premium short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_premium_short_code_confirm_title">Send premium SMS?</string>
+ <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+ <string name="sms_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which appears to be an SMS short code.<p>Sending text messages to some short codes may cause your mobile account to be billed for premium services.<p>Do you want to allow this app to send the message?</string>
+ <!-- The message text for the SMS short code confirmation dialog. [CHAR LIMIT=NONE] -->
+ <string name="sms_premium_short_code_confirm_message"><b><xliff:g id="app_name">%1$s</xliff:g></b> would like to send a text message to <b><xliff:g id="dest_address">%2$s</xliff:g></b>, which is a premium SMS short code.<p><b>Sending a message to this destination will cause your mobile account to be billed for premium services.</b><p>Do you want to allow this app to send the message?</string>
+ <!-- Text of the approval button for the SMS short code confirmation dialog. [CHAR LIMIT=50] -->
+ <string name="sms_short_code_confirm_allow">Send message</string>
+ <!-- Text of the cancel button for the SMS short code confirmation dialog. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_deny">Don\'t send</string>
+ <!-- Text of the button for the SMS short code confirmation dialog to report a malicious app. [CHAR LIMIT=30] -->
+ <string name="sms_short_code_confirm_report">Report malicious app</string>
+
<!-- SIM swap and device reboot Dialog --> <skip />
<!-- See SIM_REMOVED_DIALOG. This is the title of that dialog. -->
<string name="sim_removed_title">SIM card removed</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 889f86f..46fd7da 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -343,17 +343,14 @@
</style>
<style name="Widget.CompoundButton.CheckBox">
- <item name="android:background">@android:drawable/btn_check_label_background</item>
<item name="android:button">?android:attr/listChoiceIndicatorMultiple</item>
</style>
<style name="Widget.CompoundButton.RadioButton">
- <item name="android:background">@android:drawable/btn_radio_label_background</item>
<item name="android:button">?android:attr/listChoiceIndicatorSingle</item>
</style>
<style name="Widget.CompoundButton.Star">
- <item name="android:background">@android:drawable/btn_star_label_background</item>
<item name="android:button">@android:drawable/btn_star</item>
</style>
@@ -1772,7 +1769,7 @@
<item name="android:dropDownHorizontalOffset">0dip</item>
<item name="android:dropDownWidth">wrap_content</item>
<item name="android:popupPromptView">@android:layout/simple_dropdown_hint</item>
- <item name="android:gravity">left|center_vertical</item>
+ <item name="android:gravity">start|center_vertical</item>
<item name="android:disableChildrenWhenDisabled">true</item>
</style>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 30312b3..7af3b9c 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -18,37 +18,44 @@
-->
<device name="Android">
- <!-- All values are in mAh except as noted -->
+ <!-- Most values are the incremental current used by a feature,
+ in mA (measured at nominal voltage).
+ The default values are deliberately incorrect dummy values.
+ OEM's must measure and provide actual values before
+ shipping a device.
+ Example real-world values are given in comments, but they
+ are totally dependent on the platform and can vary
+ significantly, so should be measured on the shipping platform
+ with a power meter. -->
<item name="none">0</item>
- <item name="screen.on">0.1</item>
- <item name="bluetooth.active">0.1</item>
- <item name="bluetooth.on">0.1</item>
- <item name="screen.full">0.1</item>
- <item name="wifi.on">0.1</item>
- <item name="wifi.active">0.1</item>
- <item name="wifi.scan">0.1</item>
- <item name="dsp.audio">0.1</item>
- <item name="dsp.video">0.1</item>
- <item name="radio.active">1</item>
- <!-- The current consumed by the radio when it is scanning for a signal -->
- <item name="radio.scanning">0.5</item>
- <item name="gps.on">1</item>
+ <item name="screen.on">0.1</item> <!-- ~200mA -->
+ <item name="screen.full">0.1</item> <!-- ~300mA -->
+ <item name="bluetooth.active">0.1</item> <!-- Bluetooth data transfer, ~10mA -->
+ <item name="bluetooth.on">0.1</item> <!-- Bluetooth on & connectable, but not connected, ~0.1mA -->
+ <item name="wifi.on">0.1</item> <!-- ~3mA -->
+ <item name="wifi.active">0.1</item> <!-- WIFI data transfer, ~200mA -->
+ <item name="wifi.scan">0.1</item> <!-- WIFI network scanning, ~100mA -->
+ <item name="dsp.audio">0.1</item> <!-- ~10mA -->
+ <item name="dsp.video">0.1</item> <!-- ~50mA -->
+ <item name="radio.active">0.1</item> <!-- ~200mA -->
+ <item name="radio.scanning">0.1</item> <!-- cellular radio scanning for signal, ~10mA -->
+ <item name="gps.on">0.1</item> <!-- ~50mA -->
<!-- Current consumed by the radio at different signal strengths, when paging -->
<array name="radio.on"> <!-- Strength 0 to BINS-1 -->
- <value>0.2</value>
- <value>0.1</value>
+ <value>0.2</value> <!-- ~2mA -->
+ <value>0.1</value> <!-- ~1mA -->
</array>
<!-- Different CPU speeds as reported in
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state -->
<array name="cpu.speeds">
<value>400000</value> <!-- 400 MHz CPU speed -->
</array>
- <!-- Power consumption when CPU is idle -->
+ <!-- Current when CPU is idle -->
<item name="cpu.idle">0.1</item>
- <!-- Power consumption at different speeds -->
+ <!-- Current at each CPU speed, as per 'cpu.speeds' -->
<array name="cpu.active">
- <value>0.2</value>
+ <value>0.1</value> <!-- ~100mA -->
</array>
- <!-- This is the battery capacity in mAh -->
+ <!-- This is the battery capacity in mAh (measured at nominal voltage) -->
<item name="battery.capacity">1000</item>
</device>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
new file mode 100644
index 0000000..8b395af
--- /dev/null
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Regex patterns for SMS short codes by country. -->
+<shortcodes>
+
+ <!-- The country attribute is the ISO country code of the user's account (from SIM card or NV).
+ The pattern attribute is a regex that matches all SMS short codes for the country.
+ The premium attribute is a regex that matches premium rate SMS short codes.
+ The free attribute matches short codes that we know will not cost the user, such as
+ emergency numbers. The standard attribute matches short codes that are billed at the
+ standard SMS rate. The user is warned when the destination phone number matches the
+ "pattern" or "premium" regexes, and does not match the "free" or "standard" regexes. -->
+
+ <!-- Harmonised European Short Codes are 6 digit numbers starting with 116 (free helplines).
+ Premium patterns include short codes from: http://aonebill.com/coverage&tariffs
+ and http://mobilcent.com/info-worldwide.asp and extracted from:
+ http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
+
+ <!-- Albania: 5 digits, known short codes listed -->
+ <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
+
+ <!-- Armenia: 3-4 digits, emergency numbers 10[123] -->
+ <shortcode country="am" pattern="\\d{3,4}" premium="11[2456]1|3024" free="10[123]" />
+
+ <!-- Austria: 10 digits, premium prefix 09xx, plus EU -->
+ <shortcode country="at" pattern="11\\d{4}" premium="09.*" free="116\\d{3}" />
+
+ <!-- Australia: 6 or 8 digits starting with "19" -->
+ <shortcode country="au" pattern="19(?:\\d{4}|\\d{6})" premium="19998882" />
+
+ <!-- Azerbaijan: 4-5 digits, known premium codes listed -->
+ <shortcode country="az" pattern="\\d{4,5}" premium="330[12]|87744|901[234]|93(?:94|101)|9426|9525" />
+
+ <!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
+ <shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
+
+ <!-- Bulgaria: 4-5 digits, plus EU -->
+ <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}" />
+
+ <!-- Belarus: 4 digits -->
+ <shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
+
+ <!-- Canada: 5-6 digits -->
+ <shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188" />
+
+ <!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
+ <shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111" />
+
+ <!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
+ http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
+ <shortcode country="cn" premium="1066.*" free="1065.*" />
+
+ <!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
+ <shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
+
+ <!-- Czech Republic: 7-8 digits, starting with 9, plus EU:
+ http://www.o2.cz/osobni/en/services-by-alphabet/91670-premium_sms.html -->
+ <shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
+
+ <!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
+ <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}" />
+
+ <!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
+ <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
+
+ <!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU.
+ http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
+ <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}" />
+
+ <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
+ http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
+ <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}" />
+
+ <!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
+ <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}" />
+
+ <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
+ http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements -->
+ <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" />
+
+ <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
+ http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf -->
+ <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" />
+
+ <!-- Georgia: 4 digits, known premium codes listed -->
+ <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
+
+ <!-- Greece: 5 digits (54xxx, 19yxx, x=0-9, y=0-5): http://www.cmtelecom.com/premium-sms/greece -->
+ <shortcode country="gr" pattern="\\d{5}" premium="54\\d{3}|19[0-5]\\d{2}" free="116\\d{3}" />
+
+ <!-- Hungary: 4 or 10 digits starting with 1 or 0, plus EU:
+ http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations -->
+ <shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" />
+
+ <!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
+ http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
+ <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" />
+
+ <!-- Israel: 4 digits, known premium codes listed -->
+ <shortcode country="il" pattern="\\d{4}" premium="4422|4545" />
+
+ <!-- Italy: 5 digits (premium=4xxxx), plus EU:
+ http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
+ <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
+
+ <!-- Kyrgyzstan: 4 digits, known premium codes listed -->
+ <shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
+
+ <!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
+ <shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
+
+ <!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
+ <shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}" />
+
+ <!-- Luxembourg: 5 digits, 6xxxx, plus EU:
+ http://www.luxgsm.lu/assets/files/filepage/file_1253803400.pdf -->
+ <shortcode country="lu" premium="6\\d{4}" free="116\\d{3}" />
+
+ <!-- Latvia: 4 digits, known premium codes listed, plus EU -->
+ <shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}" />
+
+ <!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
+ <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" />
+
+ <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
+ <shortcode country="my" pattern="\\d{5}" premium="32298|33776" />
+
+ <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
+ <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}" />
+
+ <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
+ <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
+
+ <!-- New Zealand: 3-4 digits, known premium codes listed -->
+ <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995" />
+
+ <!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
+ <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}" />
+
+ <!-- Portugal: 5 digits, plus EU:
+ http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
+ <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}" />
+
+ <!-- Romania: 4 digits, plus EU: http://www.simplus.ro/en/resources/glossary-of-terms/ -->
+ <shortcode country="ro" pattern="\\d{4}" premium="12(?:63|66|88)|13(?:14|80)" free="116\\d{3}" />
+
+ <!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
+ <shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)" />
+
+ <!-- Sweden: 5 digits (72xxx), plus EU: http://www.viatel.se/en/premium-sms/ -->
+ <shortcode country="se" premium="72\\d{3}" free="116\\d{3}" />
+
+ <!-- Singapore: 5 digits: http://clients.txtnation.com/entries/306442-singapore-premium-sms-short-code-requirements
+ Free government directory info at 74688: http://app.sgdi.gov.sg/sms_help.asp -->
+ <shortcode country="sg" pattern="7\\d{4}" premium="73800" standard="74688" />
+
+ <!-- Slovenia: 4 digits (premium=3xxx, 6xxx, 8xxx), plus EU: http://www.cmtelecom.com/premium-sms/slovenia -->
+ <shortcode country="si" pattern="\\d{4}" premium="[368]\\d{3}" free="116\\d{3}" />
+
+ <!-- Slovakia: 4 digits (premium), plus EU: http://www.cmtelecom.com/premium-sms/slovakia -->
+ <shortcode country="sk" premium="\\d{4}" free="116\\d{3}" />
+
+ <!-- Tajikistan: 4 digits, known premium codes listed -->
+ <shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
+
+ <!-- Ukraine: 4 digits, known premium codes listed -->
+ <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
+
+ <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) -->
+ <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" />
+
+</shortcodes>
diff --git a/core/tests/coretests/src/android/app/InstrumentationTest.java b/core/tests/coretests/src/android/app/InstrumentationTest.java
new file mode 100644
index 0000000..ee3834c
--- /dev/null
+++ b/core/tests/coretests/src/android/app/InstrumentationTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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 android.app;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestCase;
+
+public class InstrumentationTest extends InstrumentationTestCase {
+
+ /**
+ * Simple stress test for {@link Instrumentation#sendStatus(int, android.os.Bundle)}, to
+ * ensure it can handle many rapid calls without failing.
+ */
+ public void testSendStatus() {
+ for (int i = 0; i < 10000; i++) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("iterations", i);
+ getInstrumentation().sendStatus(-1, bundle);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/app/SearchablesTest.java b/core/tests/coretests/src/android/app/SearchablesTest.java
index 6cb31d4..4d3b144 100644
--- a/core/tests/coretests/src/android/app/SearchablesTest.java
+++ b/core/tests/coretests/src/android/app/SearchablesTest.java
@@ -71,7 +71,7 @@
*/
public void testNonSearchable() {
// test basic array & hashmap
- Searchables searchables = new Searchables(mContext);
+ Searchables searchables = new Searchables(mContext, 0);
searchables.buildSearchableList();
// confirm that we return null for non-searchy activities
@@ -103,7 +103,7 @@
// build item list with real-world source data
mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH);
- Searchables searchables = new Searchables(mockContext);
+ Searchables searchables = new Searchables(mockContext, 0);
searchables.buildSearchableList();
// tests with "real" searchables (deprecate, this should be a unit test)
ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
@@ -122,7 +122,7 @@
MyMockContext mockContext = new MyMockContext(mContext, mockPM);
mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO);
- Searchables searchables = new Searchables(mockContext);
+ Searchables searchables = new Searchables(mockContext, 0);
searchables.buildSearchableList();
ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
assertNotNull(searchablesList);
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index ab6b2b6..418bbd6 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -24,7 +24,7 @@
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
-import com.android.internal.util.StateMachine.ProcessedMessageInfo;
+import com.android.internal.util.StateMachine.LogRec;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -36,6 +36,10 @@
* Test for StateMachine.
*/
public class StateMachineTest extends TestCase {
+ private static final String ENTER = "enter";
+ private static final String EXIT = "exit";
+ private static final String ON_QUITTING = "ON_QUITTING";
+
private static final int TEST_CMD_1 = 1;
private static final int TEST_CMD_2 = 2;
private static final int TEST_CMD_3 = 3;
@@ -47,11 +51,18 @@
private static final boolean WAIT_FOR_DEBUGGER = false;
private static final String TAG = "StateMachineTest";
+ private void sleep(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch(InterruptedException e) {
+ }
+ }
+
/**
- * Tests that we can quit the state machine.
+ * Tests {@link StateMachine#quit()}.
*/
class StateMachineQuitTest extends StateMachine {
- private int mQuitCount = 0;
+ Object mWaitUntilTestDone = new Object();
StateMachineQuitTest(String name) {
super(name);
@@ -65,29 +76,45 @@
setInitialState(mS1);
}
- class S1 extends State {
- @Override
- public boolean processMessage(Message message) {
- if (isQuit(message)) {
- mQuitCount += 1;
- if (mQuitCount > 2) {
- // Returning NOT_HANDLED to actually quit
- return NOT_HANDLED;
- } else {
- // Do NOT quit
- return HANDLED;
- }
- } else {
- // All other message are handled
- return HANDLED;
+ @Override
+ public void onQuitting() {
+ Log.d(TAG, "onQuitting");
+ addLogRec(ON_QUITTING);
+ synchronized (mThisSm) {
+ mThisSm.notifyAll();
+ }
+
+ // Don't leave onQuitting before the test is done as everything is cleared
+ // including the log records.
+ synchronized (mWaitUntilTestDone) {
+ try {
+ mWaitUntilTestDone.wait();
+ } catch(InterruptedException e) {
}
}
}
- @Override
- protected void quitting() {
- synchronized (mThisSm) {
- mThisSm.notifyAll();
+ class S1 extends State {
+ public void exit() {
+ Log.d(TAG, "S1.exit");
+ addLogRec(EXIT, mS1);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ switch(message.what) {
+ // Sleep and assume the other messages will be queued up.
+ case TEST_CMD_1: {
+ Log.d(TAG, "TEST_CMD_1");
+ sleep(500);
+ quit();
+ break;
+ }
+ default: {
+ Log.d(TAG, "default what=" + message.what);
+ break;
+ }
+ }
+ return HANDLED;
}
}
@@ -96,62 +123,167 @@
}
@SmallTest
- public void testStateMachineQuitTest() throws Exception {
+ public void testStateMachineQuit() throws Exception {
if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
smQuitTest.start();
- if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest E");
+ if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
synchronized (smQuitTest) {
- // Send 6 messages
+
+ // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
for (int i = 1; i <= 6; i++) {
- smQuitTest.sendMessage(i);
+ smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
}
- // First two are ignored
- smQuitTest.quit();
- smQuitTest.quit();
-
- // Now we will quit
- smQuitTest.quit();
-
try {
// wait for the messages to be handled
smQuitTest.wait();
} catch (InterruptedException e) {
- Log.e(TAG, "testStateMachineQuitTest: exception while waiting " + e.getMessage());
+ Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
}
}
- assertTrue(smQuitTest.getProcessedMessagesCount() == 9);
+ assertEquals(8, smQuitTest.getLogRecCount());
- ProcessedMessageInfo pmi;
+ LogRec lr;
- // The first two message didn't quit and were handled by mS1
- pmi = smQuitTest.getProcessedMessageInfo(6);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(smQuitTest.mS1, pmi.getState());
- assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+ for (int i = 0; i < 6; i++) {
+ lr = smQuitTest.getLogRec(i);
+ assertEquals(i+1, lr.getWhat());
+ assertEquals(smQuitTest.mS1, lr.getState());
+ assertEquals(smQuitTest.mS1, lr.getOriginalState());
+ }
+ lr = smQuitTest.getLogRec(6);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smQuitTest.mS1, lr.getState());
- pmi = smQuitTest.getProcessedMessageInfo(7);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(smQuitTest.mS1, pmi.getState());
- assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+ lr = smQuitTest.getLogRec(7);
+ assertEquals(ON_QUITTING, lr.getInfo());
- // The last message was never handled so the states are null
- pmi = smQuitTest.getProcessedMessageInfo(8);
- assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
- assertEquals(null, pmi.getState());
- assertEquals(null, pmi.getOriginalState());
+ synchronized (smQuitTest.mWaitUntilTestDone) {
+ smQuitTest.mWaitUntilTestDone.notifyAll();
+ }
+ if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
+ }
- if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest X");
+ /**
+ * Tests {@link StateMachine#quitNow()}
+ */
+ class StateMachineQuitNowTest extends StateMachine {
+ Object mWaitUntilTestDone = new Object();
+
+ StateMachineQuitNowTest(String name) {
+ super(name);
+ mThisSm = this;
+ setDbg(DBG);
+
+ // Setup state machine with 1 state
+ addState(mS1);
+
+ // Set the initial state
+ setInitialState(mS1);
+ }
+
+ @Override
+ public void onQuitting() {
+ Log.d(TAG, "onQuitting");
+ addLogRec(ON_QUITTING);
+ synchronized (mThisSm) {
+ mThisSm.notifyAll();
+ }
+
+ // Don't leave onQuitting before the test is done as everything is cleared
+ // including the log records.
+ synchronized (mWaitUntilTestDone) {
+ try {
+ mWaitUntilTestDone.wait();
+ } catch(InterruptedException e) {
+ }
+ }
+ }
+
+ class S1 extends State {
+ public void exit() {
+ Log.d(TAG, "S1.exit");
+ addLogRec(EXIT, mS1);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ switch(message.what) {
+ // Sleep and assume the other messages will be queued up.
+ case TEST_CMD_1: {
+ Log.d(TAG, "TEST_CMD_1");
+ sleep(500);
+ quitNow();
+ break;
+ }
+ default: {
+ Log.d(TAG, "default what=" + message.what);
+ break;
+ }
+ }
+ return HANDLED;
+ }
+ }
+
+ private StateMachineQuitNowTest mThisSm;
+ private S1 mS1 = new S1();
+ }
+
+ @SmallTest
+ public void testStateMachineQuitNow() throws Exception {
+ if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+
+ StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
+ smQuitNowTest.start();
+ if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
+
+ synchronized (smQuitNowTest) {
+
+ // Send 6 messages but we'll QuitNow on the first so even though
+ // we send 6 only one will be processed.
+ for (int i = 1; i <= 6; i++) {
+ smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
+ }
+
+ try {
+ // wait for the messages to be handled
+ smQuitNowTest.wait();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
+ }
+ }
+
+ // Only three records because we executed quitNow.
+ assertEquals(3, smQuitNowTest.getLogRecCount());
+
+ LogRec lr;
+
+ lr = smQuitNowTest.getLogRec(0);
+ assertEquals(1, lr.getWhat());
+ assertEquals(smQuitNowTest.mS1, lr.getState());
+ assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
+
+ lr = smQuitNowTest.getLogRec(1);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smQuitNowTest.mS1, lr.getState());
+
+ lr = smQuitNowTest.getLogRec(2);
+ assertEquals(ON_QUITTING, lr.getInfo());
+
+ synchronized (smQuitNowTest.mWaitUntilTestDone) {
+ smQuitNowTest.mWaitUntilTestDone.notifyAll();
+ }
+ if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
}
/**
* Test enter/exit can use transitionTo
*/
class StateMachineEnterExitTransitionToTest extends StateMachine {
+
StateMachineEnterExitTransitionToTest(String name) {
super(name);
mThisSm = this;
@@ -170,20 +302,15 @@
class S1 extends State {
@Override
public void enter() {
- // Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- // Test that a transition in enter and the initial state works
- mS1EnterCount += 1;
+ // Test transitions in enter on the initial state work
+ addLogRec(ENTER, mS1);
transitionTo(mS2);
Log.d(TAG, "S1.enter");
}
@Override
public void exit() {
// Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- mS1ExitCount += 1;
+ addLogRec(EXIT, mS1);
Log.d(TAG, "S1.exit");
}
}
@@ -191,19 +318,15 @@
class S2 extends State {
@Override
public void enter() {
- // Test that message is HSM_INIT_CMD
- assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
- mS2EnterCount += 1;
+ addLogRec(ENTER, mS2);
Log.d(TAG, "S2.enter");
}
@Override
public void exit() {
- // Test that message is TEST_CMD_1
+ addLogRec(EXIT, mS2);
assertEquals(TEST_CMD_1, getCurrentMessage().what);
// Test transition in exit work
- mS2ExitCount += 1;
transitionTo(mS4);
Log.d(TAG, "S2.exit");
}
@@ -220,36 +343,33 @@
class S3 extends State {
@Override
public void enter() {
- // Test that we can do halting in an enter/exit
- transitionToHaltingState();
- mS3EnterCount += 1;
+ addLogRec(ENTER, mS3);
Log.d(TAG, "S3.enter");
}
@Override
public void exit() {
- mS3ExitCount += 1;
+ addLogRec(EXIT, mS3);
Log.d(TAG, "S3.exit");
}
}
-
class S4 extends State {
@Override
public void enter() {
+ addLogRec(ENTER, mS4);
// Test that we can do halting in an enter/exit
transitionToHaltingState();
- mS4EnterCount += 1;
Log.d(TAG, "S4.enter");
}
@Override
public void exit() {
- mS4ExitCount += 1;
+ addLogRec(EXIT, mS4);
Log.d(TAG, "S4.exit");
}
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -260,14 +380,6 @@
private S2 mS2 = new S2();
private S3 mS3 = new S3();
private S4 mS4 = new S4();
- private int mS1EnterCount = 0;
- private int mS1ExitCount = 0;
- private int mS2EnterCount = 0;
- private int mS2ExitCount = 0;
- private int mS3EnterCount = 0;
- private int mS3ExitCount = 0;
- private int mS4EnterCount = 0;
- private int mS4ExitCount = 0;
}
@SmallTest
@@ -293,24 +405,46 @@
}
}
- assertTrue(smEnterExitTranstionToTest.getProcessedMessagesCount() == 1);
+ assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
- ProcessedMessageInfo pmi;
+ LogRec lr;
- // Message should be handled by mS2.
- pmi = smEnterExitTranstionToTest.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(smEnterExitTranstionToTest.mS2, pmi.getState());
- assertEquals(smEnterExitTranstionToTest.mS2, pmi.getOriginalState());
+ lr = smEnterExitTranstionToTest.getLogRec(0);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
- assertEquals(smEnterExitTranstionToTest.mS1EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS1ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS2EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS2ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
- assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
+ lr = smEnterExitTranstionToTest.getLogRec(1);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(2);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(3);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(4);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(5);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(6);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(7);
+ assertEquals(ENTER, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+
+ lr = smEnterExitTranstionToTest.getLogRec(8);
+ assertEquals(EXIT, lr.getInfo());
+ assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
if (smEnterExitTranstionToTest.isDbg()) {
Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
@@ -325,7 +459,7 @@
super(name);
mThisSm = this;
setDbg(DBG);
- setProcessedMessagesSize(3);
+ setLogRecSize(3);
// Setup state machine with 1 state
addState(mS1);
@@ -345,7 +479,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -377,24 +511,24 @@
}
}
- assertTrue(sm0.getProcessedMessagesCount() == 6);
- assertTrue(sm0.getProcessedMessagesSize() == 3);
+ assertEquals(6, sm0.getLogRecCount());
+ assertEquals(3, sm0.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm0.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_4, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm0.getLogRec(0);
+ assertEquals(TEST_CMD_4, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
- pmi = sm0.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_5, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ lr = sm0.getLogRec(1);
+ assertEquals(TEST_CMD_5, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
- pmi = sm0.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_6, pmi.getWhat());
- assertEquals(sm0.mS1, pmi.getState());
- assertEquals(sm0.mS1, pmi.getOriginalState());
+ lr = sm0.getLogRec(2);
+ assertEquals(TEST_CMD_6, lr.getWhat());
+ assertEquals(sm0.mS1, lr.getState());
+ assertEquals(sm0.mS1, lr.getOriginalState());
if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
}
@@ -444,7 +578,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -479,18 +613,18 @@
assertEquals(2, sm1.mEnterCount);
assertEquals(2, sm1.mExitCount);
- assertTrue(sm1.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm1.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm1.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm1.mS1, pmi.getState());
- assertEquals(sm1.mS1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm1.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm1.mS1, lr.getState());
+ assertEquals(sm1.mS1, lr.getOriginalState());
- pmi = sm1.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm1.mS1, pmi.getState());
- assertEquals(sm1.mS1, pmi.getOriginalState());
+ lr = sm1.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm1.mS1, lr.getState());
+ assertEquals(sm1.mS1, lr.getOriginalState());
assertEquals(2, sm1.mEnterCount);
assertEquals(2, sm1.mExitCount);
@@ -550,7 +684,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -583,24 +717,24 @@
}
}
- assertTrue(sm2.getProcessedMessagesSize() == 4);
+ assertEquals(4, sm2.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm2.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm2.mS1, pmi.getState());
+ LogRec lr;
+ lr = sm2.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm2.mS1, lr.getState());
- pmi = sm2.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm2.mS1, pmi.getState());
+ lr = sm2.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm2.mS1, lr.getState());
- pmi = sm2.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm2.mS2, pmi.getState());
+ lr = sm2.getLogRec(2);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm2.mS2, lr.getState());
- pmi = sm2.getProcessedMessageInfo(3);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm2.mS2, pmi.getState());
+ lr = sm2.getLogRec(3);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm2.mS2, lr.getState());
assertTrue(sm2.mDidEnter);
assertTrue(sm2.mDidExit);
@@ -647,7 +781,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -677,18 +811,18 @@
}
}
- assertTrue(sm3.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm3.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm3.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm3.mParentState, pmi.getState());
- assertEquals(sm3.mChildState, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm3.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm3.mParentState, lr.getState());
+ assertEquals(sm3.mChildState, lr.getOriginalState());
- pmi = sm3.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm3.mParentState, pmi.getState());
- assertEquals(sm3.mChildState, pmi.getOriginalState());
+ lr = sm3.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm3.mParentState, lr.getState());
+ assertEquals(sm3.mChildState, lr.getOriginalState());
if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
}
@@ -742,7 +876,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -774,18 +908,18 @@
}
- assertTrue(sm4.getProcessedMessagesSize() == 2);
+ assertEquals(2, sm4.getLogRecSize());
- ProcessedMessageInfo pmi;
- pmi = sm4.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm4.mChildState1, pmi.getState());
- assertEquals(sm4.mChildState1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm4.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm4.mChildState1, lr.getState());
+ assertEquals(sm4.mChildState1, lr.getOriginalState());
- pmi = sm4.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm4.mParentState, pmi.getState());
- assertEquals(sm4.mChildState2, pmi.getOriginalState());
+ lr = sm4.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm4.mParentState, lr.getState());
+ assertEquals(sm4.mChildState2, lr.getOriginalState());
if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
}
@@ -1018,7 +1152,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1073,7 +1207,7 @@
}
- assertTrue(sm5.getProcessedMessagesSize() == 6);
+ assertEquals(6, sm5.getLogRecSize());
assertEquals(1, sm5.mParentState1EnterCount);
assertEquals(1, sm5.mParentState1ExitCount);
@@ -1090,36 +1224,36 @@
assertEquals(1, sm5.mChildState5EnterCount);
assertEquals(1, sm5.mChildState5ExitCount);
- ProcessedMessageInfo pmi;
- pmi = sm5.getProcessedMessageInfo(0);
- assertEquals(TEST_CMD_1, pmi.getWhat());
- assertEquals(sm5.mChildState1, pmi.getState());
- assertEquals(sm5.mChildState1, pmi.getOriginalState());
+ LogRec lr;
+ lr = sm5.getLogRec(0);
+ assertEquals(TEST_CMD_1, lr.getWhat());
+ assertEquals(sm5.mChildState1, lr.getState());
+ assertEquals(sm5.mChildState1, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(1);
- assertEquals(TEST_CMD_2, pmi.getWhat());
- assertEquals(sm5.mChildState2, pmi.getState());
- assertEquals(sm5.mChildState2, pmi.getOriginalState());
+ lr = sm5.getLogRec(1);
+ assertEquals(TEST_CMD_2, lr.getWhat());
+ assertEquals(sm5.mChildState2, lr.getState());
+ assertEquals(sm5.mChildState2, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(2);
- assertEquals(TEST_CMD_3, pmi.getWhat());
- assertEquals(sm5.mChildState5, pmi.getState());
- assertEquals(sm5.mChildState5, pmi.getOriginalState());
+ lr = sm5.getLogRec(2);
+ assertEquals(TEST_CMD_3, lr.getWhat());
+ assertEquals(sm5.mChildState5, lr.getState());
+ assertEquals(sm5.mChildState5, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(3);
- assertEquals(TEST_CMD_4, pmi.getWhat());
- assertEquals(sm5.mChildState3, pmi.getState());
- assertEquals(sm5.mChildState3, pmi.getOriginalState());
+ lr = sm5.getLogRec(3);
+ assertEquals(TEST_CMD_4, lr.getWhat());
+ assertEquals(sm5.mChildState3, lr.getState());
+ assertEquals(sm5.mChildState3, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(4);
- assertEquals(TEST_CMD_5, pmi.getWhat());
- assertEquals(sm5.mChildState4, pmi.getState());
- assertEquals(sm5.mChildState4, pmi.getOriginalState());
+ lr = sm5.getLogRec(4);
+ assertEquals(TEST_CMD_5, lr.getWhat());
+ assertEquals(sm5.mChildState4, lr.getState());
+ assertEquals(sm5.mChildState4, lr.getOriginalState());
- pmi = sm5.getProcessedMessageInfo(5);
- assertEquals(TEST_CMD_6, pmi.getWhat());
- assertEquals(sm5.mParentState2, pmi.getState());
- assertEquals(sm5.mParentState2, pmi.getOriginalState());
+ lr = sm5.getLogRec(5);
+ assertEquals(TEST_CMD_6, lr.getWhat());
+ assertEquals(sm5.mParentState2, lr.getState());
+ assertEquals(sm5.mParentState2, lr.getOriginalState());
if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
}
@@ -1161,7 +1295,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1176,7 +1310,6 @@
@MediumTest
public void testStateMachine6() throws Exception {
- long sentTimeMsg2;
final int DELAY_TIME = 250;
final int DELAY_FUDGE = 20;
@@ -1186,7 +1319,6 @@
synchronized (sm6) {
// Send a message
- sentTimeMsg2 = SystemClock.elapsedRealtime();
sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
try {
@@ -1268,7 +1400,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1285,7 +1417,6 @@
@MediumTest
public void testStateMachine7() throws Exception {
- long sentTimeMsg2;
final int SM7_DELAY_FUDGE = 20;
StateMachine7 sm7 = new StateMachine7("sm7");
@@ -1294,7 +1425,6 @@
synchronized (sm7) {
// Send a message
- sentTimeMsg2 = SystemClock.elapsedRealtime();
sm7.sendMessage(TEST_CMD_1);
try {
@@ -1350,7 +1480,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
synchronized (mThisSm) {
mThisSm.notifyAll();
}
@@ -1383,7 +1513,7 @@
}
}
- assertTrue(sm.getProcessedMessagesCount() == 2);
+ assertEquals(sm.getLogRecCount(), 2);
assertEquals(2, sm.mUnhandledMessageCount);
if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
@@ -1420,7 +1550,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
// Update the shared counter, which is OK since all state
// machines are using the same thread.
sharedCounter += 1;
@@ -1470,12 +1600,12 @@
}
for (StateMachineSharedThread sm : sms) {
- assertTrue(sm.getProcessedMessagesCount() == 4);
- for (int i = 0; i < sm.getProcessedMessagesCount(); i++) {
- ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(i);
- assertEquals(i+1, pmi.getWhat());
- assertEquals(sm.mS1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ assertEquals(sm.getLogRecCount(), 4);
+ for (int i = 0; i < sm.getLogRecCount(); i++) {
+ LogRec lr = sm.getLogRec(i);
+ assertEquals(i+1, lr.getWhat());
+ assertEquals(sm.mS1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
}
}
@@ -1501,41 +1631,41 @@
}
}
- assertEquals(7, sm.getProcessedMessagesCount());
- ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(0);
- assertEquals(Hsm1.CMD_1, pmi.getWhat());
- assertEquals(sm.mS1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ assertEquals(7, sm.getLogRecCount());
+ LogRec lr = sm.getLogRec(0);
+ assertEquals(Hsm1.CMD_1, lr.getWhat());
+ assertEquals(sm.mS1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(1);
- assertEquals(Hsm1.CMD_2, pmi.getWhat());
- assertEquals(sm.mP1, pmi.getState());
- assertEquals(sm.mS1, pmi.getOriginalState());
+ lr = sm.getLogRec(1);
+ assertEquals(Hsm1.CMD_2, lr.getWhat());
+ assertEquals(sm.mP1, lr.getState());
+ assertEquals(sm.mS1, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(2);
- assertEquals(Hsm1.CMD_2, pmi.getWhat());
- assertEquals(sm.mS2, pmi.getState());
- assertEquals(sm.mS2, pmi.getOriginalState());
+ lr = sm.getLogRec(2);
+ assertEquals(Hsm1.CMD_2, lr.getWhat());
+ assertEquals(sm.mS2, lr.getState());
+ assertEquals(sm.mS2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(3);
- assertEquals(Hsm1.CMD_3, pmi.getWhat());
- assertEquals(sm.mS2, pmi.getState());
- assertEquals(sm.mS2, pmi.getOriginalState());
+ lr = sm.getLogRec(3);
+ assertEquals(Hsm1.CMD_3, lr.getWhat());
+ assertEquals(sm.mS2, lr.getState());
+ assertEquals(sm.mS2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(4);
- assertEquals(Hsm1.CMD_3, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(4);
+ assertEquals(Hsm1.CMD_3, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(5);
- assertEquals(Hsm1.CMD_4, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(5);
+ assertEquals(Hsm1.CMD_4, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
- pmi = sm.getProcessedMessageInfo(6);
- assertEquals(Hsm1.CMD_5, pmi.getWhat());
- assertEquals(sm.mP2, pmi.getState());
- assertEquals(sm.mP2, pmi.getOriginalState());
+ lr = sm.getLogRec(6);
+ assertEquals(Hsm1.CMD_5, lr.getWhat());
+ assertEquals(sm.mP2, lr.getState());
+ assertEquals(sm.mP2, lr.getOriginalState());
if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
}
@@ -1684,7 +1814,7 @@
}
@Override
- protected void halting() {
+ protected void onHalting() {
Log.d(TAG, "halting");
synchronized (this) {
this.notifyAll();
diff --git a/core/tests/hosttests/Android.mk b/core/tests/hosttests/Android.mk
index 07d99cb..f26d401 100644
--- a/core/tests/hosttests/Android.mk
+++ b/core/tests/hosttests/Android.mk
@@ -16,17 +16,5 @@
include $(CLEAR_VARS)
-#LOCAL_TEST_TYPE := hostSideOnly
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := FrameworkCoreHostTests
-
-LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib-prebuilt junit
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
# Build the test APKs using their own makefiles
include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/core/tests/hosttests/README b/core/tests/hosttests/README
deleted file mode 100644
index d3bdb83..0000000
--- a/core/tests/hosttests/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This dir contains tests which run on a host machine, and test aspects of
-package install etc via adb.
-
-To run, do:
-runtest framework-core-host
-
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
deleted file mode 100644
index c698e99..0000000
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * 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 android.content.pm;
-
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.InstallException;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.SyncException;
-import com.android.ddmlib.TimeoutException;
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-import com.android.ddmlib.testrunner.ITestRunListener;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.lang.Runtime;
-import java.lang.Process;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import junit.framework.Assert;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTestUtils extends Assert {
-
- private static final String LOG_TAG = "PackageManagerHostTests";
- private IDevice mDevice = null;
-
- // TODO: get this value from Android Environment instead of hardcoding
- private static final String APP_PRIVATE_PATH = "/data/app-private/";
- private static final String DEVICE_APP_PATH = "/data/app/";
- private static final String SDCARD_APP_PATH = "/mnt/secure/asec/";
-
- private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
- private static final int WAIT_FOR_DEVICE_POLL_TIME = 10 * 1000;
- private static final int MAX_WAIT_FOR_APP_LAUNCH_TIME = 60 * 1000;
- private static final int WAIT_FOR_APP_LAUNCH_POLL_TIME = 5 * 1000;
-
- // Install preference on the device-side
- public static enum InstallLocPreference {
- AUTO,
- INTERNAL,
- EXTERNAL
- }
-
- // Actual install location
- public static enum InstallLocation {
- DEVICE,
- SDCARD
- }
-
- /**
- * Constructor takes the device to use
- * @param the device to use when performing operations
- */
- public PackageManagerHostTestUtils(IDevice device)
- {
- mDevice = device;
- }
-
- /**
- * Disable default constructor
- */
- private PackageManagerHostTestUtils() {}
-
- /**
- * Returns the path on the device of forward-locked apps.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getAppPrivatePath() {
- return APP_PRIVATE_PATH;
- }
-
- /**
- * Returns the path on the device of normal apps.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getDeviceAppPath() {
- return DEVICE_APP_PATH;
- }
-
- /**
- * Returns the path of apps installed on the SD card.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getSDCardAppPath() {
- return SDCARD_APP_PATH;
- }
-
- /**
- * Helper method to run tests and return the listener that collected the results.
- *
- * For the optional params, pass null to use the default values.
-
- * @param pkgName Android application package for tests
- * @param className (optional) The class containing the method to test
- * @param methodName (optional) The method in the class of which to test
- * @param runnerName (optional) The name of the TestRunner of the test on the device to be run
- * @param params (optional) Any additional parameters to pass into the Test Runner
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @return the {@link CollectingTestRunListener}
- */
- private CollectingTestRunListener doRunTests(String pkgName, String className,
- String methodName, String runnerName, Map<String, String> params) throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName, runnerName,
- mDevice);
-
- if (className != null && methodName != null) {
- testRunner.setMethodName(className, methodName);
- }
-
- // Add in any additional args to pass into the test
- if (params != null) {
- for (Entry<String, String> argPair : params.entrySet()) {
- testRunner.addInstrumentationArg(argPair.getKey(), argPair.getValue());
- }
- }
-
- CollectingTestRunListener listener = new CollectingTestRunListener();
- try {
- testRunner.run(listener);
- } catch (IOException ioe) {
- Log.w(LOG_TAG, "encountered IOException " + ioe);
- }
- return listener;
- }
-
- /**
- * Runs the specified packages tests, and returns whether all tests passed or not.
- *
- * @param pkgName Android application package for tests
- * @param className The class containing the method to test
- * @param methodName The method in the class of which to test
- * @param runnerName The name of the TestRunner of the test on the device to be run
- * @param params Any additional parameters to pass into the Test Runner
- * @return true if test passed, false otherwise.
- */
- public boolean runDeviceTestsDidAllTestsPass(String pkgName, String className,
- String methodName, String runnerName, Map<String, String> params) throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- CollectingTestRunListener listener = doRunTests(pkgName, className, methodName,
- runnerName, params);
- return listener.didAllTestsPass();
- }
-
- /**
- * Runs the specified packages tests, and returns whether all tests passed or not.
- *
- * @param pkgName Android application package for tests
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @return true if every test passed, false otherwise.
- */
- public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- CollectingTestRunListener listener = doRunTests(pkgName, null, null, null, null);
- return listener.didAllTestsPass();
- }
-
- /**
- * Helper method to push a file to device
- * @param apkAppPrivatePath
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- */
- public void pushFile(final String localFilePath, final String destFilePath)
- throws IOException, SyncException, TimeoutException, AdbCommandRejectedException {
- mDevice.getSyncService().pushFile(localFilePath,
- destFilePath, new NullSyncProgressMonitor());
- }
-
- /**
- * Helper method to install a file
- * @param localFilePath the absolute file system path to file on local host to install
- * @param reinstall set to <code>true</code> if re-install of app should be performed
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed
- */
- public void installFile(final String localFilePath, final boolean replace) throws IOException,
- InstallException {
- String result = mDevice.installPackage(localFilePath, replace);
- assertEquals(null, result);
- }
-
- /**
- * Helper method to install a file that should not be install-able
- * @param localFilePath the absolute file system path to file on local host to install
- * @param reinstall set to <code>true</code> if re-install of app should be performed
- * @return the string output of the failed install attempt
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed
- */
- public String installFileFail(final String localFilePath, final boolean replace)
- throws IOException, InstallException {
- String result = mDevice.installPackage(localFilePath, replace);
- assertNotNull(result);
- return result;
- }
-
- /**
- * Helper method to install a file to device as forward locked
- * @param localFilePath the absolute file system path to file on local host to install
- * @param reinstall set to <code>true</code> if re-install of app should be performed
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public String installFileForwardLocked(final String localFilePath, final boolean replace)
- throws IOException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException, InstallException {
- String remoteFilePath = mDevice.syncPackageToDevice(localFilePath);
- InstallReceiver receiver = new InstallReceiver();
- String cmd = String.format(replace ? "pm install -r -l \"%1$s\"" :
- "pm install -l \"%1$s\"", remoteFilePath);
- mDevice.executeShellCommand(cmd, receiver);
- mDevice.removeRemotePackage(remoteFilePath);
- return receiver.getErrorMessage();
- }
-
- /**
- * Helper method to determine if file on device exists.
- *
- * @param destPath the absolute path of file on device to check
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesRemoteFileExist(String destPath) throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- String lsGrep = executeShellCommand(String.format("ls %s", destPath));
- return !lsGrep.contains("No such file or directory");
- }
-
- /**
- * Helper method to determine if file exists on the device containing a given string.
- *
- * @param destPath the absolute path of the file
- * @return <code>true</code> if file exists containing given string,
- * <code>false</code> otherwise.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
- throws IOException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- String lsResult = executeShellCommand(String.format("ls %s", destPath));
- return lsResult.contains(searchString);
- }
-
- /**
- * Helper method to determine if package on device exists.
- *
- * @param packageName the Android manifest package to check.
- * @return <code>true</code> if package exists, <code>false</code> otherwise
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesPackageExist(String packageName) throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- String pkgGrep = executeShellCommand(String.format("pm path %s", packageName));
- return pkgGrep.contains("package:");
- }
-
- /**
- * Determines if app was installed on device.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesAppExistOnDevice(String packageName) throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
- }
-
- /**
- * Determines if app was installed on SD card.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesAppExistOnSDCard(String packageName) throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
- }
-
- /**
- * Helper method to determine if app was installed on SD card.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public boolean doesAppExistAsForwardLocked(String packageName) throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- return doesRemoteFileExistContainingString(APP_PRIVATE_PATH, packageName);
- }
-
- /**
- * Waits for device's package manager to respond.
- *
- * @throws InterruptedException
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public void waitForPackageManager() throws InterruptedException, IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "waiting for device");
- int currentWaitTime = 0;
- // poll the package manager until it returns something for android
- while (!doesPackageExist("android")) {
- Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
- currentWaitTime += WAIT_FOR_DEVICE_POLL_TIME;
- if (currentWaitTime > MAX_WAIT_FOR_DEVICE_TIME) {
- Log.e(LOG_TAG, "time out waiting for device");
- throw new InterruptedException();
- }
- }
- }
-
- /**
- * Helper to determine if the device is currently online and visible via ADB.
- *
- * @return true iff the device is currently available to ADB and online, false otherwise.
- */
- private boolean deviceIsOnline() {
- AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
- IDevice[] devices = bridge.getDevices();
-
- for (IDevice device : devices) {
- // only online if the device appears in the devices list, and its state is online
- if ((mDevice != null) &&
- mDevice.getSerialNumber().equals(device.getSerialNumber()) &&
- device.isOnline()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Waits for device to be online (visible to ADB) before returning, or times out if we've
- * waited too long. Note that this only means the device is visible via ADB, not that
- * PackageManager is fully up and running yet.
- *
- * @throws InterruptedException
- * @throws IOException
- */
- public void waitForDeviceToComeOnline() throws InterruptedException, IOException {
- Log.i(LOG_TAG, "waiting for device to be online");
- int currentWaitTime = 0;
-
- // poll ADB until we see the device is online
- while (!deviceIsOnline()) {
- Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
- currentWaitTime += WAIT_FOR_DEVICE_POLL_TIME;
- if (currentWaitTime > MAX_WAIT_FOR_DEVICE_TIME) {
- Log.e(LOG_TAG, "time out waiting for device");
- throw new InterruptedException();
- }
- }
- // Note: if we try to access the device too quickly after it is "officially" online,
- // there are sometimes strange issues where it's actually not quite ready yet,
- // so we pause for a bit once more before actually returning.
- Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
- }
-
- /**
- * Queries package manager and waits until a package is launched (or times out)
- *
- * @param packageName The name of the package to wait to load
- * @throws InterruptedException
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public void waitForApp(String packageName) throws InterruptedException, IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "waiting for app to launch");
- int currentWaitTime = 0;
- // poll the package manager until it returns something for the package we're looking for
- while (!doesPackageExist(packageName)) {
- Thread.sleep(WAIT_FOR_APP_LAUNCH_POLL_TIME);
- currentWaitTime += WAIT_FOR_APP_LAUNCH_POLL_TIME;
- if (currentWaitTime > MAX_WAIT_FOR_APP_LAUNCH_TIME) {
- Log.e(LOG_TAG, "time out waiting for app to launch: " + packageName);
- throw new InterruptedException();
- }
- }
- }
-
- /**
- * Helper method which executes a adb shell command and returns output as a {@link String}
- * @return the output of the command
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public String executeShellCommand(String command) throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, String.format("adb shell %s", command));
- CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- mDevice.executeShellCommand(command, receiver);
- String output = receiver.getOutput();
- Log.i(LOG_TAG, String.format("Result: %s", output));
- return output;
- }
-
- /**
- * Helper method ensures we are in root mode on the host side. It returns only after
- * PackageManager is actually up and running.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public void runAdbRoot() throws IOException, InterruptedException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "adb root");
- Runtime runtime = Runtime.getRuntime();
- Process process = runtime.exec("adb root"); // adb should be in the path
- BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
-
- String nextLine = null;
- while (null != (nextLine = output.readLine())) {
- Log.i(LOG_TAG, nextLine);
- }
- process.waitFor();
- waitForDeviceToComeOnline();
- waitForPackageManager(); // now wait for package manager to actually load
- }
-
- /**
- * Helper method which reboots the device and returns once the device is online again
- * and package manager is up and running (note this function is synchronous to callers).
- * @throws InterruptedException
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public void rebootDevice() throws IOException, InterruptedException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- String command = "reboot"; // no need for -s since mDevice is already tied to a device
- Log.i(LOG_TAG, command);
- CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- mDevice.executeShellCommand(command, receiver);
- String output = receiver.getOutput();
- Log.i(LOG_TAG, String.format("Result: %s", output));
- waitForDeviceToComeOnline(); // wait for device to come online
- runAdbRoot();
- }
-
- /**
- * A {@link IShellOutputReceiver} which collects the whole shell output into one {@link String}
- */
- private class CollectingOutputReceiver extends MultiLineReceiver {
-
- private StringBuffer mOutputBuffer = new StringBuffer();
-
- public String getOutput() {
- return mOutputBuffer.toString();
- }
-
- @Override
- public void processNewLines(String[] lines) {
- for (String line: lines) {
- mOutputBuffer.append(line);
- mOutputBuffer.append("\n");
- }
- }
-
- public boolean isCancelled() {
- return false;
- }
- }
-
- private class NullSyncProgressMonitor implements ISyncProgressMonitor {
- public void advance(int work) {
- // ignore
- }
-
- public boolean isCanceled() {
- // ignore
- return false;
- }
-
- public void start(int totalWork) {
- // ignore
-
- }
-
- public void startSubTask(String name) {
- // ignore
- }
-
- public void stop() {
- // ignore
- }
- }
-
- // For collecting results from running device tests
- public static class CollectingTestRunListener implements ITestRunListener {
-
- private boolean mAllTestsPassed = true;
- private String mTestRunErrorMessage = null;
-
- public void testEnded(TestIdentifier test, Map<String, String> metrics) {
- // ignore
- }
-
- public void testFailed(TestFailure status, TestIdentifier test,
- String trace) {
- Log.w(LOG_TAG, String.format("%s#%s failed: %s", test.getClassName(),
- test.getTestName(), trace));
- mAllTestsPassed = false;
- }
-
- public void testRunEnded(long elapsedTime, Map<String, String> resultBundle) {
- // ignore
- }
-
- public void testRunFailed(String errorMessage) {
- Log.w(LOG_TAG, String.format("test run failed: %s", errorMessage));
- mAllTestsPassed = false;
- mTestRunErrorMessage = errorMessage;
- }
-
- public void testRunStarted(String runName, int testCount) {
- // ignore
- }
-
- public void testRunStopped(long elapsedTime) {
- // ignore
- }
-
- public void testStarted(TestIdentifier test) {
- // ignore
- }
-
- boolean didAllTestsPass() {
- return mAllTestsPassed;
- }
-
- /**
- * Get the test run failure error message.
- * @return the test run failure error message or <code>null</code> if test run completed.
- */
- String getTestRunErrorMessage() {
- return mTestRunErrorMessage;
- }
- }
-
- /**
- * Output receiver for "pm install package.apk" command line.
- *
- */
- private static final class InstallReceiver extends MultiLineReceiver {
-
- private static final String SUCCESS_OUTPUT = "Success"; //$NON-NLS-1$
- private static final Pattern FAILURE_PATTERN = Pattern.compile("Failure\\s+\\[(.*)\\]"); //$NON-NLS-1$
-
- private String mErrorMessage = null;
-
- public InstallReceiver() {
- }
-
- @Override
- public void processNewLines(String[] lines) {
- for (String line : lines) {
- if (line.length() > 0) {
- if (line.startsWith(SUCCESS_OUTPUT)) {
- mErrorMessage = null;
- } else {
- Matcher m = FAILURE_PATTERN.matcher(line);
- if (m.matches()) {
- mErrorMessage = m.group(1);
- }
- }
- }
- }
- }
-
- public boolean isCancelled() {
- return false;
- }
-
- public String getErrorMessage() {
- return mErrorMessage;
- }
- }
-
- /**
- * Helper method for installing an app to wherever is specified in its manifest, and
- * then verifying the app was installed onto SD Card.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param the path of the apk to install
- * @param the name of the package
- * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void installAppAndVerifyExistsOnSDCard(String apkPath, String pkgName, boolean overwrite)
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- installFile(apkPath, overwrite);
- assertTrue(doesAppExistOnSDCard(pkgName));
- assertFalse(doesAppExistOnDevice(pkgName));
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for installing an app to wherever is specified in its manifest, and
- * then verifying the app was installed onto device.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param the path of the apk to install
- * @param the name of the package
- * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void installAppAndVerifyExistsOnDevice(String apkPath, String pkgName, boolean overwrite)
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- installFile(apkPath, overwrite);
- assertFalse(doesAppExistOnSDCard(pkgName));
- assertTrue(doesAppExistOnDevice(pkgName));
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for installing an app as forward-locked, and
- * then verifying the app was installed in the proper forward-locked location.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param the path of the apk to install
- * @param the name of the package
- * @param <code>true</code> if the app should be overwritten, <code>false</code> otherwise
- * @throws InterruptedException if the thread was interrupted
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- */
- public void installFwdLockedAppAndVerifyExists(String apkPath,
- String pkgName, boolean overwrite) throws IOException, InterruptedException,
- InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- String result = installFileForwardLocked(apkPath, overwrite);
- assertEquals(null, result);
- assertTrue(doesAppExistAsForwardLocked(pkgName));
- assertFalse(doesAppExistOnSDCard(pkgName));
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for uninstalling an app.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param pkgName package name to uninstall
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the uninstall failed.
- */
- public void uninstallApp(String pkgName) throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- mDevice.uninstallPackage(pkgName);
- // make sure its not installed anymore
- assertFalse(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for clearing any installed non-system apps.
- * Useful ensuring no non-system apps are installed, and for cleaning up stale files that
- * may be lingering on the system for whatever reason.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the uninstall failed.
- */
- public void wipeNonSystemApps() throws IOException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException, InstallException {
- String allInstalledPackages = executeShellCommand("pm list packages -f");
- BufferedReader outputReader = new BufferedReader(new StringReader(allInstalledPackages));
-
- // First use Package Manager to uninstall all non-system apps
- String currentLine = null;
- while ((currentLine = outputReader.readLine()) != null) {
- // Skip over any system apps...
- if (currentLine.contains("/system/")) {
- continue;
- }
- String packageName = currentLine.substring(currentLine.indexOf('=') + 1);
- mDevice.uninstallPackage(packageName);
- }
- // Make sure there are no stale app files under these directories
- executeShellCommand(String.format("rm %s*", SDCARD_APP_PATH, "*"));
- executeShellCommand(String.format("rm %s*", DEVICE_APP_PATH, "*"));
- executeShellCommand(String.format("rm %s*", APP_PRIVATE_PATH, "*"));
- }
-
- /**
- * Sets the device's install location preference.
- *
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public void setDevicePreferredInstallLocation(InstallLocPreference pref) throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- String command = "pm setInstallLocation %d";
- int locValue = 0;
- switch (pref) {
- case INTERNAL:
- locValue = 1;
- break;
- case EXTERNAL:
- locValue = 2;
- break;
- default: // AUTO
- locValue = 0;
- break;
- }
- executeShellCommand(String.format(command, locValue));
- }
-
- /**
- * Gets the device's install location preference.
- *
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- */
- public InstallLocPreference getDevicePreferredInstallLocation() throws IOException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- String result = executeShellCommand("pm getInstallLocation");
- if (result.indexOf('0') != -1) {
- return InstallLocPreference.AUTO;
- }
- else if (result.indexOf('1') != -1) {
- return InstallLocPreference.INTERNAL;
- }
- else {
- return InstallLocPreference.EXTERNAL;
- }
- }
-}
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
deleted file mode 100644
index 22a2be6..0000000
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * 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 android.content.pm;
-
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.ddmlib.InstallException;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.SyncException;
-import com.android.ddmlib.TimeoutException;
-import com.android.hosttest.DeviceTestCase;
-import com.android.hosttest.DeviceTestSuite;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Test;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTests extends DeviceTestCase {
-
- private static final String LOG_TAG = "PackageManagerHostTests";
- private PackageManagerHostTestUtils mPMHostUtils = null;
-
- private String appPrivatePath = null;
- private String deviceAppPath = null;
- private String sdcardAppPath = null;
-
- // Various test files and their corresponding package names...
-
- // testPushAppPrivate constants
- // these constants must match values defined in test-apps/SimpleTestApp
- private static final String SIMPLE_APK = "SimpleTestApp.apk";
- private static final String SIMPLE_PKG = "com.android.framework.simpletestapp";
-
- // Apk with install location set to auto
- private static final String AUTO_LOC_APK = "AutoLocTestApp.apk";
- private static final String AUTO_LOC_PKG = "com.android.framework.autoloctestapp";
- // Apk with install location set to internalOnly
- private static final String INTERNAL_LOC_APK = "InternalLocTestApp.apk";
- private static final String INTERNAL_LOC_PKG = "com.android.framework.internalloctestapp";
- // Apk with install location set to preferExternal
- private static final String EXTERNAL_LOC_APK = "ExternalLocTestApp.apk";
- private static final String EXTERNAL_LOC_PKG = "com.android.framework.externalloctestapp";
- // Apk with install location set to auto (2 versions, for update testing)
- private static final String AUTO_LOC_VERSION_V1_APK = "AutoLocVersionedTestApp_v1.apk";
- private static final String AUTO_LOC_VERSION_V2_APK = "AutoLocVersionedTestApp_v2.apk";
- private static final String AUTO_LOC_VERSION_PKG =
- "com.android.framework.autolocversionedtestapp";
- // Apk with install location set to preferExternal (2 versions, for update testing)
- private static final String EXTERNAL_LOC_VERSION_V1_APK = "ExternalLocVersionedTestApp_v1.apk";
- private static final String EXTERNAL_LOC_VERSION_V2_APK = "ExternalLocVersionedTestApp_v2.apk";
- private static final String EXTERNAL_LOC_VERSION_PKG =
- "com.android.framework.externallocversionedtestapp";
- // Apk with install location set to auto (2 versions, for update testing)
- private static final String NO_LOC_VERSION_V1_APK = "NoLocVersionedTestApp_v1.apk";
- private static final String NO_LOC_VERSION_V2_APK = "NoLocVersionedTestApp_v2.apk";
- private static final String NO_LOC_VERSION_PKG =
- "com.android.framework.nolocversionedtestapp";
- // Apk with no install location set
- private static final String NO_LOC_APK = "NoLocTestApp.apk";
- private static final String NO_LOC_PKG = "com.android.framework.noloctestapp";
- // Apk with 2 different versions - v1 is set to external, v2 has no location setting
- private static final String UPDATE_EXTERNAL_LOC_V1_EXT_APK
- = "UpdateExternalLocTestApp_v1_ext.apk";
- private static final String UPDATE_EXTERNAL_LOC_V2_NONE_APK
- = "UpdateExternalLocTestApp_v2_none.apk";
- private static final String UPDATE_EXTERNAL_LOC_PKG
- = "com.android.framework.updateexternalloctestapp";
- // Apk with 2 different versions - v1 is set to external, v2 is set to internalOnly
- private static final String UPDATE_EXT_TO_INT_LOC_V1_EXT_APK
- = "UpdateExtToIntLocTestApp_v1_ext.apk";
- private static final String UPDATE_EXT_TO_INT_LOC_V2_INT_APK
- = "UpdateExtToIntLocTestApp_v2_int.apk";
- private static final String UPDATE_EXT_TO_INT_LOC_PKG
- = "com.android.framework.updateexttointloctestapp";
- // Apk set to preferExternal, with Access Fine Location permissions set in its manifest
- private static final String FL_PERMS_APK = "ExternalLocPermsFLTestApp.apk";
- private static final String FL_PERMS_PKG = "com.android.framework.externallocpermsfltestapp";
- // Apk set to preferExternal, with all permissions set in manifest
- private static final String ALL_PERMS_APK = "ExternalLocAllPermsTestApp.apk";
- private static final String ALL_PERMS_PKG = "com.android.framework.externallocallpermstestapp";
- // Apks with the same package name, but install location set to
- // one of: Internal, External, Auto, or None
- private static final String VERSATILE_LOC_PKG = "com.android.framework.versatiletestapp";
- private static final String VERSATILE_LOC_INTERNAL_APK = "VersatileTestApp_Internal.apk";
- private static final String VERSATILE_LOC_EXTERNAL_APK = "VersatileTestApp_External.apk";
- private static final String VERSATILE_LOC_AUTO_APK = "VersatileTestApp_Auto.apk";
- private static final String VERSATILE_LOC_NONE_APK = "VersatileTestApp_None.apk";
- // Apks with shared UserID
- private static final String SHARED_PERMS_APK = "ExternalSharedPermsTestApp.apk";
- private static final String SHARED_PERMS_PKG
- = "com.android.framework.externalsharedpermstestapp";
- private static final String SHARED_PERMS_FL_APK = "ExternalSharedPermsFLTestApp.apk";
- private static final String SHARED_PERMS_FL_PKG
- = "com.android.framework.externalsharedpermsfltestapp";
- private static final String SHARED_PERMS_BT_APK = "ExternalSharedPermsBTTestApp.apk";
- private static final String SHARED_PERMS_BT_PKG
- = "com.android.framework.externalsharedpermsbttestapp";
- // Apk with shared UserID, but signed with a different cert (the media cert)
- private static final String SHARED_PERMS_DIFF_KEY_APK = "ExternalSharedPermsDiffKeyTestApp.apk";
- private static final String SHARED_PERMS_DIFF_KEY_PKG
- = "com.android.framework.externalsharedpermsdiffkeytestapp";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // ensure apk path has been set before test is run
- assertNotNull(getTestAppPath());
-
- // setup the PackageManager host tests utilities class, and get various paths we'll need...
- mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
- appPrivatePath = mPMHostUtils.getAppPrivatePath();
- deviceAppPath = mPMHostUtils.getDeviceAppPath();
- sdcardAppPath = mPMHostUtils.getSDCardAppPath();
-
- // Ensure the default is set to let the system decide where to install apps
- // (It's ok for individual tests to override and change this during their test, but should
- // reset it back when they're done)
- mPMHostUtils.setDevicePreferredInstallLocation(
- PackageManagerHostTestUtils.InstallLocPreference.AUTO);
- }
-
- /**
- * Get the absolute file system location of test app with given filename
- * @param fileName the file name of the test app apk
- * @return {@link String} of absolute file path
- */
- public String getTestAppFilePath(String fileName) {
- return String.format("%s%s%s", getTestAppPath(), File.separator, fileName);
- }
-
- public static Test suite() {
- return new DeviceTestSuite(PackageManagerHostTests.class);
- }
-
- /**
- * Regression test to verify that pushing an apk to the private app directory doesn't install
- * the app, and otherwise cause the system to blow up.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testPushAppPrivate() throws IOException, InterruptedException, InstallException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- SyncException {
- Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
- final String apkAppPrivatePath = appPrivatePath + SIMPLE_APK;
-
- // cleanup test app just in case it was accidently installed
- getDevice().uninstallPackage(SIMPLE_PKG);
- mPMHostUtils.executeShellCommand("stop");
- mPMHostUtils.pushFile(getTestAppFilePath(SIMPLE_APK), apkAppPrivatePath);
-
- // sanity check to make sure file is there
- assertTrue(mPMHostUtils.doesRemoteFileExist(apkAppPrivatePath));
- mPMHostUtils.executeShellCommand("start");
-
- mPMHostUtils.waitForPackageManager();
-
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(SIMPLE_PKG));
- // ensure it has been deleted from app-private
- assertFalse(mPMHostUtils.doesRemoteFileExist(apkAppPrivatePath));
- }
-
- /**
- * Helper to do a standard install of an apk and verify it installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @param apkName the file name of the test app apk
- * @param pkgName the package name of the test app apk
- * @param expectedLocation the file name of the test app apk
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- private void doStandardInstall(String apkName, String pkgName,
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
-
- if (expectedLocation == PackageManagerHostTestUtils.InstallLocation.DEVICE) {
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(apkName), pkgName, false);
- }
- else {
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(apkName), pkgName, false);
- }
- }
-
- /**
- * Installs the Auto app using the preferred device install location specified,
- * and verifies it was installed on the device.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @param preference the device's preferred location of where to install apps
- * @param expectedLocation the expected location of where the apk was installed
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException, InstallException {
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(preference);
-
- doStandardInstall(AUTO_LOC_APK, AUTO_LOC_PKG, expectedLocation);
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=auto
- * will install the app to the device when device's preference is auto.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppAutoLocPrefIsAuto() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=auto, prefer=auto gets installed on device");
- installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=auto
- * will install the app to the device when device's preference is internal.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppAutoLocPrefIsInternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=auto, prefer=internal gets installed on device");
- installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=auto
- * will install the app to the SD card when device's preference is external.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppAutoLocPrefIsExternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=auto, prefer=external gets installed on device");
- installAppAutoLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Installs the Internal app using the preferred device install location specified,
- * and verifies it was installed to the location expected.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @param preference the device's preferred location of where to install apps
- * @param expectedLocation the expected location of where the apk was installed
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the (un)install failed.
- */
- public void installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException, InstallException {
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(preference);
-
- doStandardInstall(INTERNAL_LOC_APK, INTERNAL_LOC_PKG, expectedLocation);
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=internalOnly
- * will install the app to the device when device's preference is auto.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppInternalLocPrefIsAuto() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=internal, prefer=auto gets installed on device");
- installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=internalOnly
- * will install the app to the device when device's preference is internal.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppInternalLocPrefIsInternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=internal, prefer=internal is installed on device");
- installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=internalOnly
- * will install the app to the device when device's preference is external.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppInternalLocPrefIsExternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=internal, prefer=external is installed on device");
- installAppInternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
- PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=preferExternal
- * will install the app to the SD card.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @param preference the device's preferred location of where to install apps
- * @param expectedLocation the expected location of where the apk was installed
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference preference,
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws IOException, InterruptedException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException, InstallException {
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(preference);
-
- doStandardInstall(EXTERNAL_LOC_APK, EXTERNAL_LOC_PKG, expectedLocation);
-
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=preferExternal
- * will install the app to the device when device's preference is auto.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppExternalLocPrefIsAuto() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=external, pref=auto gets installed on SD Card");
- installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.AUTO,
- PackageManagerHostTestUtils.InstallLocation.SDCARD);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=preferExternal
- * will install the app to the device when device's preference is internal.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppExternalLocPrefIsInternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=external, pref=internal gets installed on SD Card");
- installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.INTERNAL,
- PackageManagerHostTestUtils.InstallLocation.SDCARD);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to installLocation=preferExternal
- * will install the app to the device when device's preference is external.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppExternalLocPrefIsExternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installLocation=external, pref=external gets installed on SD Card");
- installAppExternalLoc(PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL,
- PackageManagerHostTestUtils.InstallLocation.SDCARD);
- }
-
- /**
- * Regression test to verify that an app without installLocation in its manifest
- * will install the app to the device by default when the system default pref is to let the
- * system decide.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppNoLocPrefIsAuto() throws IOException, InterruptedException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- InstallException {
- Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(
- PackageManagerHostTestUtils.InstallLocPreference.AUTO);
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app without installLocation in its manifest
- * will install the app to the device by default when the system default pref is to install
- * external.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppNoLocPrefIsExternal() throws IOException, InterruptedException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- InstallException {
- Log.i(LOG_TAG, "Test an app with no installLocation gets installed on SD card");
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(
- PackageManagerHostTestUtils.InstallLocPreference.EXTERNAL);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app without installLocation in its manifest
- * will install the app to the device by default when the system default pref is to install
- * internal.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAppNoLocPrefIsInternal() throws IOException, InterruptedException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException,
- InstallException {
- Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
-
- PackageManagerHostTestUtils.InstallLocPreference savedPref =
- PackageManagerHostTestUtils.InstallLocPreference.AUTO;
-
- try {
- savedPref = mPMHostUtils.getDevicePreferredInstallLocation();
- mPMHostUtils.setDevicePreferredInstallLocation(
- PackageManagerHostTestUtils.InstallLocPreference.INTERNAL);
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.setDevicePreferredInstallLocation(savedPref);
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to internal that is
- * forward-locked will get installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallFwdLockedAppInternal() throws IOException, InterruptedException,
- InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(INTERNAL_LOC_APK), INTERNAL_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to external that is
- * forward-locked will get installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallFwdLockedAppExternal() throws IOException, InterruptedException,
- InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(INTERNAL_LOC_APK), INTERNAL_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to external that is
- * forward-locked will get installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallFwdLockedAppAuto() throws IOException, InterruptedException,
- InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test an app with installLoc set to Auto gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(AUTO_LOC_APK), AUTO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with no installLocation set and is
- * forward-locked installed will get installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallFwdLockedAppNone() throws IOException, InterruptedException,
- InstallException, SyncException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test an app with no installLoc set gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that we can install an app onto the device,
- * uninstall it, and reinstall it onto the SD card.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- // TODO: This currently relies on the app's manifest to switch from device to
- // SD card install locations. We might want to make Device's installPackage()
- // accept a installLocation flag so we can install a package to the
- // destination of our choosing.
- public void testReinstallInternalToExternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
-
- try {
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that we can install an app onto the SD Card,
- * uninstall it, and reinstall it onto the device.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- // TODO: This currently relies on the app's manifest to switch from device to
- // SD card install locations. We might want to make Device's installPackage()
- // accept a installLocation flag so we can install a package to the
- // destination of our choosing.
- public void testReinstallExternalToInternal() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- // then replace the app with one marked for internalOnly
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will install
- * the update onto the SD card as well when location is set to external for both versions
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testUpdateBothExternal() throws IOException, InterruptedException, InstallException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
- // now replace the app with one where the location is still set to preferExternal
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will install
- * the update onto the SD card as well when location is not explicitly set in the
- * updated apps' manifest file.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testUpdateToSDCard() throws IOException, InterruptedException, InstallException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXTERNAL_LOC_V1_EXT_APK), UPDATE_EXTERNAL_LOC_PKG, false);
- // now replace the app with one where the location is blank (app should stay external)
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXTERNAL_LOC_V2_NONE_APK), UPDATE_EXTERNAL_LOC_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(UPDATE_EXTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will install
- * the update onto the device if the manifest has changed to installLocation=internalOnly
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testUpdateSDCardToDevice() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXT_TO_INT_LOC_V1_EXT_APK), UPDATE_EXT_TO_INT_LOC_PKG, false);
- // now replace the app with an update marked for internalOnly...(should move internal)
- mPMHostUtils.installAppAndVerifyExistsOnDevice(getTestAppFilePath(
- UPDATE_EXT_TO_INT_LOC_V2_INT_APK), UPDATE_EXT_TO_INT_LOC_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(UPDATE_EXT_TO_INT_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that installing and updating a forward-locked app will install
- * the update onto the device's forward-locked location
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndUpdateExternalLocForwardLockedApp()
- throws IOException, InterruptedException, InstallException, SyncException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating a forward-locked app marked preferExternal");
-
- try {
- // first try to install the forward-locked app externally
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
- // now replace the app with an update marked for internalOnly and as forward locked
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating a forward-locked app will install
- * the update onto the device's forward-locked location
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndUpdateNoLocForwardLockedApp()
- throws IOException, InterruptedException, InstallException, SyncException,
- TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating a forward-locked app with no installLocation pref set");
-
- try {
- // install the app
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- NO_LOC_VERSION_V1_APK), NO_LOC_VERSION_PKG, false);
- // now replace the app with an update marked for internalOnly...
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- NO_LOC_VERSION_V2_APK), NO_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(NO_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with all permissions set can be installed on SD card
- * and then launched without crashing.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws SyncException if the sync failed for another reason.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchAllPermsAppOnSD()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with all perms set, installed on SD card");
-
- try {
- // install the app
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- ALL_PERMS_APK), ALL_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(ALL_PERMS_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(ALL_PERMS_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS) permissions can
- * run without permissions errors.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchFLPermsAppOnSD()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with BLUE_TOOTH permissions can
- * run without permissions errors.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchBTPermsAppOnSD()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with bluetooth perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_BT_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions throws a
- * SecurityException when launched if its other shared apps are not installed.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_NoPerms()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
- try {
- // Make sure the 2 shared apps with needed permissions are not installed...
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-
- // now install the app and see if when we launch it we get a permissions error
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
-
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assertEquals("Shared perms app should fail to run", false, testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions can run if its other
- * shared apps are installed.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_GrantedPerms()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
- try {
- // install the 2 shared apps with needed permissions first
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
- // now install the test app and see if we can launch it without errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS) permissions can
- * run without permissions errors even after a reboot
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchFLPermsAppOnSD_Reboot()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert(testsPassed);
-
- mPMHostUtils.rebootDevice();
-
- testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions can run if its other
- * shared apps are installed, even after a reboot.
- * <p/>
- * Assumes adb is running as root in device under test.
- * @throws InterruptedException if the thread was interrupted
- * @throws TimeoutException in case of a timeout on the connection.
- * @throws AdbCommandRejectedException if adb rejects the command
- * @throws ShellCommandUnresponsiveException if the device did not output anything for
- * a period longer than the max time to output.
- * @throws IOException if connection to device was lost.
- * @throws InstallException if the install failed.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_Reboot()
- throws IOException, InterruptedException, InstallException, TimeoutException,
- AdbCommandRejectedException, ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test launching an app on SD, with no explicit perms set after reboot");
-
- try {
- // install the 2 shared apps with needed permissions first
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
- // now install the test app and see if we can launch it without errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert(testsPassed);
-
- // reboot
- mPMHostUtils.rebootDevice();
-
- // Verify we can still launch the app
- testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert(testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-}
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
deleted file mode 100644
index a2a5dd3..0000000
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerStressHostTests.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * 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 android.content.pm;
-
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.ddmlib.InstallException;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.TimeoutException;
-import com.android.hosttest.DeviceTestCase;
-import com.android.hosttest.DeviceTestSuite;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Test;
-
-/**
- * Set of tests that verify host side stress scenarios (large apps, multiple upgrades, etc.)
- */
-public class PackageManagerStressHostTests extends DeviceTestCase {
-
- private static final String LOG_TAG = "PackageManagerStressHostTests";
- private PackageManagerHostTestUtils mPMHostUtils = null;
-
- // Path to the app repository and various subdirectories of it
- // Note: These stress tests require large apks that cannot be checked into the tree.
- // These variables define static locations that point to existing APKs (not built from
- // the tree) which can be used by the the stress tests in this file.
- private static final String LARGE_APPS_DIRECTORY_NAME = "largeApps";
- private static final String MISC_APPS_DIRECTORY_NAME = "miscApps";
- private static final String VERSIONED_APPS_DIRECTORY_NAME = "versionedApps";
- private static final String MANY_APPS_DIRECTORY_NAME = "manyApps";
-
- // Note: An external environment variable "ANDROID_TEST_APP_REPOSITORY" must be set
- // which points to the root location of the app respository.
- private static String AppRepositoryPath = null;
-
- // Large apps (>1mb) - filenames and their corresponding package names:
- private static enum APK {
- FILENAME,
- PACKAGENAME;
- }
- private static final String[][] LARGE_APPS = {
- {"External1mb.apk", "com.appsonsd.mytests.External1mb"},
- {"External2mb.apk", "com.appsonsd.mytests.External2mb"},
- {"External3mb.apk", "com.appsonsd.mytests.External3mb"},
- {"External4mb.apk", "com.appsonsd.mytests.External4mb"},
- {"External5mb.apk", "com.appsonsd.mytests.External5mb"},
- {"External6mb.apk", "com.appsonsd.mytests.External6mb"},
- {"External7mb.apk", "com.appsonsd.mytests.External7mb"},
- {"External8mb.apk", "com.appsonsd.mytests.External8mb"},
- {"External9mb.apk", "com.appsonsd.mytests.External9mb"},
- {"External10mb.apk", "com.appsonsd.mytests.External10mb"},
- {"External16mb.apk", "com.appsonsd.mytests.External16mb"},
- {"External28mb.apk", "com.appsonsd.mytests.External28mb"},
- {"External34mb.apk", "com.appsonsd.mytests.External34mb"},
- {"External46mb.apk", "com.appsonsd.mytests.External46mb"},
- {"External58mb.apk", "com.appsonsd.mytests.External58mb"},
- {"External65mb.apk", "com.appsonsd.mytests.External65mb"},
- {"External72mb.apk", "com.appsonsd.mytests.External72mb"},
- {"External79mb.apk", "com.appsonsd.mytests.External79mb"},
- {"External86mb.apk", "com.appsonsd.mytests.External86mb"},
- {"External93mb.apk", "com.appsonsd.mytests.External93mb"}};
-
- // Various test files and their corresponding package names
- private static final String AUTO_LOC_APK = "Auto241kb.apk";
- private static final String AUTO_LOC_PKG = "com.appsonsd.mytests.Auto241kb";
- private static final String INTERNAL_LOC_APK = "Internal781kb.apk";
- private static final String INTERNAL_LOC_PKG = "com.appsonsd.mytests.Internal781kb";
- private static final String EXTERNAL_LOC_APK = "External931kb.apk";
- private static final String EXTERNAL_LOC_PKG = "com.appsonsd.mytests.External931kb";
- private static final String NO_LOC_APK = "Internal751kb_EclairSDK.apk";
- private static final String NO_LOC_PKG = "com.appsonsd.mytests.Internal751kb_EclairSDK";
- // Versioned test apps
- private static final String VERSIONED_APPS_FILENAME_PREFIX = "External455kb_v";
- private static final String VERSIONED_APPS_PKG = "com.appsonsd.mytests.External455kb";
- private static final int VERSIONED_APPS_START_VERSION = 1; // inclusive
- private static final int VERSIONED_APPS_END_VERSION = 250; // inclusive
- // Large number of app installs
- // @TODO: increase the max when we can install more apps
- private static final int MANY_APPS_START = 1;
- private static final int MANY_APPS_END = 100;
- private static final String MANY_APPS_PKG_PREFIX = "com.appsonsd.mytests.External49kb_";
- private static final String MANY_APPS_APK_PREFIX = "External49kb_";
-
- public static Test suite() {
- return new DeviceTestSuite(PackageManagerStressHostTests.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- // setup the PackageManager host tests utilities class, and get various paths we'll need...
- mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
- AppRepositoryPath = System.getenv("ANDROID_TEST_APP_REPOSITORY");
- assertNotNull(AppRepositoryPath);
-
- // Make sure path ends with a separator
- if (!AppRepositoryPath.endsWith(File.separator)) {
- AppRepositoryPath += File.separator;
- }
- }
-
- /**
- * Get the absolute file system location of repository test app with given filename
- * @param fileName the file name of the test app apk
- * @return {@link String} of absolute file path
- */
- private String getRepositoryTestAppFilePath(String fileDirectory, String fileName) {
- return String.format("%s%s%s%s", AppRepositoryPath, fileDirectory,
- File.separator, fileName);
- }
-
- /**
- * Get the absolute file system location of test app with given filename
- * @param fileName the file name of the test app apk
- * @return {@link String} of absolute file path
- */
- public String getTestAppFilePath(String fileName) {
- return String.format("%s%s%s", getTestAppPath(), File.separator, fileName);
- }
-
- /**
- * Stress test to verify that we can update an app multiple times on the SD card.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUpdateAppManyTimesOnSD() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating an app on SD numerous times");
-
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG));
-
- try {
- for (int i = VERSIONED_APPS_START_VERSION; i <= VERSIONED_APPS_END_VERSION; ++i) {
- String currentApkName = String.format("%s%d.apk",
- VERSIONED_APPS_FILENAME_PREFIX, i);
-
- Log.i(LOG_TAG, "Installing app " + currentApkName);
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(VERSIONED_APPS_DIRECTORY_NAME,
- currentApkName), true);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(VERSIONED_APPS_PKG));
- assertTrue(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG));
- }
- }
- finally {
- // cleanup test app
- mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG));
- }
- }
-
- /**
- * Stress test to verify that an app can be installed, uninstalled, and
- * reinstalled on SD many times.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUninstallReinstallAppOnSDManyTimes() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
- // cleanup test app just in case it was already exists
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG));
-
- for (int i = 0; i <= 500; ++i) {
- Log.i(LOG_TAG, "Installing app");
-
- try {
- // install the app
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(MISC_APPS_DIRECTORY_NAME,
- EXTERNAL_LOC_APK), false);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(EXTERNAL_LOC_PKG));
- assertTrue(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG));
- }
- finally {
- // now uninstall the app
- Log.i(LOG_TAG, "Uninstalling app");
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- mPMHostUtils.waitForPackageManager();
- assertFalse(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG));
- }
- }
- }
-
- /**
- * Stress test to verify that we can install, 20 large apps (>1mb each)
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallManyLargeAppsOnSD() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installing 20 large apps onto the sd card");
-
- try {
- // Install all the large apps
- for (int i=0; i < LARGE_APPS.length; ++i) {
- String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
- String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
-
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(pkgName);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(pkgName));
-
- Log.i(LOG_TAG, "Installing app " + apkName);
- // install the app
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(LARGE_APPS_DIRECTORY_NAME,
- apkName), false);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(pkgName));
- assertTrue(mPMHostUtils.doesPackageExist(pkgName));
- }
- }
- finally {
- // Cleanup - ensure we uninstall all large apps if they were installed
- for (int i=0; i < LARGE_APPS.length; ++i) {
- String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
- String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
-
- Log.i(LOG_TAG, "Uninstalling app " + apkName);
- // cleanup test app just in case it was accidently installed
- mPMHostUtils.uninstallApp(pkgName);
- // grep for package to make sure its not installed anymore
- assertFalse(mPMHostUtils.doesPackageExist(pkgName));
- assertFalse(mPMHostUtils.doesAppExistOnSDCard(pkgName));
- }
- }
- }
-
- /**
- * Stress test to verify that we can install many small apps onto SD.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallManyAppsOnSD() throws IOException, InterruptedException,
- InstallException, TimeoutException, AdbCommandRejectedException,
- ShellCommandUnresponsiveException {
- Log.i(LOG_TAG, "Test installing 500 small apps onto SD");
-
- try {
- for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
- String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
-
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(currentPkgName);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(currentPkgName));
-
- String currentApkName = String.format("%s%d.apk", MANY_APPS_APK_PREFIX, i);
- Log.i(LOG_TAG, "Installing app " + currentApkName);
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(MANY_APPS_DIRECTORY_NAME,
- currentApkName), true);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(currentPkgName));
- assertTrue(mPMHostUtils.doesPackageExist(currentPkgName));
- }
- }
- finally {
- for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
- String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
-
- // cleanup test app
- mPMHostUtils.uninstallApp(currentPkgName);
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(currentPkgName));
- }
- }
- }
-}
\ No newline at end of file
diff --git a/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java b/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
deleted file mode 100644
index a94555c..0000000
--- a/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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 android.net;
-
-import android.content.pm.PackageManagerHostTestUtils;
-
-import com.android.ddmlib.Log;
-import com.android.hosttest.DeviceTestCase;
-import com.android.hosttest.DeviceTestSuite;
-
-import java.io.File;
-import java.util.Hashtable;
-
-import junit.framework.Test;
-
-/**
- * Host-based tests of the DownloadManager API. (Uses a device-based app to actually invoke the
- * various tests.)
- */
-public class DownloadManagerHostTests extends DeviceTestCase {
- protected PackageManagerHostTestUtils mPMUtils = null;
-
- private static final String LOG_TAG = "android.net.DownloadManagerHostTests";
- private static final String FILE_DOWNLOAD_APK = "DownloadManagerTestApp.apk";
- private static final String FILE_DOWNLOAD_PKG = "com.android.frameworks.downloadmanagertests";
- private static final String FILE_DOWNLOAD_CLASS =
- "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
- private static final String DOWNLOAD_TEST_RUNNER_NAME =
- "com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner";
-
- // Extra parameters to pass to the TestRunner
- private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
- // Note: External environment variable ANDROID_TEST_EXTERNAL_URI must be set to point to the
- // external URI under which the files downloaded by the tests can be found. Note that the Uri
- // must be accessible by the device during a test run. Correspondingly,
- // ANDROID_TEST_EXTERNAL_LARGE_URI should point to the external URI of the folder containing
- // large files.
- private static String externalDownloadUriValue = null;
-
- Hashtable<String, String> mExtraParams = null;
-
- public static Test suite() {
- return new DeviceTestSuite(DownloadManagerHostTests.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // ensure apk path has been set before test is run
- assertNotNull(getTestAppPath());
- mPMUtils = new PackageManagerHostTestUtils(getDevice());
- externalDownloadUriValue = System.getenv("ANDROID_TEST_EXTERNAL_URI");
- assertNotNull(externalDownloadUriValue);
- mExtraParams = getExtraParams();
- }
-
- /**
- * Helper function to get extra params that can be used to pass into the helper app.
- */
- protected Hashtable<String, String> getExtraParams() {
- Hashtable<String, String> extraParams = new Hashtable<String, String>();
- extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, externalDownloadUriValue);
- return extraParams;
- }
-
- /**
- * Tests that a large download over WiFi
- * @throws Exception if the test failed at any point
- */
- public void testLargeDownloadOverWiFi() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runLargeDownloadOverWiFi", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
-
- assertTrue("Failed to install large file over WiFi in < 10 minutes!", testPassed);
- }
-
- /**
- * Spawns a device-based function to initiate a download on the device, reboots the device,
- * then waits and verifies the download succeeded.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadManagerSingleReboot() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
-
- assertTrue("Failed to initiate download properly!", testPassed);
- mPMUtils.rebootDevice();
- testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
- assertTrue("Failed to verify initiated download completed properyly!", testPassed);
- }
-
- /**
- * Spawns a device-based function to initiate a download on the device, reboots the device three
- * times (using different intervals), then waits and verifies the download succeeded.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadManagerMultipleReboots() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
-
- assertTrue("Failed to initiate download properly!", testPassed);
- Thread.sleep(5000);
-
- // Do 3 random reboots - after 13, 9, and 19 seconds
- Log.i(LOG_TAG, "First reboot...");
- mPMUtils.rebootDevice();
- Thread.sleep(13000);
- Log.i(LOG_TAG, "Second reboot...");
- mPMUtils.rebootDevice();
- Thread.sleep(9000);
- Log.i(LOG_TAG, "Third reboot...");
- mPMUtils.rebootDevice();
- Thread.sleep(19000);
- testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
- assertTrue("Failed to verify initiated download completed properyly!", testPassed);
- }
-
- /**
- * Spawns a device-based function to test download while WiFi is enabled/disabled multiple times
- * during the download.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleWiFiEnableDisable() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleWiFiEnableDisable",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test switching on/off both airplane mode and WiFi
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleSwitching() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleSwitching",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test switching on/off airplane mode multiple times
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleAirplaneModeEnableDisable() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleAirplaneModeEnableDisable",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test 15 concurrent downloads of 5,000,000-byte files
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleSimultaneously() throws Exception {
- mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
- File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
-
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleSimultaneously",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 5094df18..381e65b 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -19,6 +19,7 @@
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.util.TypedValue;
import java.io.BufferedInputStream;
@@ -303,6 +304,7 @@
/* do nothing.
If the exception happened on open, bm will be null.
*/
+ Log.e("BitmapFactory", "Unable to decode stream: " + e);
} finally {
if (stream != null) {
try {
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f9b8a5f..f68f9dc 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1055,7 +1055,6 @@
* Get the text Locale.
*
* @return the paint's Locale used for drawing text, never null.
- * @hide
*/
public Locale getTextLocale() {
return mLocale;
@@ -1086,7 +1085,6 @@
* job in certain ambiguous cases
*
* @param locale the paint's locale value for drawing text, must not be null.
- * @hide
*/
public void setTextLocale(Locale locale) {
if (locale == null) {
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 87421b1..e82ccd4 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -385,7 +385,7 @@
Shader shader = state.mPaint.getShader();
if (shader == null) {
if (mApplyGravity) {
- final int layoutDirection = getResolvedLayoutDirectionSelf();
+ final int layoutDirection = getLayoutDirection();
Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight,
getBounds(), mDstRect, layoutDirection);
mApplyGravity = false;
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index c41dd07..bade9b4 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -209,7 +209,7 @@
if ((mClipState.mOrientation & VERTICAL) != 0) {
h -= (h - ih) * (10000 - level) / 10000;
}
- final int layoutDirection = getResolvedLayoutDirectionSelf();
+ final int layoutDirection = getLayoutDirection();
Gravity.apply(mClipState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 785582c..07bcbdc 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -124,6 +124,8 @@
private WeakReference<Callback> mCallback = null;
private boolean mVisible = true;
+ private int mLayoutDirection;
+
/**
* Draw in its bounds (set via setBounds) respecting optional effects such
* as alpha (set via setAlpha) and color filter (set via setColorFilter).
@@ -296,19 +298,6 @@
}
/**
- * Implement this interface if you want to create an drawable that is RTL aware
- * @hide
- */
- public static interface Callback2 extends Callback {
- /**
- * A Drawable can call this to get the resolved layout direction of the <var>who</var>.
- *
- * @param who The drawable being queried.
- */
- public int getResolvedLayoutDirection(Drawable who);
- }
-
- /**
* Bind a {@link Callback} object to this Drawable. Required for clients
* that want to support animated drawables.
*
@@ -385,15 +374,27 @@
}
/**
- * Get the resolved layout direction of this Drawable.
- * @hide
+ * Returns the resolved layout direction for this Drawable.
+ *
+ * @return One of {@link View#LAYOUT_DIRECTION_LTR},
+ * {@link View#LAYOUT_DIRECTION_RTL}
*/
- public int getResolvedLayoutDirectionSelf() {
- final Callback callback = getCallback();
- if (callback == null || !(callback instanceof Callback2)) {
- return View.LAYOUT_DIRECTION_LTR;
+ public int getLayoutDirection() {
+ return mLayoutDirection;
+ }
+
+ /**
+ * Set the layout direction for this drawable. Should be a resolved direction as the
+ * Drawable as no capacity to do the resolution on his own.
+ *
+ * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR},
+ * {@link View#LAYOUT_DIRECTION_RTL},
+ *
+ */
+ public void setLayoutDirection(int layoutDirection) {
+ if (getLayoutDirection() != layoutDirection) {
+ mLayoutDirection = layoutDirection;
}
- return ((Callback2) callback).getResolvedLayoutDirection(this);
}
/**
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index ccad250..bd2b2f0 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -221,7 +221,7 @@
final int ih = min ? mScaleState.mDrawable.getIntrinsicHeight() : 0;
h -= (int) ((h - ih) * (10000 - level) * mScaleState.mScaleHeight / 10000);
}
- final int layoutDirection = getResolvedLayoutDirectionSelf();
+ final int layoutDirection = getLayoutDirection();
Gravity.apply(mScaleState.mGravity, w, h, bounds, r, layoutDirection);
if (w > 0 && h > 0) {
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 3d5d1a9..8c8ff4d 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -489,7 +489,7 @@
static void
nAllocationSetSurface(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc, jobject sur)
{
- LOG_API("nAllocationSetSurfaceTexture, con(%p), alloc(%p), surface(%p)",
+ LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)",
con, alloc, (Surface *)sur);
sp<Surface> s;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b6e4659..b5613f3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -49,6 +49,7 @@
private final Context mContext;
private long mVolumeKeyUpTime;
private final boolean mUseMasterVolume;
+ private final boolean mUseVolumeKeySounds;
private static String TAG = "AudioManager";
/**
@@ -412,6 +413,8 @@
mContext = context;
mUseMasterVolume = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useMasterVolume);
+ mUseVolumeKeySounds = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_useVolumeKeySounds);
}
private static IAudioService getService()
@@ -463,6 +466,7 @@
* responsive to the user.
*/
int flags = FLAG_SHOW_UI | FLAG_VIBRATE;
+
if (mUseMasterVolume) {
adjustMasterVolume(
keyCode == KeyEvent.KEYCODE_VOLUME_UP
@@ -502,18 +506,17 @@
* Play a sound. This is done on key up since we don't want the
* sound to play when a user holds down volume down to mute.
*/
- if (mUseMasterVolume) {
- if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ if (mUseVolumeKeySounds) {
+ if (mUseMasterVolume) {
adjustMasterVolume(ADJUST_SAME, FLAG_PLAY_SOUND);
+ } else {
+ int flags = FLAG_PLAY_SOUND;
+ adjustSuggestedStreamVolume(
+ ADJUST_SAME,
+ stream,
+ flags);
}
- } else {
- int flags = FLAG_PLAY_SOUND;
- adjustSuggestedStreamVolume(
- ADJUST_SAME,
- stream,
- flags);
}
-
mVolumeKeyUpTime = SystemClock.uptimeMillis();
break;
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 6f8b809..5cd5ff5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -314,6 +314,7 @@
private int mMtpObjectHandle;
private final String mExternalStoragePath;
+ private final boolean mExternalIsEmulated;
/** whether to use bulk inserts or individual inserts for each item */
private static final boolean ENABLE_BULK_INSERTS = true;
@@ -392,6 +393,7 @@
setDefaultRingtoneFileNames();
mExternalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
+ mExternalIsEmulated = Environment.isExternalStorageEmulated();
//mClient.testGenreNameConverter();
}
@@ -543,13 +545,28 @@
boolean music = (lowpath.indexOf(MUSIC_DIR) > 0) ||
(!ringtones && !notifications && !alarms && !podcasts);
+ boolean isaudio = MediaFile.isAudioFileType(mFileType);
+ boolean isvideo = MediaFile.isVideoFileType(mFileType);
+ boolean isimage = MediaFile.isImageFileType(mFileType);
+
+ if (isaudio || isvideo || isimage) {
+ if (mExternalIsEmulated && path.startsWith(mExternalStoragePath)) {
+ // try to rewrite the path to bypass the sd card fuse layer
+ String directPath = Environment.getMediaStorageDirectory() +
+ path.substring(mExternalStoragePath.length());
+ File f = new File(directPath);
+ if (f.exists()) {
+ path = directPath;
+ }
+ }
+ }
+
// we only extract metadata for audio and video files
- if (MediaFile.isAudioFileType(mFileType)
- || MediaFile.isVideoFileType(mFileType)) {
+ if (isaudio || isvideo) {
processFile(path, mimeType, this);
}
- if (MediaFile.isImageFileType(mFileType)) {
+ if (isimage) {
processImageFile(path);
}
@@ -972,7 +989,6 @@
}
values.put(FileColumns.MEDIA_TYPE, mediaType);
}
-
mMediaProvider.update(result, values, null, null);
}
diff --git a/media/libstagefright/codecs/aacdec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/aacdec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/aacdec/NOTICE b/media/libstagefright/codecs/aacdec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/aacenc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/aacenc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/aacenc/NOTICE b/media/libstagefright/codecs/aacenc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/aacenc/SampleCode/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/SampleCode/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/NOTICE b/media/libstagefright/codecs/aacenc/SampleCode/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/SampleCode/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrnb/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrnb/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/NOTICE b/media/libstagefright/codecs/amrnb/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrnb/common/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrnb/common/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/common/NOTICE b/media/libstagefright/codecs/amrnb/common/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/common/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/dec/NOTICE b/media/libstagefright/codecs/amrnb/dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrnb/enc/NOTICE b/media/libstagefright/codecs/amrnb/enc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrwb/NOTICE b/media/libstagefright/codecs/amrwb/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrwbenc/NOTICE b/media/libstagefright/codecs/amrwbenc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/amrwbenc/SampleCode/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/NOTICE b/media/libstagefright/codecs/amrwbenc/SampleCode/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/avc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/avc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/avc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/avc/NOTICE b/media/libstagefright/codecs/avc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/avc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/avc/common/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/avc/common/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/avc/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/avc/common/NOTICE b/media/libstagefright/codecs/avc/common/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/avc/common/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/avc/enc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/avc/enc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/avc/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/avc/enc/NOTICE b/media/libstagefright/codecs/avc/enc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/avc/enc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/common/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/common/NOTICE b/media/libstagefright/codecs/common/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/common/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/g711/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/g711/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/g711/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/g711/NOTICE b/media/libstagefright/codecs/g711/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/g711/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/g711/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/g711/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/g711/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/g711/dec/NOTICE b/media/libstagefright/codecs/g711/dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/g711/dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/m4v_h263/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/m4v_h263/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/m4v_h263/NOTICE b/media/libstagefright/codecs/m4v_h263/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/m4v_h263/dec/NOTICE b/media/libstagefright/codecs/m4v_h263/dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/enc/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/m4v_h263/enc/NOTICE b/media/libstagefright/codecs/m4v_h263/enc/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/enc/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/mp3dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/mp3dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/mp3dec/NOTICE b/media/libstagefright/codecs/mp3dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/on2/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/on2/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/on2/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/on2/NOTICE b/media/libstagefright/codecs/on2/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/on2/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/on2/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/on2/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/on2/dec/NOTICE b/media/libstagefright/codecs/on2/dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/on2/dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/vorbis/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/vorbis/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/vorbis/NOTICE b/media/libstagefright/codecs/vorbis/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/media/libstagefright/codecs/vorbis/dec/MODULE_LICENSE_APACHE2 b/media/libstagefright/codecs/vorbis/dec/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/MODULE_LICENSE_APACHE2
diff --git a/media/libstagefright/codecs/vorbis/dec/NOTICE b/media/libstagefright/codecs/vorbis/dec/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/media/libstagefright/codecs/vorbis/dec/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/packages/DefaultContainerService/res/values-zh-rCN/strings.xml b/packages/DefaultContainerService/res/values-zh-rCN/strings.xml
index 65928b1..cb117a2 100644
--- a/packages/DefaultContainerService/res/values-zh-rCN/strings.xml
+++ b/packages/DefaultContainerService/res/values-zh-rCN/strings.xml
@@ -20,5 +20,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="service_name" msgid="4841491635055379553">"软件包访问帮助程序"</string>
+ <string name="service_name" msgid="4841491635055379553">"应用包访问权限帮助程序"</string>
</resources>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index f09c010..6eca3b6 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -246,6 +246,7 @@
throw new IllegalStateException(e);
}
}
+
};
public DefaultContainerService() {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index bcd0add..cfdd63d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1639,8 +1639,12 @@
loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
R.string.def_accessibility_screen_reader_url);
- loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
- R.bool.def_lockscreen_disabled);
+ if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
+ loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
+ } else {
+ loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED,
+ R.bool.def_lockscreen_disabled);
+ }
loadBooleanSetting(stmt, Settings.Secure.DEVICE_PROVISIONED,
R.bool.def_device_provisioned);
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 47e5b71..cf93f9f 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -56,7 +56,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="none"
- android:overScrollMode="ifContentScrolls"
+ android:overScrollMode="never"
android:layout_marginTop="@dimen/notification_panel_header_height"
>
<com.android.systemui.statusbar.policy.NotificationRowLayout
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel.xml b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
index 48a188b..f6d56d4 100644
--- a/packages/SystemUI/res/layout/system_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
@@ -57,6 +57,7 @@
android:id="@+id/notification_scroller"
android:layout_height="wrap_content"
android:layout_width="match_parent"
+ android:overScrollMode="never"
android:layout_weight="1"
>
<com.android.systemui.statusbar.policy.NotificationRowLayout
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 26dba67..66add1a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -65,5 +65,8 @@
<!-- Vibration duration for MultiWaveView used in SearchPanelView -->
<integer translatable="false" name="config_search_panel_view_vibration_duration">20</integer>
+
+ <!-- The length of the vibration when the notificaiotn pops open. -->
+ <integer name="one_finger_pop_duration_ms">10</integer>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6c40461..aecad0b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -150,4 +150,7 @@
<!-- Height of the carrier/wifi name label -->
<dimen name="carrier_label_height">24dp</dimen>
+
+ <!-- The distance you can pull a notificaiton before it pops open -->
+ <dimen name="one_finger_pop_limit">40dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 5dd15c3..575697b 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -22,11 +22,13 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.os.Vibrator;
import android.util.Slog;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
@@ -63,6 +65,9 @@
private Context mContext;
private boolean mStretching;
+ private boolean mPullingWithOneFinger;
+ private boolean mWatchingForPull;
+ private boolean mHasPopped;
private View mEventSource;
private View mCurrView;
private View mCurrViewTopGlow;
@@ -70,7 +75,12 @@
private float mOldHeight;
private float mNaturalHeight;
private float mInitialTouchFocusY;
+ private float mInitialTouchY;
private float mInitialTouchSpan;
+ private int mTouchSlop;
+ private int mLastMotionY;
+ private float mPopLimit;
+ private int mPopDuration;
private Callback mCallback;
private ScaleGestureDetector mDetector;
private ViewScaler mScaler;
@@ -78,6 +88,7 @@
private AnimatorSet mGlowAnimationSet;
private ObjectAnimator mGlowTopAnimation;
private ObjectAnimator mGlowBottomAnimation;
+ private Vibrator mVibrator;
private int mSmallSize;
private int mLargeSize;
@@ -85,6 +96,8 @@
private int mGravity;
+ private View mScrollView;
+
private class ViewScaler {
View mView;
@@ -142,6 +155,8 @@
mGravity = Gravity.TOP;
mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
mScaleAnimation.setDuration(EXPAND_DURATION);
+ mPopLimit = mContext.getResources().getDimension(R.dimen.one_finger_pop_limit);
+ mPopDuration = mContext.getResources().getInteger(R.integer.one_finger_pop_duration_ms);
AnimatorListenerAdapter glowVisibilityController = new AnimatorListenerAdapter() {
@Override
@@ -169,6 +184,9 @@
mGlowAnimationSet.play(mGlowTopAnimation).with(mGlowBottomAnimation);
mGlowAnimationSet.setDuration(GLOW_DURATION);
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+ mTouchSlop = configuration.getScaledTouchSlop();
+
mDetector =
new ScaleGestureDetector(context,
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@@ -178,23 +196,12 @@
float x = detector.getFocusX();
float y = detector.getFocusY();
- View v = null;
- if (mEventSource != null) {
- int[] location = new int[2];
- mEventSource.getLocationOnScreen(location);
- x += (float) location[0];
- y += (float) location[1];
- v = mCallback.getChildAtRawPosition(x, y);
- } else {
- v = mCallback.getChildAtPosition(x, y);
- }
-
// your fingers have to be somewhat close to the bounds of the view in question
mInitialTouchFocusY = detector.getFocusY();
mInitialTouchSpan = Math.abs(detector.getCurrentSpan());
if (DEBUG) Slog.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
- mStretching = initScale(v);
+ mStretching = initScale(findView(x, y));
return mStretching;
}
@@ -210,20 +217,11 @@
drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
float pull = Math.abs(drag) + Math.abs(span) + 1f;
float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
- if (DEBUG) Slog.d(TAG, "current span handle is: " + hand);
- hand = hand + mOldHeight;
- float target = hand;
- if (DEBUG) Slog.d(TAG, "target is: " + target);
- hand = hand < mSmallSize ? mSmallSize : (hand > mLargeSize ? mLargeSize : hand);
- hand = hand > mNaturalHeight ? mNaturalHeight : hand;
- if (DEBUG) Slog.d(TAG, "scale continues: hand =" + hand);
- mScaler.setHeight(hand);
+ float target = hand + mOldHeight;
+ float newHeight = clamp(target);
+ mScaler.setHeight(newHeight);
- // glow if overscale
- float stretch = (float) Math.abs((target - hand) / mMaximumStretch);
- float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
- if (DEBUG) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
- setGlow(GLOW_BASE + strength * (1f - GLOW_BASE));
+ setGlow(calculateGlow(target, newHeight));
return true;
}
@@ -233,10 +231,56 @@
// I guess we're alone now
if (DEBUG) Slog.d(TAG, "scale end");
finishScale(false);
+ mStretching = false;
}
});
}
+ private float clamp(float target) {
+ float out = target;
+ out = out < mSmallSize ? mSmallSize : (out > mLargeSize ? mLargeSize : out);
+ out = out > mNaturalHeight ? mNaturalHeight : out;
+ return out;
+ }
+
+ private View findView(float x, float y) {
+ View v = null;
+ if (mEventSource != null) {
+ int[] location = new int[2];
+ mEventSource.getLocationOnScreen(location);
+ x += (float) location[0];
+ y += (float) location[1];
+ v = mCallback.getChildAtRawPosition(x, y);
+ } else {
+ v = mCallback.getChildAtPosition(x, y);
+ }
+ return v;
+ }
+
+ private boolean isInside(View v, float x, float y) {
+ if (DEBUG) Slog.d(TAG, "isinside (" + x + ", " + y + ")");
+
+ if (v == null) {
+ if (DEBUG) Slog.d(TAG, "isinside null subject");
+ return false;
+ }
+ if (mEventSource != null) {
+ int[] location = new int[2];
+ mEventSource.getLocationOnScreen(location);
+ x += (float) location[0];
+ y += (float) location[1];
+ if (DEBUG) Slog.d(TAG, " to global (" + x + ", " + y + ")");
+ }
+ int[] location = new int[2];
+ v.getLocationOnScreen(location);
+ x -= (float) location[0];
+ y -= (float) location[1];
+ if (DEBUG) Slog.d(TAG, " to local (" + x + ", " + y + ")");
+ if (DEBUG) Slog.d(TAG, " inside (" + v.getWidth() + ", " + v.getHeight() + ")");
+ boolean inside = (x > 0f && y > 0f && x < v.getWidth() & y < v.getHeight());
+ return inside;
+ }
+
public void setEventSource(View eventSource) {
mEventSource = eventSource;
}
@@ -245,13 +289,25 @@
mGravity = gravity;
}
+ public void setScrollView(View scrollView) {
+ mScrollView = scrollView;
+ }
+
+ private float calculateGlow(float target, float actual) {
+ // glow if overscale
+ float stretch = (float) Math.abs((target - actual) / mMaximumStretch);
+ float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
+ if (DEBUG) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
+ return (GLOW_BASE + strength * (1f - GLOW_BASE));
+ }
+
public void setGlow(float glow) {
if (!mGlowAnimationSet.isRunning() || glow == 0f) {
if (mGlowAnimationSet.isRunning()) {
mGlowAnimationSet.cancel();
}
if (mCurrViewTopGlow != null && mCurrViewBottomGlow != null) {
- if (glow == 0f || mCurrViewTopGlow.getAlpha() == 0f) {
+ if (glow == 0f || mCurrViewTopGlow.getAlpha() == 0f) {
// animate glow in and out
mGlowTopAnimation.setTarget(mCurrViewTopGlow);
mGlowBottomAnimation.setTarget(mCurrViewBottomGlow);
@@ -278,23 +334,100 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Slog.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
- " stretching=" + mStretching);
+ " stretching=" + mStretching +
+ " onefinger=" + mPullingWithOneFinger);
+ // check for a two-finger gesture
mDetector.onTouchEvent(ev);
- return mStretching;
+ if (mStretching) {
+ return true;
+ } else {
+ final int action = ev.getAction();
+ if ((action == MotionEvent.ACTION_MOVE) && mPullingWithOneFinger) {
+ return true;
+ }
+ if (mScrollView != null && mScrollView.getScrollY() > 0) {
+ return false;
+ }
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
+ if (mWatchingForPull) {
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
+ final int yDiff = y - mLastMotionY;
+ if (yDiff > mTouchSlop) {
+ mLastMotionY = y;
+ mPullingWithOneFinger = initScale(findView(x, y));
+ if (mPullingWithOneFinger) {
+ mInitialTouchFocusY = mLastMotionY;
+ mHasPopped = false;
+ }
+ }
+ if (DEBUG) Slog.d(TAG, "examining move: " + yDiff);
+ } else {
+ if (DEBUG) Slog.d(TAG, "uninteresting move");
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_DOWN:
+ mWatchingForPull = isInside(mScrollView, ev.getX(), ev.getY());
+ mLastMotionY = (int) ev.getY();
+ if (DEBUG) Slog.d(TAG, "action down: " + mWatchingForPull);
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ if (mPullingWithOneFinger) {
+ finishScale(false);
+ }
+ mPullingWithOneFinger = false;
+ mWatchingForPull = false;
+ if (DEBUG) Slog.d(TAG, "action up: " + mWatchingForPull);
+ break;
+ }
+ return mPullingWithOneFinger;
+ }
}
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
- if (DEBUG) Slog.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
+ if (DEBUG) Slog.d(TAG, "touch: act=" + (action) +
+ " stretching=" + mStretching +
+ " onefinger=" + mPullingWithOneFinger);
if (mStretching) {
if (DEBUG) Slog.d(TAG, "detector ontouch");
mDetector.onTouchEvent(ev);
}
switch (action) {
+ case MotionEvent.ACTION_MOVE: {
+ if (mPullingWithOneFinger) {
+ float hand = ev.getY() - mInitialTouchFocusY;
+ if (mHasPopped || hand > mPopLimit) {
+ if (!mHasPopped) {
+ vibrate(mPopDuration);
+ mHasPopped = true;
+ }
+ hand = hand + mOldHeight;
+ float target = hand;
+ float newHeight = clamp(target);
+ mScaler.setHeight(newHeight);
+ // glow if overscale
+ setGlow(calculateGlow(target, newHeight));
+ } else {
+ setGlow(calculateGlow(4f * hand, 0f));
+ }
+ return true;
+ }
+ break;
+ }
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (DEBUG) Slog.d(TAG, "cancel");
mStretching = false;
+ if (mPullingWithOneFinger) {
+ finishScale(false);
+ mPullingWithOneFinger = false;
+ }
clearView();
break;
}
@@ -303,7 +436,6 @@
private boolean initScale(View v) {
if (v != null) {
if (DEBUG) Slog.d(TAG, "scale begins on view: " + v);
- mStretching = true;
setView(v);
setGlow(GLOW_BASE);
mScaler.setView(v);
@@ -318,8 +450,10 @@
if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
" mNaturalHeight: " + mNaturalHeight);
v.getParent().requestDisallowInterceptTouchEvent(true);
+ return true;
+ } else {
+ return false;
}
- return mStretching;
}
private void finishScale(boolean force) {
@@ -337,7 +471,6 @@
mScaleAnimation.setFloatValues(h);
mScaleAnimation.setupStartValues();
mScaleAnimation.start();
- mStretching = false;
setGlow(0f);
mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
@@ -357,7 +490,7 @@
mCurrViewTopGlow = g.findViewById(R.id.top_glow);
mCurrViewBottomGlow = g.findViewById(R.id.bottom_glow);
if (DEBUG) {
- String debugLog = "Looking for glows: " +
+ String debugLog = "Looking for glows: " +
(mCurrViewTopGlow != null ? "found top " : "didn't find top") +
(mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
Slog.v(TAG, debugLog);
@@ -369,6 +502,17 @@
public void onClick(View v) {
initScale(v);
finishScale(true);
+ }
+ /**
+ * Triggers haptic feedback.
+ */
+ private synchronized void vibrate(long duration) {
+ if (mVibrator == null) {
+ mVibrator = (android.os.Vibrator)
+ mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ mVibrator.vibrate(duration);
}
}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 9317561..2628631 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -53,6 +53,7 @@
int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
mExpandHelper.setEventSource(this);
+ mExpandHelper.setScrollView(scroller);
}
@Override
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index fc187ce..e9b8267 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -29,6 +29,8 @@
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ScaleDrawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Handler;
@@ -43,6 +45,7 @@
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;
+import android.view.Gravity;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.View;
@@ -52,6 +55,7 @@
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import java.util.ArrayList;
@@ -243,8 +247,10 @@
for (final UserInfo user : users) {
boolean isCurrentUser = currentUser == null
? user.id == 0 : (currentUser.id == user.id);
+ Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
+ : null;
SinglePressAction switchToUser = new SinglePressAction(
- com.android.internal.R.drawable.ic_menu_cc,
+ com.android.internal.R.drawable.ic_menu_cc, icon,
(user.name != null ? user.name : "Primary")
+ (isCurrentUser ? " \u2714" : "")) {
public void onPress() {
@@ -439,6 +445,7 @@
*/
private static abstract class SinglePressAction implements Action {
private final int mIconResId;
+ private final Drawable mIcon;
private final int mMessageResId;
private final CharSequence mMessage;
@@ -446,13 +453,23 @@
mIconResId = iconResId;
mMessageResId = messageResId;
mMessage = null;
+ mIcon = null;
+ }
+
+ protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) {
+ mIconResId = iconResId;
+ mMessageResId = 0;
+ mMessage = message;
+ mIcon = icon;
}
protected SinglePressAction(int iconResId, CharSequence message) {
mIconResId = iconResId;
mMessageResId = 0;
mMessage = message;
+ mIcon = null;
}
+
public boolean isEnabled() {
return true;
}
@@ -471,8 +488,12 @@
TextView messageView = (TextView) v.findViewById(R.id.message);
v.findViewById(R.id.status).setVisibility(View.GONE);
-
- icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+ if (mIcon != null) {
+ icon.setImageDrawable(mIcon);
+ icon.setScaleType(ScaleType.CENTER_CROP);
+ } else if (mIconResId != 0) {
+ icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+ }
if (mMessage != null) {
messageView.setText(mMessage);
} else {
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index df2e1aa..7bc6a88 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -223,6 +223,7 @@
final String action = intent.getAction();
boolean added = false;
boolean changed = false;
+ boolean providersModified = false;
String pkgList[] = null;
if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -254,12 +255,12 @@
|| (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false))) {
for (String pkgName : pkgList) {
// The package was just upgraded
- updateProvidersForPackageLocked(pkgName);
+ providersModified |= updateProvidersForPackageLocked(pkgName);
}
} else {
// The package was just added
for (String pkgName : pkgList) {
- addProvidersForPackageLocked(pkgName);
+ providersModified |= addProvidersForPackageLocked(pkgName);
}
}
saveStateLocked();
@@ -272,12 +273,20 @@
synchronized (mAppWidgetIds) {
ensureStateLoadedLocked();
for (String pkgName : pkgList) {
- removeProvidersForPackageLocked(pkgName);
+ providersModified |= removeProvidersForPackageLocked(pkgName);
saveStateLocked();
}
}
}
}
+
+ if (providersModified) {
+ // If the set of providers has been modified, notify each active AppWidgetHost
+ synchronized (mAppWidgetIds) {
+ ensureStateLoadedLocked();
+ notifyHostsForProvidersChangedLocked();
+ }
+ }
}
private void dumpProvider(Provider p, int index, PrintWriter pw) {
@@ -1637,7 +1646,8 @@
getSettingsFile(mUserId).delete();
}
- void addProvidersForPackageLocked(String pkgName) {
+ boolean addProvidersForPackageLocked(String pkgName) {
+ boolean providersAdded = false;
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.setPackage(pkgName);
List<ResolveInfo> broadcastReceivers;
@@ -1647,7 +1657,7 @@
PackageManager.GET_META_DATA, mUserId);
} catch (RemoteException re) {
// Shouldn't happen, local call
- return;
+ return false;
}
final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();
for (int i = 0; i < N; i++) {
@@ -1658,11 +1668,15 @@
}
if (pkgName.equals(ai.packageName)) {
addProviderLocked(ri);
+ providersAdded = true;
}
}
+
+ return providersAdded;
}
- void updateProvidersForPackageLocked(String pkgName) {
+ boolean updateProvidersForPackageLocked(String pkgName) {
+ boolean providersUpdated = false;
HashSet<String> keep = new HashSet<String>();
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.setPackage(pkgName);
@@ -1673,7 +1687,7 @@
PackageManager.GET_META_DATA, mUserId);
} catch (RemoteException re) {
// Shouldn't happen, local call
- return;
+ return false;
}
// add the missing ones and collect which ones to keep
@@ -1690,6 +1704,7 @@
if (p == null) {
if (addProviderLocked(ri)) {
keep.add(ai.name);
+ providersUpdated = true;
}
} else {
Provider parsed = parseProviderInfoXml(component, ri);
@@ -1724,6 +1739,7 @@
}
// Now that we've told the host, push out an update.
sendUpdateIntentLocked(p, appWidgetIds);
+ providersUpdated = true;
}
}
}
@@ -1737,16 +1753,21 @@
if (pkgName.equals(p.info.provider.getPackageName())
&& !keep.contains(p.info.provider.getClassName())) {
removeProviderLocked(i, p);
+ providersUpdated = true;
}
}
+
+ return providersUpdated;
}
- void removeProvidersForPackageLocked(String pkgName) {
+ boolean removeProvidersForPackageLocked(String pkgName) {
+ boolean providersRemoved = false;
int N = mInstalledProviders.size();
for (int i = N - 1; i >= 0; i--) {
Provider p = mInstalledProviders.get(i);
if (pkgName.equals(p.info.provider.getPackageName())) {
removeProviderLocked(i, p);
+ providersRemoved = true;
}
}
@@ -1761,5 +1782,24 @@
deleteHostLocked(host);
}
}
+
+ return providersRemoved;
+ }
+
+ void notifyHostsForProvidersChangedLocked() {
+ final int N = mHosts.size();
+ for (int i = N - 1; i >= 0; i--) {
+ Host host = mHosts.get(i);
+ try {
+ if (host.callbacks != null) {
+ host.callbacks.providersChanged();
+ }
+ } catch (RemoteException ex) {
+ // It failed; remove the callback. No need to prune because
+ // we know that this host is still referenced by this
+ // instance.
+ host.callbacks = null;
+ }
+ }
}
}
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index ab9ae69..0a6f23c 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -68,7 +68,7 @@
* a degree Centigrade</p>
* <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p>
*/
-class BatteryService extends Binder {
+public class BatteryService extends Binder {
private static final String TAG = BatteryService.class.getSimpleName();
private static final boolean LOCAL_LOGV = false;
@@ -148,12 +148,12 @@
update();
}
- final boolean isPowered() {
+ public final boolean isPowered() {
// assume we are powered if battery state is unknown so the "stay on while plugged in" option will work.
return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
}
- final boolean isPowered(int plugTypeSet) {
+ public final boolean isPowered(int plugTypeSet) {
// assume we are powered if battery state is unknown so
// the "stay on while plugged in" option will work.
if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
@@ -172,7 +172,7 @@
return (plugTypeSet & plugTypeBit) != 0;
}
- final int getPlugType() {
+ public final int getPlugType() {
return mPlugType;
}
@@ -195,7 +195,7 @@
};
// returns battery level as a percentage
- final int getBatteryLevel() {
+ public final int getBatteryLevel() {
return mBatteryLevel;
}
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 64789d3..72c0767 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,6 +16,8 @@
package com.android.server;
+import com.android.server.power.PowerManagerService;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 41f7335..dd50beb 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -114,6 +114,8 @@
# Package Manager ready:
3100 boot_progress_pms_ready (time|2|3)
# + check activity_launch_time for Home app
+# Value of "unknown sources" setting at app install time
+3110 unknown_sources_enabled (value|1)
# ---------------------------
diff --git a/services/java/com/android/server/LightsService.java b/services/java/com/android/server/LightsService.java
index 1e95f3e..89bfcac 100644
--- a/services/java/com/android/server/LightsService.java
+++ b/services/java/com/android/server/LightsService.java
@@ -31,29 +31,29 @@
private static final String TAG = "LightsService";
private static final boolean DEBUG = false;
- static final int LIGHT_ID_BACKLIGHT = 0;
- static final int LIGHT_ID_KEYBOARD = 1;
- static final int LIGHT_ID_BUTTONS = 2;
- static final int LIGHT_ID_BATTERY = 3;
- static final int LIGHT_ID_NOTIFICATIONS = 4;
- static final int LIGHT_ID_ATTENTION = 5;
- static final int LIGHT_ID_BLUETOOTH = 6;
- static final int LIGHT_ID_WIFI = 7;
- static final int LIGHT_ID_COUNT = 8;
+ public static final int LIGHT_ID_BACKLIGHT = 0;
+ public static final int LIGHT_ID_KEYBOARD = 1;
+ public static final int LIGHT_ID_BUTTONS = 2;
+ public static final int LIGHT_ID_BATTERY = 3;
+ public static final int LIGHT_ID_NOTIFICATIONS = 4;
+ public static final int LIGHT_ID_ATTENTION = 5;
+ public static final int LIGHT_ID_BLUETOOTH = 6;
+ public static final int LIGHT_ID_WIFI = 7;
+ public static final int LIGHT_ID_COUNT = 8;
- static final int LIGHT_FLASH_NONE = 0;
- static final int LIGHT_FLASH_TIMED = 1;
- static final int LIGHT_FLASH_HARDWARE = 2;
+ public static final int LIGHT_FLASH_NONE = 0;
+ public static final int LIGHT_FLASH_TIMED = 1;
+ public static final int LIGHT_FLASH_HARDWARE = 2;
/**
* Light brightness is managed by a user setting.
*/
- static final int BRIGHTNESS_MODE_USER = 0;
+ public static final int BRIGHTNESS_MODE_USER = 0;
/**
* Light brightness is managed by a light sensor.
*/
- static final int BRIGHTNESS_MODE_SENSOR = 1;
+ public static final int BRIGHTNESS_MODE_SENSOR = 1;
private final Light mLights[] = new Light[LIGHT_ID_COUNT];
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index f71125a..92af9a9 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -35,6 +35,9 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
import java.util.LinkedList;
/**
@@ -482,102 +485,108 @@
private static class ResponseQueue {
- private static class Response {
+ private static class PendingCmd {
public int cmdNum;
- public LinkedList<NativeDaemonEvent> responses = new LinkedList<NativeDaemonEvent>();
+ public BlockingQueue<NativeDaemonEvent> responses =
+ new ArrayBlockingQueue<NativeDaemonEvent>(10);
public String request;
- public Response(int c, String r) {cmdNum = c; request = r;}
+
+ // The availableResponseCount member is used to track when we can remove this
+ // instance from the ResponseQueue.
+ // This is used under the protection of a sync of the mPendingCmds object.
+ // A positive value means we've had more writers retreive this object while
+ // a negative value means we've had more readers. When we've had an equal number
+ // (it goes to zero) we can remove this object from the mPendingCmds list.
+ // Note that we may have more responses for this command (and more readers
+ // coming), but that would result in a new PendingCmd instance being created
+ // and added with the same cmdNum.
+ // Also note that when this goes to zero it just means a parity of readers and
+ // writers have retrieved this object - not that they are done using it. The
+ // responses queue may well have more responses yet to be read or may get more
+ // responses added to it. But all those readers/writers have retreived and
+ // hold references to this instance already so it can be removed from
+ // mPendingCmds queue.
+ public int availableResponseCount;
+ public PendingCmd(int c, String r) {cmdNum = c; request = r;}
}
- private final LinkedList<Response> mResponses;
+ private final LinkedList<PendingCmd> mPendingCmds;
private int mMaxCount;
ResponseQueue(int maxCount) {
- mResponses = new LinkedList<Response>();
+ mPendingCmds = new LinkedList<PendingCmd>();
mMaxCount = maxCount;
}
public void add(int cmdNum, NativeDaemonEvent response) {
- Response found = null;
- synchronized (mResponses) {
- for (Response r : mResponses) {
- if (r.cmdNum == cmdNum) {
- found = r;
+ PendingCmd found = null;
+ synchronized (mPendingCmds) {
+ for (PendingCmd pendingCmd : mPendingCmds) {
+ if (pendingCmd.cmdNum == cmdNum) {
+ found = pendingCmd;
break;
}
}
if (found == null) {
// didn't find it - make sure our queue isn't too big before adding
- // another..
- while (mResponses.size() >= mMaxCount) {
+ while (mPendingCmds.size() >= mMaxCount) {
Slog.e("NativeDaemonConnector.ResponseQueue",
- "more buffered than allowed: " + mResponses.size() +
+ "more buffered than allowed: " + mPendingCmds.size() +
" >= " + mMaxCount);
// let any waiter timeout waiting for this
- Response r = mResponses.remove();
+ PendingCmd pendingCmd = mPendingCmds.remove();
Slog.e("NativeDaemonConnector.ResponseQueue",
- "Removing request: " + r.request + " (" + r.cmdNum + ")");
+ "Removing request: " + pendingCmd.request + " (" +
+ pendingCmd.cmdNum + ")");
}
- found = new Response(cmdNum, null);
- mResponses.add(found);
+ found = new PendingCmd(cmdNum, null);
+ mPendingCmds.add(found);
}
- found.responses.add(response);
+ found.availableResponseCount++;
+ // if a matching remove call has already retrieved this we can remove this
+ // instance from our list
+ if (found.availableResponseCount == 0) mPendingCmds.remove(found);
}
- synchronized (found) {
- found.notify();
- }
+ try {
+ found.responses.put(response);
+ } catch (InterruptedException e) { }
}
// note that the timeout does not count time in deep sleep. If you don't want
// the device to sleep, hold a wakelock
public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String origCmd) {
- long endTime = SystemClock.uptimeMillis() + timeoutMs;
- long nowTime;
- Response found = null;
- while (true) {
- synchronized (mResponses) {
- for (Response response : mResponses) {
- if (response.cmdNum == cmdNum) {
- found = response;
- // how many response fragments are left
- switch (response.responses.size()) {
- case 0: // haven't got any - must wait
- break;
- case 1: // last one - remove this from the master list
- mResponses.remove(response); // fall through
- default: // take one and move on
- response.request = origCmd;
- return response.responses.remove();
- }
- }
- }
- nowTime = SystemClock.uptimeMillis();
- if (endTime <= nowTime) {
- Slog.e("NativeDaemonConnector.ResponseQueue",
- "Timeout waiting for response");
- return null;
- }
- /* pre-allocate so we have something unique to wait on */
- if (found == null) {
- found = new Response(cmdNum, origCmd);
- mResponses.add(found);
+ PendingCmd found = null;
+ synchronized (mPendingCmds) {
+ for (PendingCmd pendingCmd : mPendingCmds) {
+ if (pendingCmd.cmdNum == cmdNum) {
+ found = pendingCmd;
+ break;
}
}
- try {
- synchronized (found) {
- found.wait(endTime - nowTime);
- }
- } catch (InterruptedException e) {
- // loop around to check if we're done or if it's time to stop waiting
+ if (found == null) {
+ found = new PendingCmd(cmdNum, origCmd);
+ mPendingCmds.add(found);
}
+ found.availableResponseCount--;
+ // if a matching add call has already retrieved this we can remove this
+ // instance from our list
+ if (found.availableResponseCount == 0) mPendingCmds.remove(found);
}
+ NativeDaemonEvent result = null;
+ try {
+ result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {}
+ if (result == null) {
+ Slog.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response");
+ }
+ return result;
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Pending requests:");
- synchronized (mResponses) {
- for (Response response : mResponses) {
- pw.println(" Cmd " + response.cmdNum + " - " + response.request);
+ synchronized (mPendingCmds) {
+ for (PendingCmd pendingCmd : mPendingCmds) {
+ pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.request);
}
}
}
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 6ad8bd0..87843d9 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -110,8 +110,8 @@
private final EnabledState mEnabledState = new EnabledState();
@Override
- protected String getMessageInfo(Message msg) {
- return cmdToString(msg.what);
+ protected String getWhatToString(int what) {
+ return cmdToString(what);
}
/**
@@ -144,7 +144,7 @@
} else {
setInitialState(mDisabledState);
}
- setProcessedMessagesSize(25);
+ setLogRecSize(25);
registerForNsdSetting();
}
diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java
index d85abe6..a4341b7 100644
--- a/services/java/com/android/server/ShutdownActivity.java
+++ b/services/java/com/android/server/ShutdownActivity.java
@@ -17,13 +17,12 @@
package com.android.server;
import android.app.Activity;
-import android.content.BroadcastReceiver;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Slog;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.ShutdownThread;
public class ShutdownActivity extends Activity {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7e733c6..ed7b6e3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -55,7 +55,8 @@
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.pm.PackageManagerService;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.PowerManagerService;
+import com.android.server.power.ShutdownThread;
import com.android.server.usb.UsbService;
import com.android.server.wm.WindowManagerService;
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index c239382..c5b4a07 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -17,6 +17,7 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
+import com.android.server.power.PowerManagerService;
import android.app.AlarmManager;
import android.app.PendingIntent;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 1f03d17..3250dce 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -58,6 +58,7 @@
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Slog;
import java.util.ArrayList;
@@ -161,6 +162,10 @@
/* Tracks whether wifi is enabled from WifiStateMachine's perspective */
private boolean mWifiEnabled;
+ /* The work source (UID) that triggered the current WIFI scan, synchronized
+ * on this */
+ private WorkSource mScanWorkSource;
+
private boolean mIsReceiverRegistered = false;
@@ -413,6 +418,7 @@
}
} else if (intent.getAction().equals(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ noteScanEnd();
checkAndSetNotification();
}
}
@@ -430,6 +436,44 @@
mNotificationEnabledSettingObserver.register();
}
+ /** Tell battery stats about a new WIFI scan */
+ private void noteScanStart() {
+ WorkSource scanWorkSource = null;
+ synchronized (WifiService.this) {
+ if (mScanWorkSource != null) {
+ // Scan already in progress, don't add this one to battery stats
+ return;
+ }
+ scanWorkSource = new WorkSource(Binder.getCallingUid());
+ mScanWorkSource = scanWorkSource;
+ }
+
+ long id = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteWifiScanStartedFromSource(scanWorkSource);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ }
+
+ /** Tell battery stats that the current WIFI scan has completed */
+ private void noteScanEnd() {
+ WorkSource scanWorkSource = null;
+ synchronized (WifiService.this) {
+ scanWorkSource = mScanWorkSource;
+ mScanWorkSource = null;
+ }
+ if (scanWorkSource != null) {
+ try {
+ mBatteryStats.noteWifiScanStoppedFromSource(scanWorkSource);
+ } catch (RemoteException e) {
+ Log.w(TAG, e);
+ }
+ }
+ }
+
/**
* Check if Wi-Fi needs to be enabled and start
* if needed
@@ -551,6 +595,7 @@
mScanCount.put(uid, ++count);
}
mWifiStateMachine.startScan(forceActive);
+ noteScanStart();
}
private void enforceAccessPermission() {
@@ -1333,10 +1378,8 @@
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
- mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
- break;
case WifiManager.WIFI_MODE_SCAN_ONLY:
- mBatteryStats.noteScanWifiLockAcquiredFromSource(wifiLock.mWorkSource);
+ mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
break;
}
}
@@ -1345,10 +1388,8 @@
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
- mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
- break;
case WifiManager.WIFI_MODE_SCAN_ONLY:
- mBatteryStats.noteScanWifiLockReleasedFromSource(wifiLock.mWorkSource);
+ mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
break;
}
}
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 8f797ec..ab20208 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -346,18 +346,18 @@
mStats.noteFullWifiLockReleasedLocked(uid);
}
}
-
- public void noteScanWifiLockAcquired(int uid) {
+
+ public void noteWifiScanStarted(int uid) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScanWifiLockAcquiredLocked(uid);
+ mStats.noteWifiScanStartedLocked(uid);
}
}
-
- public void noteScanWifiLockReleased(int uid) {
+
+ public void noteWifiScanStopped(int uid) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScanWifiLockReleasedLocked(uid);
+ mStats.noteWifiScanStoppedLocked(uid);
}
}
@@ -389,17 +389,17 @@
}
}
- public void noteScanWifiLockAcquiredFromSource(WorkSource ws) {
+ public void noteWifiScanStartedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScanWifiLockAcquiredFromSourceLocked(ws);
+ mStats.noteWifiScanStartedFromSourceLocked(ws);
}
}
- public void noteScanWifiLockReleasedFromSource(WorkSource ws) {
+ public void noteWifiScanStoppedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScanWifiLockReleasedFromSourceLocked(ws);
+ mStats.noteWifiScanStoppedFromSourceLocked(ws);
}
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 88a0ccb..00832ee 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -500,8 +500,13 @@
mUsbTetherRequested = false;
}
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
- if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
- mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
+ NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra(
+ ConnectivityManager.EXTRA_NETWORK_INFO);
+ if (networkInfo != null &&
+ networkInfo.getDetailedState() != NetworkInfo.DetailedState.FAILED) {
+ if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
+ mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
+ }
}
}
}
@@ -1134,7 +1139,7 @@
private State mStopTetheringErrorState;
private State mSetDnsForwardersErrorState;
- private ArrayList mNotifyList;
+ private ArrayList<TetherInterfaceSM> mNotifyList;
private int mCurrentConnectionSequence;
private int mMobileApnReserved = ConnectivityManager.TYPE_NONE;
@@ -1164,7 +1169,7 @@
mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
addState(mSetDnsForwardersErrorState);
- mNotifyList = new ArrayList();
+ mNotifyList = new ArrayList<TetherInterfaceSM>();
setInitialState(mInitialState);
}
@@ -1361,8 +1366,7 @@
protected void notifyTetheredOfNewUpstreamIface(String ifaceName) {
if (DBG) Log.d(TAG, "notifying tethered with iface =" + ifaceName);
mUpstreamIfaceName = ifaceName;
- for (Object o : mNotifyList) {
- TetherInterfaceSM sm = (TetherInterfaceSM)o;
+ for (TetherInterfaceSM sm : mNotifyList) {
sm.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED,
ifaceName);
}
@@ -1380,13 +1384,13 @@
switch (message.what) {
case CMD_TETHER_MODE_REQUESTED:
TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode requested by " + who.toString());
+ if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
mNotifyList.add(who);
transitionTo(mTetherModeAliveState);
break;
case CMD_TETHER_MODE_UNREQUESTED:
who = (TetherInterfaceSM)message.obj;
- if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who.toString());
+ if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
int index = mNotifyList.indexOf(who);
if (index != -1) {
mNotifyList.remove(who);
@@ -1423,18 +1427,29 @@
switch (message.what) {
case CMD_TETHER_MODE_REQUESTED:
TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
mNotifyList.add(who);
who.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED,
mUpstreamIfaceName);
break;
case CMD_TETHER_MODE_UNREQUESTED:
who = (TetherInterfaceSM)message.obj;
+ if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
int index = mNotifyList.indexOf(who);
if (index != -1) {
+ if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who);
mNotifyList.remove(index);
if (mNotifyList.isEmpty()) {
turnOffMasterTetherSettings(); // transitions appropriately
+ } else {
+ if (DBG) {
+ Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
+ " live requests:");
+ for (Object o : mNotifyList) Log.d(TAG, " " + o);
+ }
}
+ } else {
+ Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who);
}
break;
case CMD_UPSTREAM_CHANGED:
@@ -1561,7 +1576,7 @@
pw.println();
pw.println("Tether state:");
for (Object o : mIfaces.values()) {
- pw.println(" "+o.toString());
+ pw.println(" " + o);
}
}
pw.println();
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9a79f86..2609664 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -208,7 +208,15 @@
* The default maximum time to wait for the verification agent to return in
* milliseconds.
*/
- private static final long DEFAULT_VERIFICATION_TIMEOUT = 60 * 1000;
+ private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
+
+ /**
+ * The default response for package verification timeout.
+ *
+ * This can be either PackageManager.VERIFICATION_ALLOW or
+ * PackageManager.VERIFICATION_REJECT.
+ */
+ private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
@@ -694,6 +702,10 @@
// Remove the replaced package's older resources safely now
deleteOld = true;
}
+
+ // Log current value of "unknown sources" setting
+ EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
+ getUnknownSourcesSettings());
}
// Force a gc to clear up things
Runtime.getRuntime().gc();
@@ -769,7 +781,18 @@
Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
mPendingVerification.remove(verificationId);
- int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
+ int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
+
+ if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
+ Slog.i(TAG, "Continuing with installation of " + args.packageURI.toString());
+ state.setVerifierResponse(Binder.getCallingUid(), PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
+ try {
+ ret = args.copyApk(mContainerService, true);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Could not contact the ContainerService");
+ }
+ }
+
processPendingInstall(args, ret);
mHandler.sendEmptyMessage(MCS_UNBIND);
@@ -5446,6 +5469,17 @@
}
/**
+ * Get the default verification agent response code.
+ *
+ * @return default verification response code
+ */
+ private int getDefaultVerificationResponse() {
+ return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
+ DEFAULT_VERIFICATION_RESPONSE);
+ }
+
+ /**
* Check whether or not package verification has been enabled.
*
* @return true if verification should be performed
@@ -5456,6 +5490,17 @@
DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
}
+ /**
+ * Get the "allow unknown sources" setting.
+ *
+ * @return the current "allow unknown sources" setting
+ */
+ private int getUnknownSourcesSettings() {
+ return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
+ android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
+ -1);
+ }
+
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
final int uid = Binder.getCallingUid();
// writer
@@ -9376,14 +9421,20 @@
@Override
public UserInfo getUser(int userId) {
- enforceSystemOrRoot("Only the system can remove users");
+ enforceSystemOrRoot("Only the system can query user");
return sUserManager.getUser(userId);
}
@Override
- public void updateUserName(int userId, String name) {
+ public void setUserName(int userId, String name) {
enforceSystemOrRoot("Only the system can rename users");
- sUserManager.updateUserName(userId, name);
+ sUserManager.setUserName(userId, name);
+ }
+
+ @Override
+ public ParcelFileDescriptor setUserIcon(int userId) {
+ enforceSystemOrRoot("Only the system can update users");
+ return sUserManager.setUserIcon(userId);
}
@Override
diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java
index 4e9e666..738ab08 100644
--- a/services/java/com/android/server/pm/UserManager.java
+++ b/services/java/com/android/server/pm/UserManager.java
@@ -16,6 +16,9 @@
package com.android.server.pm;
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
@@ -24,6 +27,7 @@
import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.os.UserId;
import android.util.Log;
@@ -34,6 +38,7 @@
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -44,10 +49,15 @@
import org.xmlpull.v1.XmlSerializer;
public class UserManager {
+
+ private static final String TAG = "UserManager";
+
private static final String TAG_NAME = "name";
private static final String ATTR_FLAGS = "flags";
+ private static final String ATTR_ICON_PATH = "icon";
+
private static final String ATTR_ID = "id";
private static final String TAG_USERS = "users";
@@ -58,6 +68,7 @@
private static final String USER_INFO_DIR = "system" + File.separator + "users";
private static final String USER_LIST_FILENAME = "userlist.xml";
+ private static final String USER_PHOTO_FILENAME = "photo.png";
private SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>();
@@ -114,7 +125,7 @@
}
}
- public void updateUserName(int userId, String name) {
+ public void setUserName(int userId, String name) {
synchronized (mUsers) {
UserInfo info = mUsers.get(userId);
if (name != null && !name.equals(info.name)) {
@@ -124,6 +135,39 @@
}
}
+ public ParcelFileDescriptor setUserIcon(int userId) {
+ synchronized (mUsers) {
+ UserInfo info = mUsers.get(userId);
+ if (info == null) return null;
+ ParcelFileDescriptor fd = updateIconBitmapLocked(info);
+ if (fd != null) {
+ writeUserLocked(info);
+ }
+ return fd;
+ }
+ }
+
+ private ParcelFileDescriptor updateIconBitmapLocked(UserInfo info) {
+ try {
+ File dir = new File(mUsersDir, Integer.toString(info.id));
+ File file = new File(dir, USER_PHOTO_FILENAME);
+ if (!dir.exists()) {
+ dir.mkdir();
+ FileUtils.setPermissions(
+ dir.getPath(),
+ FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
+ -1, -1);
+ }
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
+ MODE_CREATE|MODE_READ_WRITE);
+ info.iconPath = file.getAbsolutePath();
+ return fd;
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "Error setting photo for user ", e);
+ }
+ return null;
+ }
+
/**
* Returns an array of user ids. This array is cached here for quick access, so do not modify or
* cache it elsewhere.
@@ -187,7 +231,7 @@
private void fallbackToSingleUserLocked() {
// Create the primary user
- UserInfo primary = new UserInfo(0, "Primary",
+ UserInfo primary = new UserInfo(0, "Primary", null,
UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
mUsers.put(0, primary);
updateUserIdsLocked();
@@ -219,6 +263,9 @@
serializer.startTag(null, TAG_USER);
serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id));
serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags));
+ if (userInfo.iconPath != null) {
+ serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath);
+ }
serializer.startTag(null, TAG_NAME);
serializer.text(userInfo.name);
@@ -286,6 +333,7 @@
private UserInfo readUser(int id) {
int flags = 0;
String name = null;
+ String iconPath = null;
FileInputStream fis = null;
try {
@@ -312,6 +360,7 @@
}
String flagString = parser.getAttributeValue(null, ATTR_FLAGS);
flags = Integer.parseInt(flagString);
+ iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -324,7 +373,7 @@
}
}
- UserInfo userInfo = new UserInfo(id, name, flags);
+ UserInfo userInfo = new UserInfo(id, name, iconPath, flags);
return userInfo;
} catch (IOException ioe) {
@@ -342,7 +391,7 @@
public UserInfo createUser(String name, int flags) {
int userId = getNextAvailableId();
- UserInfo userInfo = new UserInfo(userId, name, flags);
+ UserInfo userInfo = new UserInfo(userId, name, null, flags);
File userPath = new File(mBaseUserPath, Integer.toString(userId));
if (!createPackageFolders(userId, userPath)) {
return null;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
similarity index 99%
rename from services/java/com/android/server/PowerManagerService.java
rename to services/java/com/android/server/power/PowerManagerService.java
index 0a9905e..de2edff 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -14,11 +14,16 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.power;
import com.android.internal.app.IBatteryStats;
+import com.android.server.BatteryService;
+import com.android.server.EventLogTags;
+import com.android.server.LightsService;
+import com.android.server.LightsService.Light;
+import com.android.server.Watchdog;
+import com.android.server.Watchdog.Monitor;
import com.android.server.am.BatteryStatsService;
-import com.android.server.pm.ShutdownThread;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -532,7 +537,7 @@
}
}
- PowerManagerService() {
+ public PowerManagerService() {
// Hack to get our uid... should have a func for this.
long token = Binder.clearCallingIdentity();
MY_UID = Process.myUid();
@@ -550,7 +555,7 @@
private ContentQueryMap mSettings;
- void init(Context context, LightsService lights, IActivityManager activity,
+ public void init(Context context, LightsService lights, IActivityManager activity,
BatteryService battery) {
mLightsService = lights;
mContext = context;
@@ -707,7 +712,7 @@
/**
* Low-level function turn the device off immediately, without trying
* to be clean. Most people should use
- * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown.
+ * {@link com.android.server.power.internal.app.ShutdownThread} for a clean shutdown.
*/
public static void lowLevelShutdown() {
nativeShutdown();
@@ -2384,13 +2389,13 @@
}
private int getPreferredBrightness() {
+ int brightness = mScreenBrightnessSetting;
if (mScreenBrightnessOverride >= 0) {
- return mScreenBrightnessOverride;
+ brightness = mScreenBrightnessOverride;
} else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness
&& mAutoBrightessEnabled) {
- return mLightSensorScreenBrightness;
+ brightness = mLightSensorScreenBrightness;
}
- final int brightness = mScreenBrightnessSetting;
// Don't let applications turn the screen all the way off
return Math.max(brightness, mScreenBrightnessDim);
}
@@ -3056,7 +3061,7 @@
return mPolicy;
}
- void systemReady() {
+ public void systemReady() {
mSensorManager = new SystemSensorManager(mHandlerThread.getLooper());
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// don't bother with the light sensor if auto brightness is handled in hardware
diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
similarity index 99%
rename from services/java/com/android/server/pm/ShutdownThread.java
rename to services/java/com/android/server/power/ShutdownThread.java
index 3675d41..5f2f428 100644
--- a/services/java/com/android/server/pm/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -15,7 +15,7 @@
*/
-package com.android.server.pm;
+package com.android.server.power;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
@@ -43,7 +43,6 @@
import android.os.storage.IMountShutdownObserver;
import com.android.internal.telephony.ITelephony;
-import com.android.server.PowerManagerService;
import android.util.Log;
import android.view.WindowManager;
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 758b6e7..e65d5d2 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -38,10 +38,18 @@
ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
boolean mAnimating;
- boolean mTokenMayBeDrawn;
- boolean mForceHiding;
- WindowState mWindowAnimationBackground;
- int mWindowAnimationBackgroundColor;
+
+ /** Variables only intended to be valid within each pass through animate(). Does not contain
+ * persistent state. */
+ private class InnerLoopParams {
+ boolean mTokenMayBeDrawn;
+ boolean mForceHiding;
+ WindowState mDetachedWallpaper = null;
+ WindowState mWindowAnimationBackground;
+ int mWindowAnimationBackgroundColor;
+ }
+ InnerLoopParams mInner = new InnerLoopParams();
+
int mAdjResult;
int mPendingLayoutChanges;
@@ -65,9 +73,9 @@
// Window currently running an animation that has requested it be detached
// from the wallpaper. This means we need to ensure the wallpaper is
// visible behind it in case it animates in a way that would allow it to be
- // seen.
+ // seen. If multiple windows satisfy this, use the lowest window.
WindowState mWindowDetachedWallpaper = null;
- WindowState mDetachedWallpaper = null;
+
DimSurface mWindowAnimationBackgroundSurface = null;
int mBulkUpdateParams = 0;
@@ -103,19 +111,20 @@
}
private void testWallpaperAndBackgroundLocked() {
- if (mWindowDetachedWallpaper != mDetachedWallpaper) {
+ final WindowState detachedWallpaper = mInner.mDetachedWallpaper;
+ if (mWindowDetachedWallpaper != detachedWallpaper) {
if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
"Detached wallpaper changed from " + mWindowDetachedWallpaper
- + " to " + mDetachedWallpaper);
- mWindowDetachedWallpaper = mDetachedWallpaper;
+ + " to " + detachedWallpaper);
+ mWindowDetachedWallpaper = detachedWallpaper;
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
}
- if (mWindowAnimationBackgroundColor != 0) {
+ if (mInner.mWindowAnimationBackgroundColor != 0) {
// If the window that wants black is the current wallpaper
// target, then the black goes *below* the wallpaper so we
// don't cause the wallpaper to suddenly disappear.
- WindowState target = mWindowAnimationBackground;
+ WindowState target = mInner.mWindowAnimationBackground;
if (mService.mWallpaperTarget == target
|| mService.mLowerWallpaperTarget == target
|| mService.mUpperWallpaperTarget == target) {
@@ -135,7 +144,7 @@
final int dh = mDh;
mWindowAnimationBackgroundSurface.show(dw, dh,
target.mWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM,
- mWindowAnimationBackgroundColor);
+ mInner.mWindowAnimationBackgroundColor);
} else if (mWindowAnimationBackgroundSurface != null) {
mWindowAnimationBackgroundSurface.hide();
}
@@ -199,9 +208,9 @@
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
- for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
- WindowState win = mService.mWindows.get(i);
- WindowStateAnimator winAnimator = win.mWinAnimator;
+ for (int i = mWinAnimators.size() - 1; i >= 0; i--) {
+ WindowStateAnimator winAnimator = mWinAnimators.get(i);
+ WindowState win = winAnimator.mWin;
final int flags = winAnimator.mAttrFlags;
if (winAnimator.mSurface != null) {
@@ -220,15 +229,15 @@
if (winAnimator.mAnimation != null) {
if ((flags & FLAG_SHOW_WALLPAPER) != 0
&& winAnimator.mAnimation.getDetachWallpaper()) {
- mDetachedWallpaper = win;
+ mInner.mDetachedWallpaper = win;
}
final int backgroundColor = winAnimator.mAnimation.getBackgroundColor();
if (backgroundColor != 0) {
- if (mWindowAnimationBackground == null
- || (winAnimator.mAnimLayer <
- mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
- mWindowAnimationBackground = win;
- mWindowAnimationBackgroundColor = backgroundColor;
+ final WindowState background = mInner.mWindowAnimationBackground;
+ if (background == null || (winAnimator.mAnimLayer <
+ background.mWinAnimator.mAnimLayer)) {
+ mInner.mWindowAnimationBackground = win;
+ mInner.mWindowAnimationBackgroundColor = backgroundColor;
}
}
}
@@ -244,15 +253,15 @@
&& appAnimator.animating) {
if ((flags & FLAG_SHOW_WALLPAPER) != 0
&& appAnimator.animation.getDetachWallpaper()) {
- mDetachedWallpaper = win;
+ mInner.mDetachedWallpaper = win;
}
final int backgroundColor = appAnimator.animation.getBackgroundColor();
if (backgroundColor != 0) {
- if (mWindowAnimationBackground == null
- || (winAnimator.mAnimLayer <
- mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
- mWindowAnimationBackground = win;
- mWindowAnimationBackgroundColor = backgroundColor;
+ final WindowState background = mInner.mWindowAnimationBackground;
+ if (background == null || (winAnimator.mAnimLayer <
+ background.mWinAnimator.mAnimLayer)) {
+ mInner.mWindowAnimationBackground = win;
+ mInner.mWindowAnimationBackgroundColor = backgroundColor;
}
}
}
@@ -280,10 +289,10 @@
mService.mFocusMayChange = true;
}
if (win.isReadyForDisplay() && !winAnimator.isAnimating()) {
- mForceHiding = true;
+ mInner.mForceHiding = true;
}
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
- "Force hide " + mForceHiding
+ "Force hide " + mInner.mForceHiding
+ " hasSurface=" + win.mHasSurface
+ " policyVis=" + win.mPolicyVisibility
+ " destroying=" + win.mDestroying
@@ -293,7 +302,7 @@
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
final boolean changed;
- if (mForceHiding && !winAnimator.isAnimating()) {
+ if (mInner.mForceHiding && !winAnimator.isAnimating()) {
changed = win.hideLw(false, false);
if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
"Now policy hidden: " + win);
@@ -308,7 +317,7 @@
unForceHiding = new ArrayList<WindowStateAnimator>();
}
unForceHiding.add(winAnimator);
- if ((win.mAttrs.flags&WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+ if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
wallpaperInUnForceHiding = true;
}
}
@@ -320,7 +329,7 @@
}
}
}
- if (changed && (flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+ if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) {
mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -364,7 +373,7 @@
"tokenMayBeDrawn: " + atoken
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen
+ " mAppFreezing=" + win.mAppFreezing);
- mTokenMayBeDrawn = true;
+ mInner.mTokenMayBeDrawn = true;
}
}
} else if (win.isDrawnLw()) {
@@ -454,18 +463,18 @@
}
private void performAnimationsLocked() {
- mTokenMayBeDrawn = false;
- mForceHiding = false;
- mDetachedWallpaper = null;
- mWindowAnimationBackground = null;
- mWindowAnimationBackgroundColor = 0;
+ mInner.mTokenMayBeDrawn = false;
+ mInner.mForceHiding = false;
+ mInner.mDetachedWallpaper = null;
+ mInner.mWindowAnimationBackground = null;
+ mInner.mWindowAnimationBackgroundColor = 0;
updateWindowsAndWallpaperLocked();
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
mPendingActions |= WALLPAPER_ACTION_PENDING;
}
- if (mTokenMayBeDrawn) {
+ if (mInner.mTokenMayBeDrawn) {
testTokenMayBeDrawnLocked();
}
}
@@ -526,7 +535,15 @@
Surface.closeTransaction();
}
- mService.bulkSetParameters(mBulkUpdateParams, mPendingLayoutChanges);
+ if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) {
+ final WindowManagerService.AnimatorToLayoutParams animToLayout = mService.mAnimToLayout;
+ synchronized (animToLayout) {
+ animToLayout.mBulkUpdateParams = mBulkUpdateParams;
+ animToLayout.mPendingLayoutChanges = mPendingLayoutChanges;
+ animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper;
+ mService.setAnimatorParameters();
+ }
+ }
if (mAnimating) {
mService.scheduleAnimationLocked();
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index c329174..e2acd7f 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -42,12 +42,12 @@
import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AttributeCache;
import com.android.server.EventLogTags;
-import com.android.server.PowerManagerService;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.input.InputFilter;
import com.android.server.input.InputManagerService;
-import com.android.server.pm.ShutdownThread;
+import com.android.server.power.PowerManagerService;
+import com.android.server.power.ShutdownThread;
import android.Manifest;
import android.app.ActivityManagerNative;
@@ -511,9 +511,9 @@
// State while inside of layoutAndPlaceSurfacesLocked().
boolean mFocusMayChange;
-
+
Configuration mCurConfiguration = new Configuration();
-
+
// This is held as long as we have the screen frozen, to give us time to
// perform a rotation animation when turning off shows the lock screen which
// changes the orientation.
@@ -640,7 +640,17 @@
private float mButtonBrightness = -1;
private boolean mUpdateRotation = false;
}
- LayoutFields mInnerFields = new LayoutFields();
+ final LayoutFields mInnerFields = new LayoutFields();
+
+ static class AnimatorToLayoutParams {
+ int mBulkUpdateParams;
+ int mPendingLayoutChanges;
+ WindowState mWindowDetachedWallpaper;
+ }
+ final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
+
+ /** The lowest wallpaper target with a detached wallpaper animation on it. */
+ WindowState mWindowDetachedWallpaper = null;
/** Only do a maximum of 6 repeated layouts. After that quit */
private int mLayoutRepeatCount;
@@ -671,7 +681,7 @@
}
final AnimationRunnable mAnimationRunnable = new AnimationRunnable();
boolean mAnimationScheduled;
-
+
final WindowAnimator mAnimator;
final class DragInputEventReceiver extends InputEventReceiver {
@@ -1576,9 +1586,9 @@
Slog.v(TAG, "List with no IM target:");
logWindowList(" ");
}
- if (DN > 0) moveInputMethodDialogsLocked(-1);;
+ if (DN > 0) moveInputMethodDialogsLocked(-1);
} else {
- moveInputMethodDialogsLocked(-1);;
+ moveInputMethodDialogsLocked(-1);
}
}
@@ -1640,7 +1650,7 @@
continue;
}
topCurW = null;
- if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
+ if (w != mWindowDetachedWallpaper && w.mAppToken != null) {
// If this window's app token is hidden and not animating,
// it is of no interest to us.
if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
@@ -1666,7 +1676,7 @@
continue;
}
break;
- } else if (w == mAnimator.mWindowDetachedWallpaper) {
+ } else if (w == mWindowDetachedWallpaper) {
windowDetachedI = i;
}
}
@@ -3108,12 +3118,11 @@
a.setDetachWallpaper(true);
a.setDuration(duration);
return a;
- } else {
- // For normal animations, the exiting element just holds in place.
- Animation a = new AlphaAnimation(1, 1);
- a.setDuration(duration);
- return a;
}
+ // For normal animations, the exiting element just holds in place.
+ Animation a = new AlphaAnimation(1, 1);
+ a.setDuration(duration);
+ return a;
}
/**
@@ -6826,7 +6835,7 @@
public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
public static final int BOOT_TIMEOUT = 23;
public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
- public static final int BULK_UPDATE_PARAMETERS = 25;
+ public static final int UPDATE_ANIM_PARAMETERS = 25;
public static final int SHOW_STRICT_MODE_VIOLATION = 26;
public static final int DO_ANIMATION_CALLBACK = 27;
@@ -7253,44 +7262,49 @@
break;
}
- case BULK_UPDATE_PARAMETERS: {
+ case UPDATE_ANIM_PARAMETERS: {
// Used to send multiple changes from the animation side to the layout side.
synchronized (mWindowMap) {
- boolean doRequest = false;
- // TODO(cmautner): As the number of bits grows, use masks of bit groups to
- // eliminate unnecessary tests.
- if ((msg.arg1 & LayoutFields.SET_UPDATE_ROTATION) != 0) {
- mInnerFields.mUpdateRotation = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
- mInnerFields.mWallpaperMayChange = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
- mInnerFields.mWallpaperForceHidingChanged = true;
- doRequest = true;
- }
- if ((msg.arg1 & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) {
- mInnerFields.mOrientationChangeComplete = false;
- } else {
- mInnerFields.mOrientationChangeComplete = true;
- if (mWindowsFreezingScreen) {
+ synchronized (mAnimToLayout) {
+ boolean doRequest = false;
+ final int bulkUpdateParams = mAnimToLayout.mBulkUpdateParams;
+ // TODO(cmautner): As the number of bits grows, use masks of bit groups to
+ // eliminate unnecessary tests.
+ if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+ mInnerFields.mUpdateRotation = true;
doRequest = true;
}
- }
- if ((msg.arg1 & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
- mTurnOnScreen = true;
- }
+ if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+ mInnerFields.mWallpaperMayChange = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+ mInnerFields.mWallpaperForceHidingChanged = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) {
+ mInnerFields.mOrientationChangeComplete = false;
+ } else {
+ mInnerFields.mOrientationChangeComplete = true;
+ if (mWindowsFreezingScreen) {
+ doRequest = true;
+ }
+ }
+ if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+ mTurnOnScreen = true;
+ }
- mPendingLayoutChanges |= msg.arg2;
- if (mPendingLayoutChanges != 0) {
- doRequest = true;
- }
+ mPendingLayoutChanges |= mAnimToLayout.mPendingLayoutChanges;
+ if (mPendingLayoutChanges != 0) {
+ doRequest = true;
+ }
- if (doRequest) {
- mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
- performLayoutAndPlaceSurfacesLocked();
+ mWindowDetachedWallpaper = mAnimToLayout.mWindowDetachedWallpaper;
+
+ if (doRequest) {
+ mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS);
+ performLayoutAndPlaceSurfacesLocked();
+ }
}
}
break;
@@ -10015,8 +10029,7 @@
}
}
- void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) {
- mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
- pendingLayoutChanges));
+ void setAnimatorParameters() {
+ mH.sendMessage(mH.obtainMessage(H.UPDATE_ANIM_PARAMETERS));
}
}
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index e0a14af..d097a93 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -8,7 +8,7 @@
com_android_server_input_InputManagerService.cpp \
com_android_server_input_InputWindowHandle.cpp \
com_android_server_LightsService.cpp \
- com_android_server_PowerManagerService.cpp \
+ com_android_server_power_PowerManagerService.cpp \
com_android_server_SerialService.cpp \
com_android_server_SystemServer.cpp \
com_android_server_UsbDeviceManager.cpp \
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 0e1ce51..57e1c28 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -49,7 +49,7 @@
#include <ScopedLocalRef.h>
#include <ScopedUtfChars.h>
-#include "com_android_server_PowerManagerService.h"
+#include "com_android_server_power_PowerManagerService.h"
#include "com_android_server_input_InputApplicationHandle.h"
#include "com_android_server_input_InputWindowHandle.h"
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
similarity index 96%
rename from services/jni/com_android_server_PowerManagerService.cpp
rename to services/jni/com_android_server_power_PowerManagerService.cpp
index 0904bdd..2690b68 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -35,7 +35,7 @@
#include <private/gui/ComposerService.h>
-#include "com_android_server_PowerManagerService.h"
+#include "com_android_server_power_PowerManagerService.h"
namespace android {
@@ -177,12 +177,15 @@
}
static int nativeSetScreenState(JNIEnv *env, jobject clazz, jboolean on) {
+ sp<ISurfaceComposer> s(ComposerService::getComposerService());
if (on) {
autosuspend_disable();
if (gPowerModule) {
gPowerModule->setInteractive(gPowerModule, true);
}
+ s->unblank();
} else {
+ s->blank();
if (gPowerModule) {
gPowerModule->setInteractive(gPowerModule, false);
}
@@ -243,14 +246,14 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_PowerManagerService(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService",
+ int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
// Callbacks
jclass clazz;
- FIND_CLASS(clazz, "com/android/server/PowerManagerService");
+ FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, clazz,
"goToSleep", "(J)V");
diff --git a/services/jni/com_android_server_PowerManagerService.h b/services/jni/com_android_server_power_PowerManagerService.h
similarity index 100%
rename from services/jni/com_android_server_PowerManagerService.h
rename to services/jni/com_android_server_power_PowerManagerService.h
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index c23e868..416900f8 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -179,7 +179,7 @@
@Override
public List<UserInfo> getUsers() {
final ArrayList<UserInfo> users = new ArrayList<UserInfo>();
- users.add(new UserInfo(USER_ID, "Primary", UserInfo.FLAG_PRIMARY));
+ users.add(new UserInfo(USER_ID, "Primary", null, UserInfo.FLAG_PRIMARY));
users.add(new UserInfo(USER_ID_GUEST, "Guest", 0));
return users;
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index cc4adfd..a6bd85e 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -17,7 +17,6 @@
package com.android.internal.telephony;
-import com.android.internal.telephony.DataCallState.SetupResult;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
@@ -39,6 +38,7 @@
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* {@hide}
@@ -65,8 +65,7 @@
protected static final boolean DBG = true;
protected static final boolean VDBG = false;
- protected static Object mCountLock = new Object();
- protected static int mCount;
+ protected static AtomicInteger mCount = new AtomicInteger(0);
protected AsyncChannel mAc;
protected List<ApnContext> mApnList = null;
@@ -260,12 +259,11 @@
protected abstract void log(String s);
-
//***** Constructor
protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
DataConnectionTracker dct) {
super(name);
- setProcessedMessagesSize(100);
+ setLogRecSize(100);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
this.mDataConnectionTracker = dct;
@@ -287,6 +285,27 @@
}
/**
+ * Shut down this instance and its state machine.
+ */
+ private void shutDown() {
+ if (DBG) log("shutDown");
+
+ if (mAc != null) {
+ mAc.disconnected();
+ mAc = null;
+ }
+ mApnList = null;
+ mReconnectIntent = null;
+ mDataConnectionTracker = null;
+ mApn = null;
+ phone = null;
+ mLinkProperties = null;
+ mCapabilities = null;
+ lastFailCause = null;
+ userData = null;
+ }
+
+ /**
* TearDown the data connection.
*
* @param o will be returned in AsyncResult.userObj
@@ -619,9 +638,11 @@
@Override
public void exit() {
phone.mCM.unregisterForRilConnected(getHandler());
+ shutDown();
}
@Override
public boolean processMessage(Message msg) {
+ boolean retVal = HANDLED;
AsyncResult ar;
switch (msg.what) {
@@ -639,14 +660,9 @@
}
break;
}
- case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
- if (VDBG) log("CMD_CHANNEL_DISCONNECT");
- mAc.disconnect();
- break;
- }
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
if (VDBG) log("CMD_CHANNEL_DISCONNECTED");
- mAc = null;
+ quit();
break;
}
case DataConnectionAc.REQ_IS_INACTIVE: {
@@ -784,7 +800,7 @@
break;
}
- return HANDLED;
+ return retVal;
}
}
private DcDefaultState mDefaultState = new DcDefaultState();
@@ -1215,11 +1231,11 @@
* @return the string for msg.what as our info.
*/
@Override
- protected String getMessageInfo(Message msg) {
+ protected String getWhatToString(int what) {
String info = null;
- info = cmdToString(msg.what);
+ info = cmdToString(what);
if (info == null) {
- info = DataConnectionAc.cmdToString(msg.what);
+ info = DataConnectionAc.cmdToString(what);
}
return info;
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 07d733e..41125dd 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -116,6 +116,12 @@
/** Don't send SMS (user did not confirm). */
static final int EVENT_STOP_SENDING = 7; // accessed from inner class
+ /** Confirmation required for third-party apps sending to an SMS short code. */
+ private static final int EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE = 8;
+
+ /** Confirmation required for third-party apps sending to an SMS short code. */
+ private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9;
+
protected final Phone mPhone;
protected final Context mContext;
protected final ContentResolver mResolver;
@@ -288,6 +294,14 @@
handleReachSentLimit((SmsTracker)(msg.obj));
break;
+ case EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE:
+ handleConfirmShortCode(false, (SmsTracker)(msg.obj));
+ break;
+
+ case EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE:
+ handleConfirmShortCode(true, (SmsTracker)(msg.obj));
+ break;
+
case EVENT_SEND_CONFIRMED_SMS:
{
SmsTracker tracker = (SmsTracker) msg.obj;
@@ -906,18 +920,61 @@
SmsTracker tracker = new SmsTracker(map, sentIntent, deliveryIntent, appPackage,
PhoneNumberUtils.extractNetworkPortion(destAddr));
- // check for excessive outgoing SMS usage by this app
- if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) {
- sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
- return;
+ // checkDestination() returns true if the destination is not a premium short code or the
+ // sending app is approved to send to short codes. Otherwise, a message is sent to our
+ // handler with the SmsTracker to request user confirmation before sending.
+ if (checkDestination(tracker)) {
+ // check for excessive outgoing SMS usage by this app
+ if (!mUsageMonitor.check(appPackage, SINGLE_PART_SMS)) {
+ sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, tracker));
+ return;
+ }
+
+ int ss = mPhone.getServiceState().getState();
+
+ if (ss != ServiceState.STATE_IN_SERVICE) {
+ handleNotInService(ss, tracker.mSentIntent);
+ } else {
+ sendSms(tracker);
+ }
}
+ }
- int ss = mPhone.getServiceState().getState();
-
- if (ss != ServiceState.STATE_IN_SERVICE) {
- handleNotInService(ss, tracker.mSentIntent);
+ /**
+ * Check if destination is a potential premium short code and sender is not pre-approved to
+ * send to short codes.
+ *
+ * @param tracker the tracker for the SMS to send
+ * @return true if the destination is approved; false if user confirmation event was sent
+ */
+ boolean checkDestination(SmsTracker tracker) {
+ if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION_PERMISSION)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true; // app is pre-approved to send to short codes
} else {
- sendSms(tracker);
+ String countryIso = mTelephonyManager.getSimCountryIso();
+ if (countryIso == null || countryIso.length() != 2) {
+ Log.e(TAG, "Can't get SIM country code: trying network country code");
+ countryIso = mTelephonyManager.getNetworkCountryIso();
+ }
+
+ switch (mUsageMonitor.checkDestination(tracker.mDestAddress, countryIso)) {
+ case SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE:
+ sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE,
+ tracker));
+ return false; // wait for user confirmation before sending
+
+ case SmsUsageMonitor.CATEGORY_PREMIUM_SHORT_CODE:
+ sendMessage(obtainMessage(EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE,
+ tracker));
+ return false; // wait for user confirmation before sending
+
+ case SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE:
+ case SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE:
+ case SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE:
+ default:
+ return true; // destination is not a premium short code
+ }
}
}
@@ -986,6 +1043,47 @@
}
/**
+ * Post an alert for user confirmation when sending to a potential short code.
+ * @param isPremium true if the destination is known to be a premium short code
+ * @param tracker the SmsTracker for the current message.
+ */
+ protected void handleConfirmShortCode(boolean isPremium, SmsTracker tracker) {
+ if (denyIfQueueLimitReached(tracker)) {
+ return; // queue limit reached; error was returned to caller
+ }
+
+ int messageId;
+ int titleId;
+ if (isPremium) {
+ messageId = R.string.sms_premium_short_code_confirm_message;
+ titleId = R.string.sms_premium_short_code_confirm_title;
+ } else {
+ messageId = R.string.sms_short_code_confirm_message;
+ titleId = R.string.sms_short_code_confirm_title;
+ }
+
+ CharSequence appLabel = getAppLabel(tracker.mAppPackage);
+ Resources r = Resources.getSystem();
+ Spanned messageText = Html.fromHtml(r.getString(messageId, appLabel, tracker.mDestAddress));
+
+ ConfirmDialogListener listener = new ConfirmDialogListener(tracker);
+
+ AlertDialog d = new AlertDialog.Builder(mContext)
+ .setTitle(titleId)
+ .setIcon(R.drawable.stat_sys_warning)
+ .setMessage(messageText)
+ .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener)
+ .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener)
+// TODO: add third button for "Report malicious app" feature
+// .setNeutralButton(r.getString(R.string.sms_short_code_confirm_report), listener)
+ .setOnCancelListener(listener)
+ .create();
+
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+ d.show();
+ }
+
+ /**
* Send the message along to the radio.
*
* @param tracker holds the SMS message to send
diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
index 4a4485d..1804d97 100644
--- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -60,17 +60,177 @@
/** Default number of SMS sent in checking period without user permission. */
private static final int DEFAULT_SMS_MAX_COUNT = 30;
+ /** Return value from {@link #checkDestination} for regular phone numbers. */
+ static final int CATEGORY_NOT_SHORT_CODE = 0;
+
+ /** Return value from {@link #checkDestination} for free (no cost) short codes. */
+ static final int CATEGORY_FREE_SHORT_CODE = 1;
+
+ /** Return value from {@link #checkDestination} for standard rate (non-premium) short codes. */
+ static final int CATEGORY_STANDARD_SHORT_CODE = 2;
+
+ /** Return value from {@link #checkDestination} for possible premium short codes. */
+ static final int CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+
+ /** Return value from {@link #checkDestination} for premium short codes. */
+ static final int CATEGORY_PREMIUM_SHORT_CODE = 4;
+
private final int mCheckPeriod;
private final int mMaxAllowed;
private final HashMap<String, ArrayList<Long>> mSmsStamp =
new HashMap<String, ArrayList<Long>>();
+ /** Context for retrieving regexes from XML resource. */
+ private final Context mContext;
+
+ /** Country code for the cached short code pattern matcher. */
+ private String mCurrentCountry;
+
+ /** Cached short code pattern matcher for {@link #mCurrentCountry}. */
+ private ShortCodePatternMatcher mCurrentPatternMatcher;
+
+ /** Cached short code regex patterns from secure settings for {@link #mCurrentCountry}. */
+ private String mSettingsShortCodePatterns;
+
+ /** Handler for responding to content observer updates. */
+ private final SettingsObserverHandler mSettingsObserverHandler;
+
+ /** XML tag for root element. */
+ private static final String TAG_SHORTCODES = "shortcodes";
+
+ /** XML tag for short code patterns for a specific country. */
+ private static final String TAG_SHORTCODE = "shortcode";
+
+ /** XML attribute for the country code. */
+ private static final String ATTR_COUNTRY = "country";
+
+ /** XML attribute for the short code regex pattern. */
+ private static final String ATTR_PATTERN = "pattern";
+
+ /** XML attribute for the premium short code regex pattern. */
+ private static final String ATTR_PREMIUM = "premium";
+
+ /** XML attribute for the free short code regex pattern. */
+ private static final String ATTR_FREE = "free";
+
+ /** XML attribute for the standard rate short code regex pattern. */
+ private static final String ATTR_STANDARD = "standard";
+
+ /**
+ * SMS short code regex pattern matcher for a specific country.
+ */
+ private static final class ShortCodePatternMatcher {
+ private final Pattern mShortCodePattern;
+ private final Pattern mPremiumShortCodePattern;
+ private final Pattern mFreeShortCodePattern;
+ private final Pattern mStandardShortCodePattern;
+
+ ShortCodePatternMatcher(String shortCodeRegex, String premiumShortCodeRegex,
+ String freeShortCodeRegex, String standardShortCodeRegex) {
+ mShortCodePattern = (shortCodeRegex != null ? Pattern.compile(shortCodeRegex) : null);
+ mPremiumShortCodePattern = (premiumShortCodeRegex != null ?
+ Pattern.compile(premiumShortCodeRegex) : null);
+ mFreeShortCodePattern = (freeShortCodeRegex != null ?
+ Pattern.compile(freeShortCodeRegex) : null);
+ mStandardShortCodePattern = (standardShortCodeRegex != null ?
+ Pattern.compile(standardShortCodeRegex) : null);
+ }
+
+ int getNumberCategory(String phoneNumber) {
+ if (mFreeShortCodePattern != null && mFreeShortCodePattern.matcher(phoneNumber)
+ .matches()) {
+ return CATEGORY_FREE_SHORT_CODE;
+ }
+ if (mStandardShortCodePattern != null && mStandardShortCodePattern.matcher(phoneNumber)
+ .matches()) {
+ return CATEGORY_STANDARD_SHORT_CODE;
+ }
+ if (mPremiumShortCodePattern != null && mPremiumShortCodePattern.matcher(phoneNumber)
+ .matches()) {
+ return CATEGORY_PREMIUM_SHORT_CODE;
+ }
+ if (mShortCodePattern != null && mShortCodePattern.matcher(phoneNumber).matches()) {
+ return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
+ }
+ return CATEGORY_NOT_SHORT_CODE;
+ }
+ }
+
+ /**
+ * Observe the secure setting for updated regex patterns.
+ */
+ private static class SettingsObserver extends ContentObserver {
+ private final int mWhat;
+ private final Handler mHandler;
+
+ SettingsObserver(Handler handler, int what) {
+ super(handler);
+ mHandler = handler;
+ mWhat = what;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ mHandler.obtainMessage(mWhat).sendToTarget();
+ }
+ }
+
+ /**
+ * Handler to update regex patterns when secure setting for the current country is updated.
+ */
+ private class SettingsObserverHandler extends Handler {
+ /** Current content observer, or null. */
+ SettingsObserver mSettingsObserver;
+
+ /** Current country code to watch for settings updates. */
+ private String mCountryIso;
+
+ /** Request to start observing a secure setting. */
+ static final int OBSERVE_SETTING = 1;
+
+ /** Handler event for updated secure settings. */
+ static final int SECURE_SETTINGS_CHANGED = 2;
+
+ /** Send a message to this handler requesting to observe the setting for a new country. */
+ void observeSettingForCountry(String countryIso) {
+ obtainMessage(OBSERVE_SETTING, countryIso).sendToTarget();
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case OBSERVE_SETTING:
+ if (msg.obj != null && msg.obj instanceof String) {
+ mCountryIso = (String) msg.obj;
+ String settingName = getSettingNameForCountry(mCountryIso);
+ ContentResolver resolver = mContext.getContentResolver();
+
+ if (mSettingsObserver != null) {
+ if (VDBG) log("Unregistering old content observer");
+ resolver.unregisterContentObserver(mSettingsObserver);
+ }
+
+ mSettingsObserver = new SettingsObserver(this, SECURE_SETTINGS_CHANGED);
+ resolver.registerContentObserver(
+ Settings.Secure.getUriFor(settingName), false, mSettingsObserver);
+ if (VDBG) log("Registered content observer for " + settingName);
+ }
+ break;
+
+ case SECURE_SETTINGS_CHANGED:
+ loadPatternsFromSettings(mCountryIso);
+ break;
+ }
+ }
+ }
+
/**
* Create SMS usage monitor.
* @param context the context to use to load resources and get TelephonyManager service
*/
public SmsUsageMonitor(Context context) {
+ mContext = context;
ContentResolver resolver = context.getContentResolver();
mMaxAllowed = Settings.Secure.getInt(resolver,
@@ -80,6 +240,83 @@
mCheckPeriod = Settings.Secure.getInt(resolver,
Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS,
DEFAULT_SMS_CHECK_PERIOD);
+
+ mSettingsObserverHandler = new SettingsObserverHandler();
+ }
+
+ /**
+ * Return a pattern matcher object for the specified country.
+ * @param country the country to search for
+ * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
+ */
+ private ShortCodePatternMatcher getPatternMatcher(String country) {
+ int id = com.android.internal.R.xml.sms_short_codes;
+ XmlResourceParser parser = mContext.getResources().getXml(id);
+
+ try {
+ return getPatternMatcher(country, parser);
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "XML parser exception reading short code pattern resource", e);
+ } catch (IOException e) {
+ Log.e(TAG, "I/O exception reading short code pattern resource", e);
+ } finally {
+ parser.close();
+ }
+ return null; // country not found
+ }
+
+ /**
+ * Return a pattern matcher object for the specified country from a secure settings string.
+ * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
+ */
+ private static ShortCodePatternMatcher getPatternMatcher(String country, String settingsPattern) {
+ // embed pattern tag into an XML document.
+ String document = "<shortcodes>" + settingsPattern + "</shortcodes>";
+ if (VDBG) log("loading updated patterns from: " + document);
+
+ try {
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ XmlPullParser parser = factory.newPullParser();
+ parser.setInput(new StringReader(document));
+ return getPatternMatcher(country, parser);
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "XML parser exception reading short code pattern from settings", e);
+ } catch (IOException e) {
+ Log.e(TAG, "I/O exception reading short code pattern from settings", e);
+ }
+ return null; // country not found
+ }
+
+ /**
+ * Return a pattern matcher object for the specified country and pattern XML parser.
+ * @param country the country to search for
+ * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
+ */
+ private static ShortCodePatternMatcher getPatternMatcher(String country, XmlPullParser parser)
+ throws XmlPullParserException, IOException
+ {
+ XmlUtils.beginDocument(parser, TAG_SHORTCODES);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+
+ String element = parser.getName();
+ if (element == null) break;
+
+ if (element.equals(TAG_SHORTCODE)) {
+ String currentCountry = parser.getAttributeValue(null, ATTR_COUNTRY);
+ if (country.equals(currentCountry)) {
+ String pattern = parser.getAttributeValue(null, ATTR_PATTERN);
+ String premium = parser.getAttributeValue(null, ATTR_PREMIUM);
+ String free = parser.getAttributeValue(null, ATTR_FREE);
+ String standard = parser.getAttributeValue(null, ATTR_STANDARD);
+ return new ShortCodePatternMatcher(pattern, premium, free, standard);
+ }
+ } else {
+ Log.e(TAG, "Error: skipping unknown XML tag " + element);
+ }
+ }
+ return null; // country not found
}
/** Clear the SMS application list for disposal. */
@@ -112,6 +349,90 @@
}
/**
+ * Check if the destination is a possible premium short code.
+ * NOTE: the caller is expected to strip non-digits from the destination number with
+ * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
+ * This happens in {@link SMSDispatcher#sendRawPdu} so that we use the same phone number
+ * for testing and in the user confirmation dialog if the user needs to confirm the number.
+ * This makes it difficult for malware to fool the user or the short code pattern matcher
+ * by using non-ASCII characters to make the number appear to be different from the real
+ * destination phone number.
+ *
+ * @param destAddress the destination address to test for possible short code
+ * @return {@link #CATEGORY_NOT_SHORT_CODE}, {@link #CATEGORY_FREE_SHORT_CODE},
+ * {@link #CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE}, or {@link #CATEGORY_PREMIUM_SHORT_CODE}.
+ */
+ public int checkDestination(String destAddress, String countryIso) {
+ synchronized (mSettingsObserverHandler) {
+ // always allow emergency numbers
+ if (PhoneNumberUtils.isEmergencyNumber(destAddress, countryIso)) {
+ return CATEGORY_NOT_SHORT_CODE;
+ }
+
+ ShortCodePatternMatcher patternMatcher = null;
+
+ if (countryIso != null) {
+ // query secure settings and initialize content observer for updated regex patterns
+ if (mCurrentCountry == null || !countryIso.equals(mCurrentCountry)) {
+ loadPatternsFromSettings(countryIso);
+ mSettingsObserverHandler.observeSettingForCountry(countryIso);
+ }
+
+ if (countryIso.equals(mCurrentCountry)) {
+ patternMatcher = mCurrentPatternMatcher;
+ } else {
+ patternMatcher = getPatternMatcher(countryIso);
+ mCurrentCountry = countryIso;
+ mCurrentPatternMatcher = patternMatcher; // may be null if not found
+ }
+ }
+
+ if (patternMatcher != null) {
+ return patternMatcher.getNumberCategory(destAddress);
+ } else {
+ // Generic rule: numbers of 5 digits or less are considered potential short codes
+ Log.e(TAG, "No patterns for \"" + countryIso + "\": using generic short code rule");
+ if (destAddress.length() <= 5) {
+ return CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
+ } else {
+ return CATEGORY_NOT_SHORT_CODE;
+ }
+ }
+ }
+ }
+
+ private static String getSettingNameForCountry(String countryIso) {
+ return Settings.Secure.SMS_SHORT_CODES_PREFIX + countryIso;
+ }
+
+ /**
+ * Load regex patterns from secure settings if present.
+ * @param countryIso the country to search for
+ */
+ void loadPatternsFromSettings(String countryIso) {
+ synchronized (mSettingsObserverHandler) {
+ if (VDBG) log("loadPatternsFromSettings(" + countryIso + ") called");
+ String settingsPatterns = Settings.Secure.getString(
+ mContext.getContentResolver(), getSettingNameForCountry(countryIso));
+ if (settingsPatterns != null && !settingsPatterns.equals(
+ mSettingsShortCodePatterns)) {
+ // settings pattern string has changed: update the pattern matcher
+ mSettingsShortCodePatterns = settingsPatterns;
+ ShortCodePatternMatcher matcher = getPatternMatcher(countryIso, settingsPatterns);
+ if (matcher != null) {
+ mCurrentCountry = countryIso;
+ mCurrentPatternMatcher = matcher;
+ }
+ } else if (settingsPatterns == null && mSettingsShortCodePatterns != null) {
+ // pattern string was removed: caller will load default patterns from XML resource
+ mCurrentCountry = null;
+ mCurrentPatternMatcher = null;
+ mSettingsShortCodePatterns = null;
+ }
+ }
+ }
+
+ /**
* Remove keys containing only old timestamps. This can happen if an SMS app is used
* to send messages and then uninstalled.
*/
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 4ef05ea..141736c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -51,11 +51,8 @@
*/
static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm,
DataConnectionTracker dct) {
- synchronized (mCountLock) {
- mCount += 1;
- }
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDC-" + mCount,
- id, rm, dct);
+ CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
+ "CdmaDC-" + mCount.incrementAndGet(), id, rm, dct);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
return cdmaDc;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 9801721..3e6d9a5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -56,10 +56,8 @@
*/
static GsmDataConnection makeDataConnection(PhoneBase phone, int id, RetryManager rm,
DataConnectionTracker dct) {
- synchronized (mCountLock) {
- mCount += 1;
- }
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDC-" + mCount, id, rm, dct);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone,
+ "GsmDC-" + mCount.incrementAndGet(), id, rm, dct);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
return gsmDc;
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
new file mode 100644
index 0000000..3bb7c06
--- /dev/null
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/SmsUsageMonitorShortCodeTest.java
@@ -0,0 +1,466 @@
+/*
+ * 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.internal.telephony;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_FREE_SHORT_CODE;
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_NOT_SHORT_CODE;
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_PREMIUM_SHORT_CODE;
+import static com.android.internal.telephony.SmsUsageMonitor.CATEGORY_STANDARD_SHORT_CODE;
+
+/**
+ * Test cases for SMS short code pattern matching in SmsUsageMonitor.
+ */
+public class SmsUsageMonitorShortCodeTest extends AndroidTestCase {
+
+ private static final class ShortCodeTest {
+ final String countryIso;
+ final String address;
+ final int category;
+
+ ShortCodeTest(String countryIso, String destAddress, int category) {
+ this.countryIso = countryIso;
+ this.address = destAddress;
+ this.category = category;
+ }
+ }
+
+ /**
+ * List of short code test cases.
+ */
+ private static final ShortCodeTest[] sShortCodeTests = new ShortCodeTest[] {
+ new ShortCodeTest("al", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("al", "4321", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("al", "54321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("al", "15191", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("al", "55500", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("al", "55600", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("al", "654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("am", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("am", "101", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("am", "102", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("am", "103", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("am", "222", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "1111", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "9999", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "1121", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "1141", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "1161", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("am", "3024", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("at", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("at", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("at", "0901234", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("at", "0900666266", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("au", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("au", "180000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("au", "190000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("au", "1900000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("au", "19000000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("au", "19998882", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("az", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("az", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "12345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "87744", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "3301", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "3302", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "9012", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "9014", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "9394", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "87744", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "93101", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("az", "123456", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("be", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("be", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("be", "567890", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("be", "8000", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("be", "6566", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("be", "7777", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("bg", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("bg", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("bg", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "12345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "1816", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "1915", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "1916", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "1935", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("bg", "18423", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("by", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("by", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("by", "3336", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("by", "5013", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("by", "5014", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("by", "7781", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("ca", "911", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ca", "+18005551234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ca", "8005551234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ca", "20000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ca", "200000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ca", "2000000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ca", "60999", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ca", "88188", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("ch", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ch", "123", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ch", "234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ch", "3456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ch", "98765", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ch", "543", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ch", "83111", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ch", "234567", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ch", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("cn", "120", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("cn", "1062503000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("cn", "1065123456", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("cn", "1066335588", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("cy", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("cy", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("cy", "4321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cy", "54321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cy", "654321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cy", "7510", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cy", "987654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("cz", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("cz", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("cz", "9090150", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cz", "90901599", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("cz", "987654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("de", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("de", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("de", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "12345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "8888", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "11111", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "11886", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "22022", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "23300", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "3434", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "34567", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "41414", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "55655", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "66766", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "66777", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "77677", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "80888", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "1232286", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("de", "987654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("dk", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("dk", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("dk", "1259", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("dk", "16123", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("dk", "987654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ee", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ee", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ee", "123", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "1259", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "15330", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "17999", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "17010", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "17013", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "9034567", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ee", "34567890", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("es", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("es", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("es", "25165", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("es", "27333", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("es", "995399", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("es", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("fi", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("fi", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("fi", "12345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "123456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "17159", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "17163", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "0600123", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "070012345", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fi", "987654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("fr", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("fr", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("fr", "34567", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("fr", "45678", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fr", "81185", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("fr", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("gb", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("gb", "999", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("gb", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("gb", "4567", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "45678", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "56789", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "79067", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "80079", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "654321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gb", "7654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ge", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ge", "8765", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ge", "2345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ge", "8012", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ge", "8013", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ge", "8014", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ge", "8889", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("gr", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("gr", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("gr", "54321", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gr", "19567", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gr", "19678", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("gr", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("hu", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("hu", "012", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "0123", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "1784", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "2345", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "01234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "012345678", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "0123456789", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "1234567890", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "0691227910", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("hu", "2345678901", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("hu", "01234567890", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ie", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ie", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ie", "50123", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ie", "51234", CATEGORY_STANDARD_SHORT_CODE),
+ new ShortCodeTest("ie", "52345", CATEGORY_STANDARD_SHORT_CODE),
+ new ShortCodeTest("ie", "57890", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ie", "67890", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ie", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("il", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("il", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("il", "4422", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("il", "4545", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("il", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("it", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("it", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("it", "4567", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("it", "48000", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("it", "45678", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("it", "56789", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("it", "456789", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("kg", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("kg", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kg", "4152", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kg", "4157", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kg", "4449", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kg", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("kz", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("kz", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kz", "9194", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kz", "7790", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("kz", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("lt", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("lt", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("lt", "123", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "1381", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "1394", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "1645", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "12345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lt", "123456", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("lu", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("lu", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("lu", "1234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("lu", "12345", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("lu", "64747", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lu", "678901", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("lv", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("lv", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("lv", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lv", "1819", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lv", "1863", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lv", "1874", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("lv", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("mx", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("mx", "2345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("mx", "7766", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("mx", "23456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("mx", "53035", CATEGORY_PREMIUM_SHORT_CODE),
+
+ new ShortCodeTest("my", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("my", "1234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("my", "23456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("my", "32298", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("my", "33776", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("my", "345678", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("nl", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("nl", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("nl", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nl", "4466", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nl", "5040", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nl", "23456", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("no", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("no", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("no", "2201", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("no", "2226", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("no", "2227", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("no", "23456", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("no", "234567", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("nz", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("nz", "123", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nz", "2345", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nz", "3903", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nz", "8995", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("nz", "23456", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("pl", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("pl", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("pl", "7890", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "34567", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "7910", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "74240", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "79866", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "92525", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pl", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("pt", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("pt", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("pt", "61000", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pt", "62345", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pt", "68304", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pt", "69876", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("pt", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ro", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ro", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("ro", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "1263", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "1288", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "1314", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "1380", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "7890", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ro", "12345", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ru", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ru", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ru", "1161", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ru", "2097", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ru", "3933", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ru", "7781", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ru", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("se", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("se", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("se", "1234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("se", "72345", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("se", "72999", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("se", "123456", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("se", "87654321", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("sg", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("sg", "1234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("sg", "70000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sg", "79999", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sg", "73800", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sg", "74688", CATEGORY_STANDARD_SHORT_CODE),
+ new ShortCodeTest("sg", "987654", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("si", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("si", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("si", "1234", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("si", "3838", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("si", "72999", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("sk", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("sk", "116117", CATEGORY_FREE_SHORT_CODE),
+ new ShortCodeTest("sk", "1234", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sk", "6674", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sk", "7604", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("sk", "72999", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("tj", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("tj", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("tj", "1161", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("tj", "1171", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("tj", "4161", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("tj", "4449", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("tj", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("ua", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("ua", "5432", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ua", "4448", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ua", "7094", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ua", "7540", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("ua", "98765", CATEGORY_NOT_SHORT_CODE),
+
+ new ShortCodeTest("us", "911", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("us", "+18005551234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("us", "8005551234", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("us", "20000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("us", "200000", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("us", "2000000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("us", "20433", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("us", "21472", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("us", "23333", CATEGORY_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("us", "99807", CATEGORY_PREMIUM_SHORT_CODE),
+
+ // generic rules for other countries: 5 digits or less considered potential short code
+ new ShortCodeTest("zz", "2000000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest("zz", "54321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("zz", "4321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("zz", "321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest("zz", "112", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest(null, "2000000", CATEGORY_NOT_SHORT_CODE),
+ new ShortCodeTest(null, "54321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest(null, "4321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest(null, "321", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
+ new ShortCodeTest(null, "112", CATEGORY_NOT_SHORT_CODE),
+ };
+
+ @SmallTest
+ public void testSmsUsageMonitor() {
+ SmsUsageMonitor monitor = new SmsUsageMonitor(getContext());
+ for (ShortCodeTest test : sShortCodeTests) {
+ assertEquals("country: " + test.countryIso + " number: " + test.address,
+ test.category, monitor.checkDestination(test.address, test.countryIso));
+ }
+ }
+}
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 6d81b71..0d9e4f1 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -21,6 +21,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := core core-junit framework
+LOCAL_STATIC_JAVA_LIBRARIES := junit-runner
LOCAL_MODULE:= android.test.runner
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 86689f3..0399b3b 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -545,7 +545,7 @@
* @hide
*/
@Override
- public void updateUserName(int id, String name) {
+ public void setUserName(int id, String name) {
throw new UnsupportedOperationException();
}
diff --git a/test-runner/src/junit/runner/BaseTestRunner.java b/test-runner/src/junit/runner/BaseTestRunner.java
deleted file mode 100644
index 8cfd7fa..0000000
--- a/test-runner/src/junit/runner/BaseTestRunner.java
+++ /dev/null
@@ -1,342 +0,0 @@
-package junit.runner;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.text.NumberFormat;
-import java.util.Properties;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestListener;
-import junit.framework.TestSuite;
-
-/**
- * Base class for all test runners.
- * This class was born live on stage in Sardinia during XP2000.
- */
-public abstract class BaseTestRunner implements TestListener {
- public static final String SUITE_METHODNAME= "suite";
-
- private static Properties fPreferences;
- static int fgMaxMessageLength= 500;
- static boolean fgFilterStack= true;
- boolean fLoading= true;
-
- /*
- * Implementation of TestListener
- */
- public synchronized void startTest(Test test) {
- testStarted(test.toString());
- }
-
- protected static void setPreferences(Properties preferences) {
- fPreferences= preferences;
- }
-
- protected static Properties getPreferences() {
- if (fPreferences == null) {
- fPreferences= new Properties();
- fPreferences.put("loading", "true");
- fPreferences.put("filterstack", "true");
- readPreferences();
- }
- return fPreferences;
- }
-
- public static void savePreferences() throws IOException {
- FileOutputStream fos= new FileOutputStream(getPreferencesFile());
- try {
- getPreferences().store(fos, "");
- } finally {
- fos.close();
- }
- }
-
- // android-changed remove 'static' qualifier for API compatibility
- public void setPreference(String key, String value) {
- getPreferences().put(key, value);
- }
-
- public synchronized void endTest(Test test) {
- testEnded(test.toString());
- }
-
- public synchronized void addError(final Test test, final Throwable t) {
- testFailed(TestRunListener.STATUS_ERROR, test, t);
- }
-
- public synchronized void addFailure(final Test test, final AssertionFailedError t) {
- testFailed(TestRunListener.STATUS_FAILURE, test, t);
- }
-
- // TestRunListener implementation
-
- public abstract void testStarted(String testName);
-
- public abstract void testEnded(String testName);
-
- public abstract void testFailed(int status, Test test, Throwable t);
-
- /**
- * Returns the Test corresponding to the given suite. This is
- * a template method, subclasses override runFailed(), clearStatus().
- */
- public Test getTest(String suiteClassName) {
- if (suiteClassName.length() <= 0) {
- clearStatus();
- return null;
- }
- Class testClass= null;
- try {
- testClass= loadSuiteClass(suiteClassName);
- } catch (ClassNotFoundException e) {
- String clazz= e.getMessage();
- if (clazz == null)
- clazz= suiteClassName;
- runFailed("Class not found \""+clazz+"\"");
- return null;
- } catch(Exception e) {
- runFailed("Error: "+e.toString());
- return null;
- }
- Method suiteMethod= null;
- try {
- suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
- } catch(Exception e) {
- // try to extract a test suite automatically
- clearStatus();
- return new TestSuite(testClass);
- }
- if (! Modifier.isStatic(suiteMethod.getModifiers())) {
- runFailed("Suite() method must be static");
- return null;
- }
- Test test= null;
- try {
- test= (Test)suiteMethod.invoke(null, (Object[])new Class[0]); // static method
- if (test == null)
- return test;
- }
- catch (InvocationTargetException e) {
- runFailed("Failed to invoke suite():" + e.getTargetException().toString());
- return null;
- }
- catch (IllegalAccessException e) {
- runFailed("Failed to invoke suite():" + e.toString());
- return null;
- }
-
- clearStatus();
- return test;
- }
-
- /**
- * Returns the formatted string of the elapsed time.
- */
- public String elapsedTimeAsString(long runTime) {
- return NumberFormat.getInstance().format((double)runTime/1000);
- }
-
- /**
- * Processes the command line arguments and
- * returns the name of the suite class to run or null
- */
- protected String processArguments(String[] args) {
- String suiteName= null;
- for (int i= 0; i < args.length; i++) {
- if (args[i].equals("-noloading")) {
- setLoading(false);
- } else if (args[i].equals("-nofilterstack")) {
- fgFilterStack= false;
- } else if (args[i].equals("-c")) {
- if (args.length > i+1)
- suiteName= extractClassName(args[i+1]);
- else
- System.out.println("Missing Test class name");
- i++;
- } else {
- suiteName= args[i];
- }
- }
- return suiteName;
- }
-
- /**
- * Sets the loading behaviour of the test runner
- */
- public void setLoading(boolean enable) {
- fLoading= enable;
- }
- /**
- * Extract the class name from a String in VA/Java style
- */
- public String extractClassName(String className) {
- if(className.startsWith("Default package for"))
- return className.substring(className.lastIndexOf(".")+1);
- return className;
- }
-
- /**
- * Truncates a String to the maximum length.
- */
- public static String truncate(String s) {
- if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength)
- s= s.substring(0, fgMaxMessageLength)+"...";
- return s;
- }
-
- /**
- * Override to define how to handle a failed loading of
- * a test suite.
- */
- protected abstract void runFailed(String message);
-
- // BEGIN android-changed - add back getLoader() for API compatibility
- /**
- * Returns the loader to be used.
- *
- * @deprecated not present in JUnit4.10
- */
- public TestSuiteLoader getLoader() {
- if (useReloadingTestSuiteLoader())
- return new ReloadingTestSuiteLoader();
- return new StandardTestSuiteLoader();
- }
- // END android-changed
-
- /**
- * Returns the loaded Class for a suite name.
- */
- protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
- return Class.forName(suiteClassName);
- }
-
- /**
- * Clears the status message.
- */
- protected void clearStatus() { // Belongs in the GUI TestRunner class
- }
-
- protected boolean useReloadingTestSuiteLoader() {
- return getPreference("loading").equals("true") && fLoading;
- }
-
- private static File getPreferencesFile() {
- String home= System.getProperty("user.home");
- return new File(home, "junit.properties");
- }
-
- private static void readPreferences() {
- InputStream is= null;
- try {
- is= new FileInputStream(getPreferencesFile());
- setPreferences(new Properties(getPreferences()));
- getPreferences().load(is);
- } catch (IOException e) {
- try {
- if (is != null)
- is.close();
- } catch (IOException e1) {
- }
- }
- }
-
- public static String getPreference(String key) {
- return getPreferences().getProperty(key);
- }
-
- public static int getPreference(String key, int dflt) {
- String value= getPreference(key);
- int intValue= dflt;
- if (value == null)
- return intValue;
- try {
- intValue= Integer.parseInt(value);
- } catch (NumberFormatException ne) {
- }
- return intValue;
- }
-
- /**
- * Returns a filtered stack trace
- */
- public static String getFilteredTrace(Throwable t) {
- StringWriter stringWriter= new StringWriter();
- PrintWriter writer= new PrintWriter(stringWriter);
- t.printStackTrace(writer);
- StringBuffer buffer= stringWriter.getBuffer();
- String trace= buffer.toString();
- return BaseTestRunner.getFilteredTrace(trace);
- }
-
- // BEGIN android-changed - add back this method for API compatibility
- /** @deprecated not present in JUnit4.10 */
- public static boolean inVAJava() {
- return false;
- }
- // END android-changed
-
- /**
- * Filters stack frames from internal JUnit classes
- */
- public static String getFilteredTrace(String stack) {
- if (showStackRaw())
- return stack;
-
- StringWriter sw= new StringWriter();
- PrintWriter pw= new PrintWriter(sw);
- StringReader sr= new StringReader(stack);
- // BEGIN android-changed
- // Use a sensible default buffer size
- BufferedReader br= new BufferedReader(sr, 1000);
- // END android-changed
-
- String line;
- try {
- while ((line= br.readLine()) != null) {
- if (!filterLine(line))
- pw.println(line);
- }
- } catch (Exception IOException) {
- return stack; // return the stack unfiltered
- }
- return sw.toString();
- }
-
- protected static boolean showStackRaw() {
- return !getPreference("filterstack").equals("true") || fgFilterStack == false;
- }
-
- static boolean filterLine(String line) {
- String[] patterns= new String[] {
- "junit.framework.TestCase",
- "junit.framework.TestResult",
- "junit.framework.TestSuite",
- "junit.framework.Assert.", // don't filter AssertionFailure
- "junit.swingui.TestRunner",
- "junit.awtui.TestRunner",
- "junit.textui.TestRunner",
- "java.lang.reflect.Method.invoke("
- };
- for (int i= 0; i < patterns.length; i++) {
- if (line.indexOf(patterns[i]) > 0)
- return true;
- }
- return false;
- }
-
- static {
- fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
- }
-
-}
diff --git a/test-runner/src/junit/runner/StandardTestSuiteLoader.java b/test-runner/src/junit/runner/StandardTestSuiteLoader.java
deleted file mode 100644
index 381e684..0000000
--- a/test-runner/src/junit/runner/StandardTestSuiteLoader.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package junit.runner;
-
-/**
- * The standard test suite loader. It can only load the same class once.
- * {@hide} - Not needed for 1.0 SDK
- */
-public class StandardTestSuiteLoader implements TestSuiteLoader {
- /**
- * Uses the system class loader to load the test class
- */
- public Class load(String suiteClassName) throws ClassNotFoundException {
- return Class.forName(suiteClassName);
- }
- /**
- * Uses the system class loader to load the test class
- */
- public Class reload(Class aClass) throws ClassNotFoundException {
- return aClass;
- }
-}
diff --git a/test-runner/src/junit/runner/TestRunListener.java b/test-runner/src/junit/runner/TestRunListener.java
deleted file mode 100644
index 0410f0c..0000000
--- a/test-runner/src/junit/runner/TestRunListener.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package junit.runner;
-/**
- * A listener interface for observing the
- * execution of a test run. Unlike TestListener,
- * this interface using only primitive objects,
- * making it suitable for remote test execution.
- * {@hide} - Not needed for 1.0 SDK
- */
-public interface TestRunListener {
- /* test status constants*/
- public static final int STATUS_ERROR= 1;
- public static final int STATUS_FAILURE= 2;
-
- public void testRunStarted(String testSuiteName, int testCount);
- public void testRunEnded(long elapsedTime);
- public void testRunStopped(long elapsedTime);
- public void testStarted(String testName);
- public void testEnded(String testName);
- public void testFailed(int status, String testName, String trace);
-}
diff --git a/test-runner/src/junit/runner/TestSuiteLoader.java b/test-runner/src/junit/runner/TestSuiteLoader.java
deleted file mode 100644
index 581ea23..0000000
--- a/test-runner/src/junit/runner/TestSuiteLoader.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package junit.runner;
-
-/**
- * An interface to define how a test suite should be loaded.
- */
-public interface TestSuiteLoader {
- abstract public Class load(String suiteClassName) throws ClassNotFoundException;
- abstract public Class reload(Class aClass) throws ClassNotFoundException;
-}
diff --git a/test-runner/src/junit/runner/Version.java b/test-runner/src/junit/runner/Version.java
deleted file mode 100644
index 4a6dc85..0000000
--- a/test-runner/src/junit/runner/Version.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package junit.runner;
-
-/**
- * This class defines the current version of JUnit
- */
-public class Version {
- private Version() {
- // don't instantiate
- }
-
- public static String id() {
- return "4.10";
- }
-
- // android-changed
- /** @hide - not needed for public API */
- public static void main(String[] args) {
- System.out.println(id());
- }
-}
diff --git a/test-runner/src/junit/textui/ResultPrinter.java b/test-runner/src/junit/textui/ResultPrinter.java
deleted file mode 100644
index 4b26558..0000000
--- a/test-runner/src/junit/textui/ResultPrinter.java
+++ /dev/null
@@ -1,142 +0,0 @@
-
-package junit.textui;
-
-import java.io.PrintStream;
-// The following line was removed for compatibility with Android libraries.
-//import java.text.NumberFormat;
-import java.util.Enumeration;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestFailure;
-import junit.framework.TestListener;
-import junit.framework.TestResult;
-import junit.runner.BaseTestRunner;
-
-public class ResultPrinter implements TestListener {
- PrintStream fWriter;
- int fColumn= 0;
-
- public ResultPrinter(PrintStream writer) {
- fWriter= writer;
- }
-
- /* API for use by textui.TestRunner
- */
-
- synchronized void print(TestResult result, long runTime) {
- printHeader(runTime);
- printErrors(result);
- printFailures(result);
- printFooter(result);
- }
-
- void printWaitPrompt() {
- getWriter().println();
- getWriter().println("<RETURN> to continue");
- }
-
- /* Internal methods
- */
-
- protected void printHeader(long runTime) {
- getWriter().println();
- getWriter().println("Time: "+elapsedTimeAsString(runTime));
- }
-
- protected void printErrors(TestResult result) {
- printDefects(result.errors(), result.errorCount(), "error");
- }
-
- protected void printFailures(TestResult result) {
- printDefects(result.failures(), result.failureCount(), "failure");
- }
-
- protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
- if (count == 0) return;
- if (count == 1)
- getWriter().println("There was " + count + " " + type + ":");
- else
- getWriter().println("There were " + count + " " + type + "s:");
- for (int i= 1; booBoos.hasMoreElements(); i++) {
- printDefect(booBoos.nextElement(), i);
- }
- }
-
- public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
- printDefectHeader(booBoo, count);
- printDefectTrace(booBoo);
- }
-
- protected void printDefectHeader(TestFailure booBoo, int count) {
- // I feel like making this a println, then adding a line giving the throwable a chance to print something
- // before we get to the stack trace.
- getWriter().print(count + ") " + booBoo.failedTest());
- }
-
- protected void printDefectTrace(TestFailure booBoo) {
- getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
- }
-
- protected void printFooter(TestResult result) {
- if (result.wasSuccessful()) {
- getWriter().println();
- getWriter().print("OK");
- getWriter().println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")");
-
- } else {
- getWriter().println();
- getWriter().println("FAILURES!!!");
- getWriter().println("Tests run: "+result.runCount()+
- ", Failures: "+result.failureCount()+
- ", Errors: "+result.errorCount());
- }
- getWriter().println();
- }
-
-
- /**
- * Returns the formatted string of the elapsed time.
- * Duplicated from BaseTestRunner. Fix it.
- */
- protected String elapsedTimeAsString(long runTime) {
- // The following line was altered for compatibility with
- // Android libraries.
- return Double.toString((double)runTime/1000);
- }
-
- public PrintStream getWriter() {
- return fWriter;
- }
- /**
- * @see junit.framework.TestListener#addError(Test, Throwable)
- */
- public void addError(Test test, Throwable t) {
- getWriter().print("E");
- }
-
- /**
- * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
- */
- public void addFailure(Test test, AssertionFailedError t) {
- getWriter().print("F");
- }
-
- /**
- * @see junit.framework.TestListener#endTest(Test)
- */
- public void endTest(Test test) {
- }
-
- /**
- * @see junit.framework.TestListener#startTest(Test)
- */
- public void startTest(Test test) {
- getWriter().print(".");
- if (fColumn++ >= 40) {
- getWriter().println();
- fColumn= 0;
- }
- }
-
-}
diff --git a/test-runner/src/junit/textui/TestRunner.java b/test-runner/src/junit/textui/TestRunner.java
deleted file mode 100644
index e955e0e..0000000
--- a/test-runner/src/junit/textui/TestRunner.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package junit.textui;
-
-
-import java.io.PrintStream;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-import junit.runner.BaseTestRunner;
-import junit.runner.Version;
-
-/**
- * A command line based tool to run tests.
- * <pre>
- * java junit.textui.TestRunner [-wait] TestCaseClass
- * </pre>
- *
- * <p>TestRunner expects the name of a TestCase class as argument.
- * If this class defines a static <code>suite</code> method it
- * will be invoked and the returned test is run. Otherwise all
- * the methods starting with "test" having no arguments are run.
- * <p>
- * When the wait command line argument is given TestRunner
- * waits until the users types RETURN.
- * <p>
- * TestRunner prints a trace as the tests are executed followed by a
- * summary at the end.
- */
-public class TestRunner extends BaseTestRunner {
- private ResultPrinter fPrinter;
-
- public static final int SUCCESS_EXIT= 0;
- public static final int FAILURE_EXIT= 1;
- public static final int EXCEPTION_EXIT= 2;
-
- /**
- * Constructs a TestRunner.
- */
- public TestRunner() {
- this(System.out);
- }
-
- /**
- * Constructs a TestRunner using the given stream for all the output
- */
- public TestRunner(PrintStream writer) {
- this(new ResultPrinter(writer));
- }
-
- /**
- * Constructs a TestRunner using the given ResultPrinter all the output
- */
- public TestRunner(ResultPrinter printer) {
- fPrinter= printer;
- }
-
- /**
- * Runs a suite extracted from a TestCase subclass.
- */
- static public void run(Class<? extends TestCase> testClass) {
- run(new TestSuite(testClass));
- }
-
- /**
- * Runs a single test and collects its results.
- * This method can be used to start a test run
- * from your program.
- * <pre>
- * public static void main (String[] args) {
- * test.textui.TestRunner.run(suite());
- * }
- * </pre>
- */
- static public TestResult run(Test test) {
- TestRunner runner= new TestRunner();
- return runner.doRun(test);
- }
-
- /**
- * Runs a single test and waits until the user
- * types RETURN.
- */
- static public void runAndWait(Test suite) {
- TestRunner aTestRunner= new TestRunner();
- aTestRunner.doRun(suite, true);
- }
-
- @Override
- public void testFailed(int status, Test test, Throwable t) {
- }
-
- @Override
- public void testStarted(String testName) {
- }
-
- @Override
- public void testEnded(String testName) {
- }
-
- /**
- * Creates the TestResult to be used for the test run.
- */
- protected TestResult createTestResult() {
- return new TestResult();
- }
-
- public TestResult doRun(Test test) {
- return doRun(test, false);
- }
-
- public TestResult doRun(Test suite, boolean wait) {
- TestResult result= createTestResult();
- result.addListener(fPrinter);
- long startTime= System.currentTimeMillis();
- suite.run(result);
- long endTime= System.currentTimeMillis();
- long runTime= endTime-startTime;
- fPrinter.print(result, runTime);
-
- pause(wait);
- return result;
- }
-
- protected void pause(boolean wait) {
- if (!wait) return;
- fPrinter.printWaitPrompt();
- try {
- System.in.read();
- }
- catch(Exception e) {
- }
- }
-
- public static void main(String args[]) {
- TestRunner aTestRunner= new TestRunner();
- try {
- TestResult r= aTestRunner.start(args);
- if (!r.wasSuccessful())
- System.exit(FAILURE_EXIT);
- System.exit(SUCCESS_EXIT);
- } catch(Exception e) {
- System.err.println(e.getMessage());
- System.exit(EXCEPTION_EXIT);
- }
- }
-
- /**
- * Starts a test run. Analyzes the command line arguments
- * and runs the given test suite.
- */
- public TestResult start(String args[]) throws Exception {
- String testCase= "";
- String method= "";
- boolean wait= false;
-
- for (int i= 0; i < args.length; i++) {
- if (args[i].equals("-wait"))
- wait= true;
- else if (args[i].equals("-c"))
- testCase= extractClassName(args[++i]);
- else if (args[i].equals("-m")) {
- String arg= args[++i];
- int lastIndex= arg.lastIndexOf('.');
- testCase= arg.substring(0, lastIndex);
- method= arg.substring(lastIndex + 1);
- } else if (args[i].equals("-v"))
- System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma");
- else
- testCase= args[i];
- }
-
- if (testCase.equals(""))
- throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
-
- try {
- if (!method.equals(""))
- return runSingleMethod(testCase, method, wait);
- Test suite= getTest(testCase);
- return doRun(suite, wait);
- } catch (Exception e) {
- throw new Exception("Could not create and run test suite: " + e);
- }
- }
-
- protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception {
- Class<? extends TestCase> testClass= loadSuiteClass(testCase).asSubclass(TestCase.class);
- Test test= TestSuite.createTest(testClass, method);
- return doRun(test, wait);
- }
-
- @Override
- protected void runFailed(String message) {
- System.err.println(message);
- System.exit(FAILURE_EXIT);
- }
-
- public void setPrinter(ResultPrinter printer) {
- fPrinter= printer;
- }
-
-
-}
diff --git a/tests/BiDiTests/AndroidPrivate.mk b/tests/BiDiTests/Android.mk
similarity index 100%
rename from tests/BiDiTests/AndroidPrivate.mk
rename to tests/BiDiTests/Android.mk
diff --git a/tests/Compatibility/Android.mk b/tests/Compatibility/Android.mk
new file mode 100644
index 0000000..5385413
--- /dev/null
+++ b/tests/Compatibility/Android.mk
@@ -0,0 +1,31 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src)
+
+
+LOCAL_SDK_VERSION := 8
+LOCAL_PACKAGE_NAME := AppCompatibilityTest
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/Compatibility/AndroidManifest.xml b/tests/Compatibility/AndroidManifest.xml
new file mode 100644
index 0000000..103ef4c
--- /dev/null
+++ b/tests/Compatibility/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.compatibilitytest" >
+ <application >
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name=".AppCompatibilityRunner"
+ android:targetPackage="com.android.compatibilitytest"
+ android:label="App Compability Test Runner" />
+
+ <uses-sdk android:minSdkVersion="8"></uses-sdk>
+</manifest>
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
new file mode 100644
index 0000000..4d60c83
--- /dev/null
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -0,0 +1,165 @@
+/*
+ * 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.compatibilitytest;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.ProcessErrorStateInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.Collection;
+
+/**
+ * Application Compatibility Test that launches an application and detects crashes.
+ */
+public class AppCompatibility extends InstrumentationTestCase {
+
+ private static final String TAG = "AppCompability";
+ private static final String PACKAGE_TO_LAUNCH = "package_to_launch";
+ private static final String APP_LAUNCH_TIMEOUT_MSECS = "app_launch_timeout_ms";
+ private static final String WORKSPACE_LAUNCH_TIMEOUT_MSECS = "workspace_launch_timeout_ms";
+
+ private int mAppLaunchTimeout = 7000;
+ private int mWorkspaceLaunchTimeout = 2000;
+
+ private Context mContext;
+ private ActivityManager mActivityManager;
+ private PackageManager mPackageManager;
+ private AppCompatibilityRunner mRunner;
+ private Bundle mArgs;
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+ mRunner = (AppCompatibilityRunner) getInstrumentation();
+ assertNotNull("Could not fetch InstrumentationTestRunner.",mRunner);
+
+ mContext = mRunner.getTargetContext();
+ Assert.assertNotNull("Could not get the Context", mContext);
+
+ mActivityManager = (ActivityManager)
+ mContext.getSystemService(Context.ACTIVITY_SERVICE);
+ Assert.assertNotNull("Could not get Activity Manager", mActivityManager);
+
+ mPackageManager = mContext.getPackageManager();
+ Assert.assertNotNull("Missing Package Manager", mPackageManager);
+
+ mArgs = mRunner.getBundle();
+
+ // Parse optional inputs.
+ String appLaunchTimeoutMsecs = mArgs.getString(APP_LAUNCH_TIMEOUT_MSECS);
+ if (appLaunchTimeoutMsecs != null) {
+ mAppLaunchTimeout = Integer.parseInt(appLaunchTimeoutMsecs);
+ }
+ String workspaceLaunchTimeoutMsecs = mArgs.getString(WORKSPACE_LAUNCH_TIMEOUT_MSECS);
+ if (workspaceLaunchTimeoutMsecs != null) {
+ mWorkspaceLaunchTimeout = Integer.parseInt(workspaceLaunchTimeoutMsecs);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /**
+ * Actual test case that launches the package and throws an exception on the first error.
+ * @throws Exception
+ */
+ public void testAppStability() throws Exception {
+ String packageName = mArgs.getString(PACKAGE_TO_LAUNCH);
+ if (packageName != null) {
+ Log.d(TAG, "Launching app " + packageName);
+ Collection<ProcessErrorStateInfo> err = launchActivity(packageName);
+ // Make sure there are no errors when launching the application, otherwise raise an
+ // exception with the first error encountered.
+ assertNull(getFirstError(err), err);
+ } else {
+ Log.d(TAG, "Missing argument, use " + PACKAGE_TO_LAUNCH +
+ " to specify the package to launch");
+ }
+ }
+
+ /**
+ * Gets the first error in collection and return the long message for it.
+ * @param in {@link Collection} of {@link ProcessErrorStateInfo} to parse.
+ * @return {@link String} the long message of the error.
+ */
+ private String getFirstError(Collection<ProcessErrorStateInfo> in) {
+ if (in == null) {
+ return null;
+ }
+ ProcessErrorStateInfo err = in.iterator().next();
+ if (err != null) {
+ return err.stackTrace;
+ }
+ return null;
+ }
+
+ /**
+ * Launches and activity and queries for errors.
+ * @param packageName {@link String} the package name of the application to launch.
+ * @return {@link Collection} of {@link ProcessErrorStateInfo} detected during the app launch.
+ */
+ private Collection<ProcessErrorStateInfo> launchActivity(String packageName) {
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME);
+ homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
+
+ // We check for any Crash or ANR dialogs that are already up, and we ignore them. This is
+ // so that we don't report crashes that were caused by prior apps (which those particular
+ // tests should have caught and reported already). Otherwise, test failures would cascade
+ // from the initial broken app to many/all of the tests following that app's launch.
+ final Collection<ProcessErrorStateInfo> preErr = mActivityManager.getProcessesInErrorState();
+
+ // Launch Activity
+ mContext.startActivity(intent);
+
+ try {
+ Thread.sleep(mAppLaunchTimeout);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ // Send the "home" intent and wait 2 seconds for us to get there
+ mContext.startActivity(homeIntent);
+ try {
+ Thread.sleep(mWorkspaceLaunchTimeout);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ // See if there are any errors. We wait until down here to give ANRs as much time as
+ // possible to occur.
+ final Collection<ProcessErrorStateInfo> postErr =
+ mActivityManager.getProcessesInErrorState();
+ // Take the difference between the error processes we see now, and the ones that were
+ // present when we started
+ if (preErr != null && postErr != null) {
+ postErr.removeAll(preErr);
+ }
+ return postErr;
+ }
+}
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java
new file mode 100644
index 0000000..258937f
--- /dev/null
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibilityRunner.java
@@ -0,0 +1,35 @@
+/*
+ * 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.compatibilitytest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+
+public class AppCompatibilityRunner extends InstrumentationTestRunner {
+
+ private Bundle mArgs;
+
+ @Override
+ public void onCreate(Bundle args) {
+ super.onCreate(args);
+ mArgs = args;
+ }
+
+ public Bundle getBundle() {
+ return mArgs;
+ }
+}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
index d74f5f7..9d621d6 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
@@ -19,7 +19,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.webkit.MockGeolocation;
import android.webkit.WebStorage;
import java.util.HashMap;
@@ -48,7 +47,6 @@
private static final int EVENT_CLEAR_TOUCH_POINTS = 17;
private static final int EVENT_CANCEL_TOUCH_POINT = 18;
private static final int EVENT_SET_TOUCH_MODIFIER = 19;
-
private static final int LAYOUT_CLEAR_LIST = 20;
private static final int LAYOUT_DISPLAY = 21;
private static final int LAYOUT_DUMP_TEXT = 22;
@@ -72,10 +70,9 @@
private static final int LAYOUT_WAIT_UNTIL_DONE = 40;
private static final int LAYOUT_DUMP_DATABASE_CALLBACKS = 41;
private static final int LAYOUT_SET_CAN_OPEN_WINDOWS = 42;
- private static final int SET_GEOLOCATION_PERMISSION = 43;
- private static final int OVERRIDE_PREFERENCE = 44;
- private static final int LAYOUT_DUMP_CHILD_FRAMES_TEXT = 45;
- private static final int SET_XSS_AUDITOR_ENABLED = 46;
+ private static final int OVERRIDE_PREFERENCE = 43;
+ private static final int LAYOUT_DUMP_CHILD_FRAMES_TEXT = 44;
+ private static final int SET_XSS_AUDITOR_ENABLED = 45;
CallbackProxy(EventSender eventSender,
LayoutTestController layoutTestController) {
@@ -269,11 +266,6 @@
mLayoutTestController.setCanOpenWindows();
break;
- case SET_GEOLOCATION_PERMISSION:
- mLayoutTestController.setGeolocationPermission(
- msg.arg1 == 1 ? true : false);
- break;
-
case OVERRIDE_PREFERENCE:
String key = msg.getData().getString("key");
boolean value = msg.getData().getBoolean("value");
@@ -497,17 +489,23 @@
public void setMockGeolocationPosition(double latitude,
double longitude,
double accuracy) {
- MockGeolocation.getInstance().setPosition(latitude,
- longitude,
- accuracy);
+ // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
+ // as we need access to the Webview.
+ mLayoutTestController.setMockGeolocationPosition(latitude,
+ longitude,
+ accuracy);
}
public void setMockGeolocationError(int code, String message) {
- MockGeolocation.getInstance().setError(code, message);
+ // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
+ // as we need access to the Webview.
+ mLayoutTestController.setMockGeolocationError(code, message);
}
public void setGeolocationPermission(boolean allow) {
- obtainMessage(SET_GEOLOCATION_PERMISSION, allow ? 1 : 0, 0).sendToTarget();
+ // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
+ // as we need access to the Webview.
+ mLayoutTestController.setGeolocationPermission(allow);
}
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
index 9be2f1c..c936a6c 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
@@ -72,6 +72,10 @@
// For XSSAuditor tests
public void setXSSAuditorEnabled(boolean flag);
+ // For Geolocation tests
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy);
+ public void setMockGeolocationError(int code, String message);
+
// For DeviceOrientation tests
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index bbfbfc4..42d6457 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -539,24 +539,21 @@
mCanOpenWindows = true;
}
- /**
- * Sets the Geolocation permission state to be used for all future requests.
- */
+ @Override
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
+ WebViewClassic.fromWebView(mWebView).setMockGeolocationPosition(latitude, longitude,
+ accuracy);
+ }
+
+ @Override
+ public void setMockGeolocationError(int code, String message) {
+ WebViewClassic.fromWebView(mWebView).setMockGeolocationError(code, message);
+ }
+
@Override
public void setGeolocationPermission(boolean allow) {
- mIsGeolocationPermissionSet = true;
- mGeolocationPermission = allow;
-
- if (mPendingGeolocationPermissionCallbacks != null) {
- Iterator iter = mPendingGeolocationPermissionCallbacks.keySet().iterator();
- while (iter.hasNext()) {
- GeolocationPermissions.Callback callback =
- (GeolocationPermissions.Callback) iter.next();
- String origin = (String) mPendingGeolocationPermissionCallbacks.get(callback);
- callback.invoke(origin, mGeolocationPermission, false);
- }
- mPendingGeolocationPermissionCallbacks = null;
- }
+ Log.v(LOGTAG, "setGeolocationPermission() allow=" + allow);
+ WebViewClassic.fromWebView(mWebView).setMockGeolocationPermission(allow);
}
@Override
@@ -749,22 +746,11 @@
callback.updateQuota(currentQuota + 1024 * 1024 * 5);
}
- /**
- * Instructs the client to show a prompt to ask the user to set the
- * Geolocation permission state for the specified origin.
- */
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
- if (mIsGeolocationPermissionSet) {
- callback.invoke(origin, mGeolocationPermission, false);
- return;
- }
- if (mPendingGeolocationPermissionCallbacks == null) {
- mPendingGeolocationPermissionCallbacks =
- new HashMap<GeolocationPermissions.Callback, String>();
- }
- mPendingGeolocationPermissionCallbacks.put(callback, origin);
+ throw new RuntimeException(
+ "The WebCore mock used by DRT should bypass the usual permissions flow.");
}
@Override
@@ -849,9 +835,8 @@
mPageFinished = false;
mDumpWebKitData = false;
setDefaultWebSettings(mWebView);
- mIsGeolocationPermissionSet = false;
- mPendingGeolocationPermissionCallbacks = null;
CookieManager.getInstance().removeAllCookie();
+ mWebViewClassic.setUseMockGeolocation();
}
private boolean canMoveToNextTest() {
@@ -958,8 +943,4 @@
static final int DRAW_RUNS = 5;
static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
"/android/page_draw_time.txt";
-
- private boolean mIsGeolocationPermissionSet;
- private boolean mGeolocationPermission;
- private Map mPendingGeolocationPermissionCallbacks;
}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
index d0c59d3..c9c35ce 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
@@ -80,6 +80,17 @@
quota);
}
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
+ Log.i(LOG_TAG, "setMockGeolocationPosition(): " + "latitude=" + latitude +
+ " longitude=" + longitude + " accuracy=" + accuracy);
+ mLayoutTestsExecutor.setMockGeolocationPosition(latitude, longitude, accuracy);
+ }
+
+ public void setMockGeolocationError(int code, String message) {
+ Log.i(LOG_TAG, "setMockGeolocationError(): " + "code=" + code + " message=" + message);
+ mLayoutTestsExecutor.setMockGeolocationError(code, message);
+ }
+
public void setGeolocationPermission(boolean allow) {
mLayoutTestsExecutor.setGeolocationPermission(allow);
}
@@ -95,17 +106,6 @@
canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
}
- public void setMockGeolocationError(int code, String message) {
- Log.i(LOG_TAG, "setMockGeolocationError(): " + "code=" + code + " message=" + message);
- MockGeolocation.getInstance().setError(code, message);
- }
-
- public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
- Log.i(LOG_TAG, "setMockGeolocationPosition(): " + "latitude=" + latitude +
- " longitude=" + longitude + " accuracy=" + accuracy);
- MockGeolocation.getInstance().setPosition(latitude, longitude, accuracy);
- }
-
public void setXSSAuditorEnabled(boolean flag) {
mLayoutTestsExecutor.setXSSAuditorEnabled(flag);
}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
index f958ade..25ac700 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
@@ -109,9 +109,6 @@
private LayoutTestController mLayoutTestController = new LayoutTestController(this);
private boolean mCanOpenWindows;
private boolean mDumpDatabaseCallbacks;
- private boolean mIsGeolocationPermissionSet;
- private boolean mGeolocationPermission;
- private Map<GeolocationPermissions.Callback, String> mPendingGeolocationPermissionCallbacks;
private EventSender mEventSender = new EventSender();
@@ -255,15 +252,8 @@
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
- if (mIsGeolocationPermissionSet) {
- callback.invoke(origin, mGeolocationPermission, false);
- return;
- }
- if (mPendingGeolocationPermissionCallbacks == null) {
- mPendingGeolocationPermissionCallbacks =
- new HashMap<GeolocationPermissions.Callback, String>();
- }
- mPendingGeolocationPermissionCallbacks.put(callback, origin);
+ throw new RuntimeException(
+ "The WebCore mock used by DRT should bypass the usual permissions flow.");
}
};
@@ -394,6 +384,7 @@
webViewSettings.setPageCacheCapacity(0);
// This is asynchronous, but it gets processed by WebCore before it starts loading pages.
+ WebViewClassic.fromWebView(mCurrentWebView).setUseMockGeolocation();
WebViewClassic.fromWebView(mCurrentWebView).setUseMockDeviceOrientation();
// Must do this after setting the AppCache path.
@@ -573,9 +564,8 @@
private static final int MSG_DUMP_CHILD_FRAMES_AS_TEXT = 3;
private static final int MSG_SET_CAN_OPEN_WINDOWS = 4;
private static final int MSG_DUMP_DATABASE_CALLBACKS = 5;
- private static final int MSG_SET_GEOLOCATION_PERMISSION = 6;
- private static final int MSG_OVERRIDE_PREFERENCE = 7;
- private static final int MSG_SET_XSS_AUDITOR_ENABLED = 8;
+ private static final int MSG_OVERRIDE_PREFERENCE = 6;
+ private static final int MSG_SET_XSS_AUDITOR_ENABLED = 7;
/** String constants for use with layoutTestController.overridePreference() */
private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
@@ -644,22 +634,6 @@
mCanOpenWindows = true;
break;
- case MSG_SET_GEOLOCATION_PERMISSION:
- mIsGeolocationPermissionSet = true;
- mGeolocationPermission = msg.arg1 == 1;
-
- if (mPendingGeolocationPermissionCallbacks != null) {
- Iterator<GeolocationPermissions.Callback> iter =
- mPendingGeolocationPermissionCallbacks.keySet().iterator();
- while (iter.hasNext()) {
- GeolocationPermissions.Callback callback = iter.next();
- String origin = mPendingGeolocationPermissionCallbacks.get(callback);
- callback.invoke(origin, mGeolocationPermission, false);
- }
- mPendingGeolocationPermissionCallbacks = null;
- }
- break;
-
case MSG_SET_XSS_AUDITOR_ENABLED:
WebViewClassic.fromWebView(mCurrentWebView).getSettings().
setXSSAuditorEnabled(msg.arg1 == 1);
@@ -679,8 +653,6 @@
private void resetLayoutTestController() {
mCanOpenWindows = false;
mDumpDatabaseCallbacks = false;
- mIsGeolocationPermissionSet = false;
- mPendingGeolocationPermissionCallbacks = null;
}
public void dumpAsText(boolean enablePixelTest) {
@@ -721,12 +693,19 @@
mLayoutTestControllerHandler.sendEmptyMessage(MSG_SET_CAN_OPEN_WINDOWS);
}
+ public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
+ WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationPosition(latitude, longitude,
+ accuracy);
+ }
+
+ public void setMockGeolocationError(int code, String message) {
+ WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationError(code, message);
+ }
+
public void setGeolocationPermission(boolean allow) {
Log.i(LOG_TAG, mCurrentTestRelativePath + ": setGeolocationPermission(" + allow +
") called");
- Message msg = mLayoutTestControllerHandler.obtainMessage(MSG_SET_GEOLOCATION_PERMISSION);
- msg.arg1 = allow ? 1 : 0;
- msg.sendToTarget();
+ WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationPermission(allow);
}
public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index d0f3e62..36f13b1 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -84,6 +84,7 @@
unitTests.add(new UT_struct(this, mRes, mCtx));
unitTests.add(new UT_math(this, mRes, mCtx));
unitTests.add(new UT_math_conformance(this, mRes, mCtx));
+ unitTests.add(new UT_math_agree(this, mRes, mCtx));
unitTests.add(new UT_element(this, mRes, mCtx));
unitTests.add(new UT_sampler(this, mRes, mCtx));
unitTests.add(new UT_program_store(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java
new file mode 100644
index 0000000..32a4bd7
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java
@@ -0,0 +1,57 @@
+/*
+ * 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.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import java.util.Random;
+
+public class UT_math_agree extends UnitTest {
+ private Resources mRes;
+
+ protected UT_math_agree(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Math Agreement", ctx);
+ mRes = res;
+ }
+
+ private void initializeValues(ScriptC_math_agree s) {
+ Random rand = new Random();
+
+ float x = rand.nextFloat();
+ float y = rand.nextFloat();
+
+ s.set_x(x);
+ s.set_y(y);
+ s.set_result_add(x + y);
+ s.set_result_sub(x - y);
+ s.set_result_mul(x * y);
+ s.set_result_div(x / y);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_math_agree s = new ScriptC_math_agree(pRS, mRes,
+ R.raw.math_agree);
+ pRS.setMessageHandler(mRsMessage);
+ initializeValues(s);
+ s.invoke_math_agree_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs
new file mode 100644
index 0000000..953b9de
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs
@@ -0,0 +1,54 @@
+#include "shared.rsh"
+//#pragma rs_fp_relaxed
+
+float x = 0.0f;
+float y = 0.0f;
+float result_add = 0.0f;
+float result_sub = 0.0f;
+float result_mul = 0.0f;
+float result_div = 0.0f;
+
+#define TEST_OP(op, opName) \
+result = x op y; \
+if (! float_almost_equal(result, result_##opName)) { \
+ rsDebug(#opName " did not match!", 0); \
+ rsDebug("x = ", x); \
+ rsDebug("y = ", y); \
+ rsDebug("Result = ", result); \
+ rsDebug("Expected = ", result_##opName); \
+ rsDebug("Difference = ", result - result_##opName); \
+ rsDebug("ULP Difference =", float_dist(result, result_##opName)); \
+ failed = true; \
+}
+
+static bool test_math_agree() {
+ bool failed = false;
+ float result = 0.0;
+
+ TEST_OP(+, add);
+ TEST_OP(-, sub);
+ TEST_OP(*, mul);
+ TEST_OP(/, div);
+
+ if (failed) {
+ rsDebug("test_math_agree FAILED", 0);
+ }
+ else {
+ rsDebug("test_math_agree PASSED", 0);
+ }
+
+ return failed;
+}
+
+void math_agree_test() {
+ bool failed = false;
+ failed |= test_math_agree();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs
index f7942a5..68ac168 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs
@@ -2,6 +2,9 @@
// Testing primitive types
float floatTest = 1.99f;
+float2 float2Test = {2.99f, 12.99f};
+float3 float3Test = {3.99f, 13.99f, 23.99f};
+float4 float4Test = {4.99f, 14.99f, 24.99f, 34.99f};
double doubleTest = 2.05;
char charTest = -8;
short shortTest = -16;
@@ -23,6 +26,9 @@
// For this reason, none of the outputs are actually checked.
rsDebug("floatTest", floatTest);
+ rsDebug("float2Test", float2Test);
+ rsDebug("float3Test", float3Test);
+ rsDebug("float4Test", float4Test);
rsDebug("doubleTest", doubleTest);
rsDebug("charTest", charTest);
rsDebug("shortTest", shortTest);
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
index 8cdf0d8..3adc999 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
@@ -74,6 +74,40 @@
return isposzero(f) || isnegzero(f);
}
+/* Absolute epsilon used for floats. Value is similar to float.h. */
+#ifndef FLT_EPSILON
+#define FLT_EPSILON 1.19e7f
+#endif
+/* Max ULPs while still being considered "equal". Only used when this number
+ of ULPs is of a greater size than FLT_EPSILON. */
+#define FLT_MAX_ULP 1
+
+/* Calculate the difference in ULPs between the two values. (Return zero on
+ perfect equality.) */
+static int float_dist(float f1, float f2) {
+ return *((int *)(&f1)) - *((int *)(&f2));
+}
+
+/* Check if two floats are essentially equal. Will fail with some values
+ due to design. (Validate using FLT_EPSILON or similar if necessary.) */
+static bool float_almost_equal(float f1, float f2) {
+ int *i1 = (int*)(&f1);
+ int *i2 = (int*)(&f2);
+
+ // Check for sign equality
+ if ( ((*i1 >> 31) == 0) != ((*i2 >> 31) == 0) ) {
+ // Handle signed zeroes
+ if (f1 == f2)
+ return true;
+ return false;
+ }
+
+ // Check with ULP distance
+ if (float_dist(f1, f2) > FLT_MAX_ULP)
+ return false;
+ return true;
+}
+
/* These constants must match those in UnitTest.java */
static const int RS_MSG_TEST_PASSED = 100;
static const int RS_MSG_TEST_FAILED = 101;
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java
new file mode 100644
index 0000000..3f0e2b3
--- /dev/null
+++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeChildFrameTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/**
+ * Part of the test suite for the WebView's Java Bridge.
+ *
+ * Ensures that injected objects are exposed to child frames as well as the
+ * main frame.
+ *
+ * To run this test ...
+ * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeChildFrameTest \
+ * com.android.webviewtests/android.test.InstrumentationTestRunner
+ */
+
+package com.android.webviewtests;
+
+public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
+ private class TestController extends Controller {
+ private String mStringValue;
+
+ public synchronized void setStringValue(String x) {
+ mStringValue = x;
+ notifyResultIsReady();
+ }
+ public synchronized String waitForStringValue() {
+ waitForResult();
+ return mStringValue;
+ }
+ }
+
+ TestController mTestController;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestController = new TestController();
+ setUpWebView(mTestController, "testController");
+ }
+
+ public void testInjectedObjectPresentInChildFrame() throws Throwable {
+ // In the case that the test fails (i.e. the child frame doesn't get the injected object,
+ // the call to testController.setStringValue in the child frame's onload handler will
+ // not be made.
+ getActivity().getWebView().loadData(
+ "<html><head></head><body>" +
+ "<iframe id=\"childFrame\" onload=\"testController.setStringValue('PASS');\" />" +
+ "</body></html>", "text/html", null);
+ assertEquals("PASS", mTestController.waitForStringValue());
+ }
+}
diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java
index 1af3f63..a451015 100644
--- a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java
+++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java
@@ -106,7 +106,12 @@
runTestOnUiThread(new Runnable() {
@Override
public void run() {
- getWebView().loadUrl("javascript:" + script);
+ // When a JavaScript URL is executed, if the value of the last
+ // expression evaluated is not 'undefined', this value is
+ // converted to a string and used as the new document for the
+ // frame. We don't want this behaviour, so wrap the script in
+ // an anonymous function.
+ getWebView().loadUrl("javascript:(function() { " + script + " })()");
}
});
}
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
index e5fa076..5e4dacc 100644
--- a/tools/aidl/generate_java_rpc.cpp
+++ b/tools/aidl/generate_java_rpc.cpp
@@ -786,7 +786,10 @@
}
// Call the callback method
- dispatchMethod->statements->Add(realCall);
+ IfStatement* ifst = new IfStatement;
+ ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE);
+ dispatchMethod->statements->Add(ifst);
+ ifst->statements->Add(realCall);
}
static void
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index a5db7b1..3c124d9 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -2,10 +2,10 @@
<classpath>
<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
- <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
+ <classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 7f8f9ce..23b1b44 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -697,7 +697,7 @@
setInitialState(mInitialState);
- setProcessedMessagesSize(100);
+ setLogRecSize(100);
if (DBG) setDbg(true);
//start the state machine
@@ -1151,7 +1151,7 @@
}
@Override
- protected boolean recordProcessedMessage(Message msg) {
+ protected boolean recordLogRec(Message msg) {
//Ignore screen on/off & common messages when driver has started
if (getCurrentState() == mConnectedState || getCurrentState() == mDisconnectedState) {
switch (msg.what) {
@@ -1651,7 +1651,7 @@
handlePostDhcpSetup();
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
- mDhcpStateMachine.quit();
+ mDhcpStateMachine.doQuit();
mDhcpStateMachine = null;
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 9e004d0..6978084 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -1192,11 +1192,11 @@
}
if (mGroup.isGroupOwner()) {
- stopDhcpServer();
+ stopDhcpServer(mGroup.getInterface());
} else {
if (DBG) logd("stop DHCP client");
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
- mDhcpStateMachine.quit();
+ mDhcpStateMachine.doQuit();
mDhcpStateMachine = null;
}
@@ -1412,9 +1412,10 @@
logd("Started Dhcp server on " + intf);
}
- private void stopDhcpServer() {
+ private void stopDhcpServer(String intf) {
try {
mNwService.stopTethering();
+ mNwService.clearInterfaceAddresses(intf);
} catch (Exception e) {
loge("Error stopping Dhcp server" + e);
return;