Merge "Environment.isExternalStorageRemovable() is false if external storage is emulated" into honeycomb
diff --git a/Android.mk b/Android.mk
index f581515..5d989d1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -167,6 +167,7 @@
core/java/com/android/internal/view/IInputMethodManager.aidl \
core/java/com/android/internal/view/IInputMethodSession.aidl \
core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
+ core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
location/java/android/location/ICountryDetector.aidl \
location/java/android/location/ICountryListener.aidl \
location/java/android/location/IGeocodeProvider.aidl \
diff --git a/api/11.xml b/api/11.xml
index 5087eca..6c06a0a 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -188,6 +188,17 @@
visibility="public"
>
</field>
+<field name="BIND_REMOTEVIEWS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.permission.BIND_REMOTEVIEWS""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="BIND_WALLPAPER"
type="java.lang.String"
transient="false"
@@ -252332,6 +252343,23 @@
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
+<method name="setRemoteAdapter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="appWidgetId" type="int">
+</parameter>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+</method>
<method name="setScrollPosition"
return="void"
abstract="false"
diff --git a/api/current.xml b/api/current.xml
index 4f566f6..73581f1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -188,6 +188,17 @@
visibility="public"
>
</field>
+<field name="BIND_REMOTEVIEWS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.permission.BIND_REMOTEVIEWS""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="BIND_WALLPAPER"
type="java.lang.String"
transient="false"
@@ -10894,6 +10905,17 @@
visibility="public"
>
</field>
+<field name="windowCloseOnTouchOutside"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843611"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowContentOverlay"
type="int"
transient="false"
@@ -24300,6 +24322,19 @@
<parameter name="uri" type="android.net.Uri">
</parameter>
</method>
+<method name="setFinishOnTouchOutside"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finish" type="boolean">
+</parameter>
+</method>
<method name="setIntent"
return="void"
abstract="false"
@@ -136088,6 +136123,17 @@
visibility="public"
>
</method>
+<method name="getPreserveEGLContextOnPause"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getRenderMode"
return="int"
abstract="false"
@@ -136259,6 +136305,19 @@
<parameter name="glWrapper" type="android.opengl.GLSurfaceView.GLWrapper">
</parameter>
</method>
+<method name="setPreserveEGLContextOnPause"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="preserveOnPause" type="boolean">
+</parameter>
+</method>
<method name="setRenderMode"
return="void"
abstract="false"
@@ -175648,6 +175707,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_PAN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""pan""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEY_PARAM_STREAM"
type="java.lang.String"
transient="false"
@@ -175670,6 +175740,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_VOLUME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""volume""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<interface name="TextToSpeech.OnInitListener"
abstract="true"
@@ -219410,6 +219491,14 @@
<parameter name="view" type="android.view.View">
</parameter>
</constructor>
+<constructor name="View.DragShadowBuilder"
+ type="android.view.View.DragShadowBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
<method name="getView"
return="android.view.View"
abstract="false"
@@ -252399,6 +252488,23 @@
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
+<method name="setRemoteAdapter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="appWidgetId" type="int">
+</parameter>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+</method>
<method name="setScrollPosition"
return="void"
abstract="false"
@@ -260192,7 +260298,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 9cbc7be..e6eaf71 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1019,6 +1019,10 @@
AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
+ // See FLAT_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag.
+ // Since it was set in Eclair+ we can't change it without breaking apps using
+ // the intent from a non-Activity context.
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(
String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid)));
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 93ad17e..0a64070 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1808,6 +1808,14 @@
}
/**
+ * Sets whether this activity is finished when touched outside its window's
+ * bounds.
+ */
+ public void setFinishOnTouchOutside(boolean finish) {
+ mWindow.setCloseOnTouchOutside(finish);
+ }
+
+ /**
* Use with {@link #setDefaultKeyMode} to turn off default handling of
* keys.
*
@@ -2063,6 +2071,11 @@
* The default implementation always returns false.
*/
public boolean onTouchEvent(MotionEvent event) {
+ if (mWindow.shouldCloseOnTouch(this, event)) {
+ finish();
+ return true;
+ }
+
return false;
}
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 70e3616..428f4e3 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -64,11 +64,13 @@
protected AlertDialog(Context context, int theme) {
super(context, theme == 0 ? getDefaultDialogTheme(context) : theme);
+ mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(context, this, getWindow());
}
protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, getDefaultDialogTheme(context));
+ mWindow.alwaysReadCloseOnTouchAttr();
setCancelable(cancelable);
setOnCancelListener(cancelListener);
mAlert = new AlertController(context, this, getWindow());
@@ -81,25 +83,6 @@
return outValue.resourceId;
}
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mCancelable) {
- final View decor = mWindow.getDecorView();
- final int width = decor.getWidth();
- final int height = decor.getHeight();
- final float x = ev.getX();
- final float y = ev.getY();
-
- if (mCancelable && (x < 0 || x > width || y < 0 || y > height)
- && mDecor != null && isShowing()) {
- cancel();
- return true;
- }
- }
-
- return super.onTouchEvent(ev);
- }
-
/**
* Gets one of the buttons used in the dialog.
* <p>
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 6791400..7365670 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -41,7 +41,6 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
@@ -90,12 +89,6 @@
private Message mDismissMessage;
private Message mShowMessage;
- /**
- * Whether to cancel the dialog when a touch is received outside of the
- * window's bounds.
- */
- private boolean mCanceledOnTouchOutside = false;
-
private OnKeyListener mOnKeyListener;
private boolean mCreated = false;
@@ -597,8 +590,7 @@
* happens outside of the window bounds.
*/
public boolean onTouchEvent(MotionEvent event) {
- if (mCancelable && mCanceledOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
- && isOutOfBounds(event) && mDecor != null && mShowing) {
+ if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
cancel();
return true;
}
@@ -606,16 +598,6 @@
return false;
}
- private boolean isOutOfBounds(MotionEvent event) {
- final int x = (int) event.getX();
- final int y = (int) event.getY();
- final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
- final View decorView = getWindow().getDecorView();
- return (x < -slop) || (y < -slop)
- || (x > (decorView.getWidth()+slop))
- || (y > (decorView.getHeight()+slop));
- }
-
/**
* Called when the trackball was moved and not handled by any of the
* views inside of the activity. So, for example, if the trackball moves
@@ -1021,7 +1003,7 @@
mCancelable = true;
}
- mCanceledOnTouchOutside = cancel;
+ mWindow.setCloseOnTouchOutside(cancel);
}
/**
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 2a583c1..019652c 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -438,6 +439,47 @@
}
/**
+ * Binds the RemoteViewsService for a given appWidgetId and intent.
+ *
+ * The appWidgetId specified must already be bound to the calling AppWidgetHost via
+ * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
+ *
+ * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
+ * @param intent The intent of the service which will be providing the data to the
+ * RemoteViewsAdapter.
+ * @param connection The callback interface to be notified when a connection is made or lost.
+ * @hide
+ */
+ public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
+ try {
+ sService.bindRemoteViewsService(appWidgetId, intent, connection);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
+ * Unbinds the RemoteViewsService for a given appWidgetId and intent.
+ *
+ * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
+ * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
+ *
+ * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
+ * @param intent The intent of the service which will be providing the data to the
+ * RemoteViewsAdapter.
+ * @hide
+ */
+ public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
+ try {
+ sService.unbindRemoteViewsService(appWidgetId, intent);
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
+ }
+
+ /**
* Get the list of appWidgetIds that have been bound to the given AppWidget
* provider.
*
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index af7b28b..35f1c58 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -211,6 +211,12 @@
* {@link android.R.style#Theme_Holo}.
* <li> The activity lifecycle has changed slightly as per
* {@link android.app.Activity}.
+ * <li> When an application requires a permission to access on of
+ * its components (activity, receiver, service, provider), this
+ * permission is no longer enforced when the application wants to
+ * access its own component. This means it can require a permission
+ * on a component that it does not itself hold and still access that
+ * component.
* </ul>
*/
public static final int HONEYCOMB = CUR_DEVELOPMENT;
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index f010076..c46d2c5 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -349,19 +349,17 @@
*/
public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
/**
- * {@hide}
* Parameter key to specify the speech volume relative to the current stream type
* volume used when speaking text. Volume is specified as a float ranging from 0 to 1
- * where 0 is silence, and 1 is the maximum volume.
+ * where 0 is silence, and 1 is the maximum volume (the default behavior).
* @see TextToSpeech#speak(String, int, HashMap)
* @see TextToSpeech#playEarcon(String, int, HashMap)
*/
public static final String KEY_PARAM_VOLUME = "volume";
/**
- * {@hide}
* Parameter key to specify how the speech is panned from left to right when speaking text.
* Pan is specified as a float ranging from -1 to +1 where -1 maps to a hard-left pan,
- * 0 to center, and +1 to hard-right.
+ * 0 to center (the default behavior), and +1 to hard-right.
* @see TextToSpeech#speak(String, int, HashMap)
* @see TextToSpeech#playEarcon(String, int, HashMap)
*/
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f9a6c1b..addd1b3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -84,6 +84,13 @@
* @return True if the initialization was successful, false otherwise.
*/
abstract boolean initialize(SurfaceHolder holder);
+
+ /**
+ * Updates the hardware renderer for the specified surface.
+ *
+ * @param holder The holder for the surface to hardware accelerate.
+ */
+ abstract void updateSurface(SurfaceHolder holder);
/**
* Setup the hardware renderer for drawing. This is called for every
@@ -330,6 +337,13 @@
}
return false;
}
+
+ @Override
+ void updateSurface(SurfaceHolder holder) {
+ if (isRequested() && isEnabled()) {
+ createEglSurface(holder);
+ }
+ }
abstract GLES20Canvas createCanvas();
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index e203355..0326a8f 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -159,6 +159,8 @@
private Canvas mCanvas;
@SuppressWarnings("unused")
private int mNativeSurface;
+ @SuppressWarnings("unused")
+ private int mSurfaceGenerationId;
private String mName;
// The display metrics used to provide the pseudo canvas size for applications
@@ -308,6 +310,13 @@
* returns false.
*/
public native boolean isValid();
+
+ /**
+ * @hide
+ */
+ public int getGenerationId() {
+ return mSurfaceGenerationId;
+ }
/** Free all server-side state associated with this surface and
* release this object's reference. {@hide} */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 53fc0c0..270ea76 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10606,13 +10606,38 @@
private final WeakReference<View> mView;
/**
- * Construct a shadow builder object for use with the given view.
- * @param view
+ * Construct a shadow builder object for use with the given View object. The
+ * default implementation will construct a drag shadow the same size and
+ * appearance as the supplied View.
+ *
+ * @param view A view within the application's layout whose appearance
+ * should be replicated as the drag shadow.
*/
public DragShadowBuilder(View view) {
mView = new WeakReference<View>(view);
}
+ /**
+ * Construct a shadow builder object with no associated View. This
+ * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
+ * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
+ * to supply the drag shadow's dimensions and appearance without
+ * reference to any View object.
+ */
+ public DragShadowBuilder() {
+ mView = new WeakReference<View>(null);
+ }
+
+ /**
+ * Returns the View object that had been passed to the
+ * {@link #View.DragShadowBuilder(View)}
+ * constructor. If that View parameter was {@code null} or if the
+ * {@link #View.DragShadowBuilder()}
+ * constructor was used to instantiate the builder object, this method will return
+ * null.
+ *
+ * @return The View object associate with this builder object.
+ */
final public View getView() {
return mView.get();
}
@@ -10623,8 +10648,10 @@
* be centered under the touch location while dragging.
* <p>
* The default implementation sets the dimensions of the shadow to be the
- * same as the dimensions of the View itself and centers the shadow under
- * the touch point.
+ * same as the dimensions of the View object that had been supplied to the
+ * {@link #View.DragShadowBuilder(View)} constructor
+ * when the builder object was instantiated, and centers the shadow under the touch
+ * point.
*
* @param shadowSize The application should set the {@code x} member of this
* parameter to the desired shadow width, and the {@code y} member to
@@ -10647,6 +10674,11 @@
* Draw the shadow image for the upcoming drag. The shadow canvas was
* created with the dimensions supplied by the
* {@link #onProvideShadowMetrics(Point, Point)} callback.
+ * <p>
+ * The default implementation replicates the appearance of the View object
+ * that had been supplied to the
+ * {@link #View.DragShadowBuilder(View)}
+ * constructor when the builder object was instantiated.
*
* @param canvas
*/
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 96f8cdc..961b633 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -983,6 +983,8 @@
Log.i(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" +
host.getMeasuredHeight() + ", params=" + params);
}
+
+ final int surfaceGenerationId = mSurface.getGenerationId();
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
if (params != null) {
@@ -1043,6 +1045,9 @@
mScroller.abortAnimation();
}
disposeResizeBitmap();
+ } else if (surfaceGenerationId != mSurface.getGenerationId() &&
+ mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.updateSurface(mHolder);
}
} catch (RemoteException e) {
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2f27935..217e731 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -116,6 +116,8 @@
private Window mActiveChild;
private boolean mIsActive = false;
private boolean mHasChildren = false;
+ private boolean mCloseOnTouchOutside = false;
+ private boolean mSetCloseOnTouchOutside = false;
private int mForcedWindowFlags = 0;
private int mFeatures = DEFAULT_FEATURES;
@@ -786,6 +788,42 @@
return mHasSoftInputMode;
}
+ /** @hide */
+ public void setCloseOnTouchOutside(boolean close) {
+ mCloseOnTouchOutside = close;
+ mSetCloseOnTouchOutside = true;
+ }
+
+ /** @hide */
+ public void setCloseOnTouchOutsideIfNotSet(boolean close) {
+ if (!mSetCloseOnTouchOutside) {
+ mCloseOnTouchOutside = close;
+ mSetCloseOnTouchOutside = true;
+ }
+ }
+
+ /** @hide */
+ public abstract void alwaysReadCloseOnTouchAttr();
+
+ /** @hide */
+ public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
+ if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
+ && isOutOfBounds(context, event) && peekDecorView() != null) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isOutOfBounds(Context context, MotionEvent event) {
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
+ final View decorView = getDecorView();
+ return (x < -slop) || (y < -slop)
+ || (x > (decorView.getWidth()+slop))
+ || (y > (decorView.getHeight()+slop));
+ }
+
/**
* Enable extended screen features. This must be called before
* setContentView(). May be called as many times as desired as long as it
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 85bff4f..d8f34e0 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -495,6 +495,7 @@
break;
}
case ENDED:
+ mSeekPosition = 0;
nativeOnEnded(mNativePointer);
break;
case PAUSED:
@@ -538,10 +539,15 @@
* Play a video stream.
* @param url is the URL of the video stream.
*/
- public void play(String url) {
+ public void play(String url, int position) {
if (url == null) {
return;
}
+
+ if (position > 0) {
+ seek(position);
+ }
+
Message message = obtainMessage(PLAY);
message.obj = url;
sendMessage(message);
diff --git a/core/java/android/webkit/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java
index bb9ec48..54dfab3 100644
--- a/core/java/android/webkit/WebIconDatabase.java
+++ b/core/java/android/webkit/WebIconDatabase.java
@@ -24,6 +24,7 @@
import android.provider.Browser;
import android.util.Log;
+import java.io.File;
import java.util.HashMap;
import java.util.Vector;
@@ -194,13 +195,16 @@
/**
* Open a the icon database and store the icons in the given path.
* @param path The directory path where the icon database will be stored.
- * @return True if the database was successfully opened or created in
- * the given path.
*/
public void open(String path) {
if (path != null) {
+ // Make the directories and parents if they don't exist
+ File db = new File(path);
+ if (!db.exists()) {
+ db.mkdirs();
+ }
mEventHandler.postMessage(
- Message.obtain(null, EventHandler.OPEN, path));
+ Message.obtain(null, EventHandler.OPEN, db.getAbsolutePath()));
}
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 2f96782b4..518ba69 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1569,6 +1569,7 @@
public void setCacheMode(int mode) {
if (mode != mOverrideCacheMode) {
mOverrideCacheMode = mode;
+ postSync();
}
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 1313fcc..72b0023 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -132,6 +132,10 @@
private boolean mAutoFillable; // Is this textview part of an autofillable form?
private int mQueryId;
private boolean mAutoFillProfileIsSet;
+ // Used to determine whether onFocusChanged was called as a result of
+ // calling remove().
+ private boolean mInsideRemove;
+ private boolean mInPassword;
// Types used with setType. Keep in sync with CachedInput.h
private static final int NORMAL_TEXT_FIELD = 0;
@@ -540,6 +544,11 @@
Rect previouslyFocusedRect) {
mFromFocusChange = true;
super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ if (focused) {
+ mWebView.setActive(true);
+ } else if (!mInsideRemove) {
+ mWebView.setActive(false);
+ }
mFromFocusChange = false;
}
@@ -770,26 +779,17 @@
if (imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
+ mInsideRemove = true;
mWebView.removeView(this);
mWebView.requestFocus();
- }
-
- /**
- * Move the caret/selection into view.
- */
- /* package */ void bringIntoView() {
- bringPointIntoView(Selection.getSelectionEnd(getText()));
+ mInsideRemove = false;
}
@Override
public boolean bringPointIntoView(int offset) {
- if (mWebView == null) return false;
- if (mWebView.nativeFocusCandidateIsPassword()) {
+ if (mInPassword) {
return getLayout() != null && super.bringPointIntoView(offset);
}
- // For non password text input, tell webkit to move the caret/selection
- // on screen, since webkit draws them.
- mWebView.revealSelection();
return true;
}
@@ -904,6 +904,7 @@
* @param inPassword True if the textfield is a password field.
*/
/* package */ void setInPassword(boolean inPassword) {
+ mInPassword = inPassword;
if (inPassword) {
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.
TYPE_TEXT_VARIATION_WEB_PASSWORD);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 78d4cd2..9e09c28 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4268,7 +4268,7 @@
Rect vBox = contentToViewRect(bounds);
mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
if (!Rect.intersects(bounds, visibleRect)) {
- mWebTextView.bringIntoView();
+ revealSelection();
}
String text = nativeFocusCandidateText();
int nodePointer = nativeFocusCandidatePointer();
@@ -5050,7 +5050,7 @@
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
}
- private void setActive(boolean active) {
+ void setActive(boolean active) {
if (active) {
if (hasFocus()) {
// If our window regained focus, and we have focus, then begin
@@ -7274,7 +7274,6 @@
// this is sent after finishing resize in WebViewCore. Make
// sure the text edit box is still on the screen.
if (inEditingMode() && nativeCursorIsTextInput()) {
- mWebTextView.bringIntoView();
rebuildWebTextView();
}
break;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 88a54ea..9a050c5 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -148,13 +148,13 @@
*/
private float mInitialScale;
- private static float MINIMUM_SCALE_INCREMENT = 0.01f;
+ private static float MINIMUM_SCALE_INCREMENT = 0.007f;
/*
* The touch points could be changed even the fingers stop moving.
* We use the following to filter out the zooming jitters.
*/
- private static float MINIMUM_SCALE_WITHOUT_JITTER = 0.05f;
+ private static float MINIMUM_SCALE_WITHOUT_JITTER = 0.007f;
/*
* The following member variables are only to be used for animating zoom. If
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index d8f5972..a65de13 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2439,8 +2439,12 @@
if (adapter != null && mItemCount > 0 &&
motionPosition != INVALID_POSITION &&
motionPosition < adapter.getCount() && sameWindow()) {
- performItemClick(getChildAt(motionPosition - mFirstPosition), motionPosition,
- adapter.getItemId(motionPosition));
+ final View view = getChildAt(motionPosition - mFirstPosition);
+ // If there is no view, something bad happened (the view scrolled off the
+ // screen, etc.) and we should cancel the click
+ if (view != null) {
+ performItemClick(view, motionPosition, adapter.getItemId(motionPosition));
+ }
}
}
}
@@ -5315,6 +5319,24 @@
mRecycler.mRecyclerListener = listener;
}
+ class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ if (mFastScroller != null) {
+ mFastScroller.onSectionsChanged();
+ }
+ }
+
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ if (mFastScroller != null) {
+ mFastScroller.onSectionsChanged();
+ }
+ }
+ }
+
/**
* A MultiChoiceModeListener receives events for {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.
* It acts as the {@link ActionMode.Callback} for the selection mode and also receives
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index dfa94c7..200c870 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -476,6 +476,10 @@
}
}
+ public void onSectionsChanged() {
+ mListAdapter = null;
+ }
+
private void scrollTo(float position) {
int count = mList.getCount();
mScrollCompleted = false;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8f25311..c336ccb 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -59,6 +59,12 @@
private static final String LOG_TAG = "RemoteViews";
/**
+ * The intent extra that contains the appWidgetId.
+ * @hide
+ */
+ static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
+
+ /**
* The package name of the package containing the layout
* resource. (Added to the parcel)
*/
@@ -1276,6 +1282,22 @@
* providing data to the RemoteViewsAdapter
*/
public void setRemoteAdapter(int viewId, Intent intent) {
+ // Do nothing. This method will be removed after all widgets have been updated to the
+ // new API.
+ }
+
+ /**
+ * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
+ *
+ * @param appWidgetId The id of the app widget which contains the specified view
+ * @param viewId The id of the view whose text should change
+ * @param intent The intent of the service which will be
+ * providing data to the RemoteViewsAdapter
+ */
+ public void setRemoteAdapter(int appWidgetId, int viewId, Intent intent) {
+ // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
+ // RemoteViewsService
+ intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, appWidgetId);
setIntent(viewId, "setRemoteViewsAdapter", intent);
}
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index ab69725..f329a3e 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -22,20 +22,21 @@
import java.util.LinkedList;
import java.util.Map;
-import android.content.ComponentName;
+import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
+import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
/**
@@ -43,11 +44,22 @@
* to be later inflated as child views.
*/
/** @hide */
-public class RemoteViewsAdapter extends BaseAdapter {
+public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback {
private static final String TAG = "RemoteViewsAdapter";
- private Context mContext;
- private Intent mIntent;
+ // The max number of items in the cache
+ private static final int sDefaultCacheSize = 36;
+ // The delay (in millis) to wait until attempting to unbind from a service after a request.
+ // This ensures that we don't stay continually bound to the service and that it can be destroyed
+ // if we need the memory elsewhere in the system.
+ private static final int sUnbindServiceDelay = 5000;
+ // Type defs for controlling different messages across the main and worker message queues
+ private static final int sDefaultMessageType = 0;
+ private static final int sUnbindServiceMessageType = 1;
+
+ private final Context mContext;
+ private final Intent mIntent;
+ private final int mAppWidgetId;
private LayoutInflater mLayoutInflater;
private RemoteViewsAdapterServiceConnection mServiceConnection;
private WeakReference<RemoteAdapterConnectionCallback> mCallback;
@@ -79,7 +91,8 @@
* garbage collected, and would cause us to leak activities due to the caching mechanism for
* FrameLayouts in the adapter).
*/
- private static class RemoteViewsAdapterServiceConnection implements ServiceConnection {
+ private static class RemoteViewsAdapterServiceConnection extends
+ IRemoteViewsAdapterConnection.Stub {
private boolean mConnected;
private WeakReference<RemoteViewsAdapter> mAdapter;
private IRemoteViewsFactory mRemoteViewsFactory;
@@ -88,8 +101,7 @@
mAdapter = new WeakReference<RemoteViewsAdapter>(adapter);
}
- public void onServiceConnected(ComponentName name,
- IBinder service) {
+ public void onServiceConnected(IBinder service) {
mRemoteViewsFactory = IRemoteViewsFactory.Stub.asInterface(service);
mConnected = true;
@@ -137,7 +149,7 @@
});
}
- public void onServiceDisconnected(ComponentName name) {
+ public void onServiceDisconnected() {
mConnected = false;
mRemoteViewsFactory = null;
@@ -145,8 +157,9 @@
if (adapter == null) return;
// Clear the main/worker queues
- adapter.mMainQueue.removeMessages(0);
- adapter.mWorkerQueue.removeMessages(0);
+ adapter.mMainQueue.removeMessages(sUnbindServiceMessageType);
+ adapter.mMainQueue.removeMessages(sDefaultMessageType);
+ adapter.mWorkerQueue.removeMessages(sDefaultMessageType);
final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
if (callback != null) {
@@ -574,20 +587,26 @@
public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectionCallback callback) {
mContext = context;
mIntent = intent;
+ mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
mLayoutInflater = LayoutInflater.from(context);
if (mIntent == null) {
throw new IllegalArgumentException("Non-null Intent must be specified.");
}
mRequestedViews = new RemoteViewsFrameLayoutRefSet();
- // initialize the worker thread
+ // Strip the previously injected app widget id from service intent
+ if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
+ intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
+ }
+
+ // Initialize the worker thread
mWorkerThread = new HandlerThread("RemoteViewsCache-loader");
mWorkerThread.start();
mWorkerQueue = new Handler(mWorkerThread.getLooper());
- mMainQueue = new Handler(Looper.myLooper());
+ mMainQueue = new Handler(Looper.myLooper(), this);
- // initialize the cache and the service connection on startup
- mCache = new FixedSizeRemoteViewsCache(50);
+ // Initialize the cache and the service connection on startup
+ mCache = new FixedSizeRemoteViewsCache(sDefaultCacheSize);
mCallback = new WeakReference<RemoteAdapterConnectionCallback>(callback);
mServiceConnection = new RemoteViewsAdapterServiceConnection(this);
requestBindService();
@@ -687,6 +706,7 @@
@Override
public void run() {
mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
+ enqueueDeferredUnbindServiceMessage();
}
});
}
@@ -879,10 +899,36 @@
super.notifyDataSetChanged();
}
+ @Override
+ public boolean handleMessage(Message msg) {
+ boolean result = false;
+ switch (msg.what) {
+ case sUnbindServiceMessageType:
+ final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
+ if (mServiceConnection.isConnected()) {
+ mgr.unbindRemoteViewsService(mAppWidgetId, mIntent);
+ }
+ result = true;
+ break;
+ default:
+ break;
+ }
+ return result;
+ }
+
+ private void enqueueDeferredUnbindServiceMessage() {
+ /* Temporarily disable delayed service unbinding
+ // Remove any existing deferred-unbind messages
+ mMainQueue.removeMessages(sUnbindServiceMessageType);
+ mMainQueue.sendEmptyMessageDelayed(sUnbindServiceMessageType, sUnbindServiceDelay);
+ */
+ }
+
private boolean requestBindService() {
- // try binding the service (which will start it if it's not already running)
+ // Try binding the service (which will start it if it's not already running)
if (!mServiceConnection.isConnected()) {
- mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
+ mgr.bindRemoteViewsService(mAppWidgetId, mIntent, mServiceConnection.asBinder());
}
return mServiceConnection.isConnected();
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 0e31fef..a8eb6fe 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -388,6 +388,7 @@
mActionMode.finish();
}
+ mUpperContextView.killMode();
ActionMode mode = new ActionModeImpl(callback);
if (callback.onCreateActionMode(mode, mode.getMenu())) {
mode.invalidate();
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index a139d31..71a7a52 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -391,6 +391,7 @@
View buttonPanel = mWindow.findViewById(R.id.buttonPanel);
if (!hasButtons) {
buttonPanel.setVisibility(View.GONE);
+ mWindow.setCloseOnTouchOutsideIfNotSet(true);
}
FrameLayout customPanel = null;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9ed4dd8..38ac37d 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -17,7 +17,6 @@
package com.android.internal.app;
import android.content.Intent;
-import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 4d56745..fa0873d 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,10 @@
package com.android.internal.appwidget;
import android.content.ComponentName;
+import android.content.Intent;
import android.appwidget.AppWidgetProviderInfo;
import com.android.internal.appwidget.IAppWidgetHost;
+import android.os.IBinder;
import android.widget.RemoteViews;
/** {@hide} */
@@ -46,6 +48,8 @@
List<AppWidgetProviderInfo> getInstalledProviders();
AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId);
void bindAppWidgetId(int appWidgetId, in ComponentName provider);
+ void bindRemoteViewsService(int appWidgetId, in Intent intent, in IBinder connection);
+ void unbindRemoteViewsService(int appWidgetId, in Intent intent);
int[] getAppWidgetIds(in ComponentName provider);
}
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 31e7bab..bb0c752 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -160,10 +160,6 @@
}
public void initForMode(final ActionMode mode) {
- if (mAnimationMode != ANIMATE_IDLE || mAnimateInOnLayout) {
- killMode();
- }
-
if (mClose == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
mClose = inflater.inflate(R.layout.action_mode_close_item, this, false);
@@ -198,15 +194,15 @@
return;
}
- mAnimationMode = ANIMATE_OUT;
finishAnimation();
+ mAnimationMode = ANIMATE_OUT;
mCurrentAnimation = makeOutAnimation();
mCurrentAnimation.start();
}
private void finishAnimation() {
final Animator a = mCurrentAnimation;
- if (a != null && a.isRunning()) {
+ if (a != null) {
mCurrentAnimation = null;
a.end();
}
@@ -448,7 +444,7 @@
@Override
public void onAnimationEnd(Animator animation) {
- if (mAnimationMode != ANIMATE_IN) {
+ if (mAnimationMode == ANIMATE_OUT) {
killMode();
}
mAnimationMode = ANIMATE_IDLE;
diff --git a/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl b/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl
new file mode 100644
index 0000000..7eb2aef
--- /dev/null
+++ b/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.os.IBinder;
+
+/** {@hide} */
+interface IRemoteViewsAdapterConnection {
+ void onServiceConnected(IBinder service);
+ void onServiceDisconnected();
+}
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 8c30987..e4af33f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -61,6 +61,7 @@
struct so_t {
jfieldID surfaceControl;
+ jfieldID surfaceGenerationId;
jfieldID surface;
jfieldID saveCount;
jfieldID canvas;
@@ -189,6 +190,12 @@
p->decStrong(clazz);
}
env->SetIntField(clazz, so.surface, (int)surface.get());
+ // This test is conservative and it would be better to compare the ISurfaces
+ if (p && p != surface.get()) {
+ jint generationId = env->GetIntField(clazz, so.surfaceGenerationId);
+ generationId++;
+ env->SetIntField(clazz, so.surfaceGenerationId, generationId);
+ }
}
// ----------------------------------------------------------------------------
@@ -785,6 +792,7 @@
void nativeClassInit(JNIEnv* env, jclass clazz)
{
so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
+ so.surfaceGenerationId = env->GetFieldID(clazz, "mSurfaceGenerationId", "I");
so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I");
so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I");
so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 41c911a..9b890fa 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1210,6 +1210,13 @@
android:description="@string/permdesc_backup"
android:protectionLevel="signatureOrSystem" />
+ <!-- Must be required by a {@link android.widget.RemoteViewsService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_REMOTEVIEWS"
+ android:label="@string/permlab_bindRemoteViews"
+ android:description="@string/permdesc_bindRemoteViews"
+ android:protectionLevel="signatureOrSystem" />
+
<!-- Allows an application to tell the AppWidget service which application
can access AppWidget's data. The normal user flow is that a user
picks an AppWidget to go into a particular host, thereby giving that
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
deleted file mode 100644
index 3ecaa9d..0000000
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
deleted file mode 100644
index 40009af..0000000
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
deleted file mode 100644
index c369e6f..0000000
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
deleted file mode 100644
index a4df2bf..0000000
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
index 4691edf..f2b846a 100644
--- a/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
@@ -14,6 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_dark" />
<item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_dark" />
</selector>
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
index 5c52ff4..34afa71 100644
--- a/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
@@ -14,6 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_light" />
<item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_light" />
</selector>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
index 4f5beff..9779074 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
@@ -100,6 +100,16 @@
android:text="@android:string/lockscreen_glogin_submit_button"
/>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/ok"
+ android:layout_marginTop="50dip"
+ android:text="@android:string/lockscreen_glogin_account_recovery_hint"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_horizontal"
+ />
+
</RelativeLayout>
</ScrollView>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 080d66d..8a506a3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"تعيين الخادم الوكيل العمومي للجهاز لكي يتم استخدامه أثناء تمكين السياسة. يعين مشرف الجهاز الأول فقط الخادم الوكيل العمومي الفعال."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"تعيين انتهاء صلاحية كلمة المرور"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"التحكم في الوقت المستغرق قبل الحاجة إلى تغيير كلمة مرور شاشة التوقف"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"الرئيسية"</item>
<item msgid="869923650527136615">"الجوال"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"اختيار تعطيل تصحيح أخطاء USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"تحديد طريقة الإرسال"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d1176b8e..2736269 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Задаване на глобалния прокси сървър, който да се използва, когато правилото е активирано. Само първият администратор на устройството задава действителния глобален прокси сървър."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Срок на валидност на паролата"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролирайте след колко време трябва да се променя паролата при заключване на екрана"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Домашен"</item>
<item msgid="869923650527136615">"Мобилен"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняването на грешки през USB е свързано"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Избиране на метод на въвеждане"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e352fc0..ba93303 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Defineix el servidor intermediari global del dispositiu que cal utilitzar mentre la política estigui activada. Només el primer administrador del dispositiu pot definir el servidor intermediari global efectiu."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Defineix la caducitat de la contrasenya"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controla quant de temps abans de la pantalla de bloqueig cal canviar la contrasenya"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Mòbil"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració d\'USB connectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccioneu-ho per desactivar la depuració d\'USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selecció del mètode d\'entrada"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 441ad01..7495a66 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavit konec platnosti hesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domů"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Výběr metody zadávání dat"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0242ee9..0c9aefd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angiv enhedens globale proxy, der skal bruges, mens politikken er aktiveret. Kun den første enhedsadministrator angiver den effektive globale proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Indstil udløb for adgangskode"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
<string name="select_input_method" msgid="6865512749462072765">"Vælg indtastningsmetode"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 87f14c5..7856aaf 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den globalen Proxy des Geräts zur Verwendung während der Aktivierung der Richtlinie festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ablauf des Passworts festlegen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging verbunden"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Auswählen, um USB-Debugging zu deaktivieren."</string>
<string name="select_input_method" msgid="6865512749462072765">"Eingabemethode auswählen"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6b8db1e..7dc9747 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ορίστε τη χρήση του γενικού διακομιστή μεσολάβησης της συσκευής όταν είναι ενεργοποιημένη η πολιτική. Μόνο ο διαχειριστής της πρώτης συσκευής ορίζει τον ισχύοντα γενικό διακομιστή μεσολάβησης."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ορισμός λήξης κωδ. πρόσβασης"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Οικία"</item>
<item msgid="869923650527136615">"Κινητό"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Επιλογή μεθόδου εισόδου"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a981ed6..a63e2c4 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Set the device\'s global proxy to be used while policy is enabled. Only the first device admin sets the effective global proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Set password expiry"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Control how long before lock-screen password needs to be changed"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Home"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="select_input_method" msgid="6865512749462072765">"Select input method"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string>
diff --git a/core/res/res/values-es-rUS-xlarge/strings.xml b/core/res/res/values-es-rUS-xlarge/strings.xml
index b1409ba..81b3f1a 100644
--- a/core/res/res/values-es-rUS-xlarge/strings.xml
+++ b/core/res/res/values-es-rUS-xlarge/strings.xml
@@ -288,6 +288,8 @@
<!-- XL -->
<string name="capital_on" msgid="5705918046896729554">"ENCENDIDO"</string>
<!-- XL -->
+ <string name="capital_off" msgid="6734525950925281617">"APAGADO"</string>
+ <!-- XL -->
<string name="wait" msgid="8036803866051401072">"Espera"</string>
<!-- XL -->
<string name="heavy_weight_notification" msgid="5762367358298413602">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando"</string>
@@ -311,6 +313,10 @@
<!-- XL -->
<string name="permdesc_mediaStorageWrite" product="default" msgid="2372999661142345443">"Permite que una aplicación modifique los contenidos del almacenamiento interno de medios."</string>
<!-- XL -->
+ <string name="policylab_encryptedStorage" msgid="488196329176602372">"Establecer la encriptación del almacenamiento"</string>
+ <!-- XL -->
+ <string name="policydesc_encryptedStorage" msgid="6111889605506443825">"Requiere que los datos almacenados de la aplicación estén encriptados"</string>
+ <!-- XL -->
<string name="autofill_address_summary_name_format" msgid="7531610259426153850">"$1$2$3"</string>
<!-- XL -->
<string name="autofill_address_summary_format" msgid="8398158823767723887">"$1$2$3"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5e6645d..5d1a25f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -489,6 +489,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Establecer la caducidad de la contraseña"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -809,8 +813,8 @@
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
<string name="loading" msgid="1760724998928255250">"Cargando..."</string>
- <string name="capital_on" msgid="1544682755514494298">"Encendido"</string>
- <string name="capital_off" msgid="6815870386972805832">"APAGADO"</string>
+ <string name="capital_on" msgid="1544682755514494298">"Sí"</string>
+ <string name="capital_off" msgid="6815870386972805832">"No"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar la acción mediante"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de manera predeterminada en esta acción."</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar la predeterminación en Configuración de la página principal > Aplicaciones > Administrar aplicaciones."</string>
@@ -904,6 +908,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para desactivar la depuración de USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4f02c4b..a4d6545 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Definir caducidad contraseña"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Móvil"</item>
@@ -501,7 +505,7 @@
<item msgid="9192514806975898961">"Personalizar"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="8073994352956129127">"Personal"</item>
+ <item msgid="8073994352956129127">"Casa"</item>
<item msgid="7084237356602625604">"Trabajo"</item>
<item msgid="1112044410659011023">"Otra"</item>
<item msgid="2374913952870110618">"Personalizar"</item>
@@ -810,8 +814,8 @@
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
<string name="loading" msgid="1760724998928255250">"Cargando…"</string>
- <string name="capital_on" msgid="1544682755514494298">"Activado"</string>
- <string name="capital_off" msgid="6815870386972805832">"Desconectado"</string>
+ <string name="capital_on" msgid="1544682755514494298">"SÍ"</string>
+ <string name="capital_off" msgid="6815870386972805832">"NO"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar acción utilizando"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de forma predeterminada para esta acción"</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar valores predeterminados en la página de configuración de la pantalla de inicio del teléfono > Aplicaciones > Administrar aplicaciones\"."</string>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de introducción de texto"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 95871a4..767655d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"پروکسی جهانی دستگاه مورد نظر را جهت استفاده هنگام فعال بودن خط مشی تنظیم کنید. فقط اولین سرپرست دستگاه پروکسی جهانی مفید را تنظیم می کند."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"تنظیم زمان انقضای رمز ورود"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"کنترل مدت زمانی که رمز ورود صفحه قفل قبل از تغییر یافتن لازم دارد"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"خانه"</item>
<item msgid="869923650527136615">"تلفن همراه"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"رفع عیب USB متصل شد"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
<string name="select_input_method" msgid="6865512749462072765">"انتخاب روش ورودی"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1392ebb..d8d13ef 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Aseta laitteen yleinen välityspalvelin käyttöön, kun käytäntö on käytössä. Vain ensimmäinen laitteen järjestelmänhallitsija voi asettaa käytettävän yleisen välityspalvelimen."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Aseta salasanan umpeutuminen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Valitse, kuinka pian ruudunlukituksen poiston salasana tulee vaihtaa"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Puhelinnumero (koti)"</item>
<item msgid="869923650527136615">"Mobiili"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
<string name="select_input_method" msgid="6865512749462072765">"Valitse syöttötapa"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 361d193..c3fb6eb 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquez le proxy global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le proxy global utilisé."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Définir date exp. mot de passe"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domicile"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Sélectionner un mode de saisie"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index befb526..fe9f319 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Postavi globalni proxy uređaja za upotrebu dok su pravila omogućena. Samo prvi administrator uređaja postavlja djelotvoran globalni proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Postavi istek zaporke"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Nadzirite za koliko vremena zaporka za zaključani zaslon treba biti promijenjena"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Početna"</item>
<item msgid="869923650527136615">"Mobilni"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje programske pogreške USB-a"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
<string name="select_input_method" msgid="6865512749462072765">"Odaberite način unosa"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0ee1bbc..a090f0b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Az eszköz globális proxyja lesz használatban, amíg az irányelv engedélyezve van. Csak az eszköz első rendszergazdája állíthatja be a tényleges globális proxyt."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Jelszó lejáratának beállítása"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Azt vezérli, mennyi időnként kell módosítani a képernyőt zároló jelszót"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Otthoni"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
<string name="select_input_method" msgid="6865512749462072765">"Válassza ki a beviteli módszert"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 304ef90..8f738d6 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setel proxy global perangkat yang akandigunakan ketika kebijakan diaktifkan. Hanya admin perangkat pertama yang menyetel procy global yang berlaku."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Setel kedaluwarsa sandi"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrol berapa lama sebelum sandi penguncian layar perlu diubah"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Rumah"</item>
<item msgid="869923650527136615">"Seluler"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pilih metode masukan"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 282d375..887a96d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Imposta il proxy globale del dispositivo in modo da utilizzarlo mentre la norma è attiva. Il proxy globale effettivo è impostabile solo dal primo amministratore del dispositivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Imposta scadenza password"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Stabilisci la scadenza della password di blocco dello schermo"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Cellulare"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleziona metodo di inserimento"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index ea48002..eab8673 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"הגדר את שרת proxy הגלובלי של ההתקן לשימוש כאשר המדיניות מופעלת. רק מנהל ההתקן הראשון מגדיר את שרת ה-proxy הגלובלי הפעיל."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"הגדר תפוגת תוקף של סיסמה"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"שלוט בפרק הזמן הדרוש לשינוי הסיסמה של נעילת המסך"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"דף הבית"</item>
<item msgid="869923650527136615">"נייד"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"ניקוי באגים של USB מחובר"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"בחר כדי להשבית ניקוי באגים ב-USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"בחר שיטת קלט"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZאבגדהוזחטיכלמנסעפצקרשת"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789אבגדהוזחטיכלמנסעפצקרשת"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6df5f3d..c1b9f5d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ポリシーが有効になっている場合は端末のグローバルプロキシが使用されるように設定します。有効なグローバルプロキシを設定できるのは最初のデバイス管理者だけです。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"パスワードの有効期限の設定"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"自宅"</item>
<item msgid="869923650527136615">"携帯"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
<string name="select_input_method" msgid="6865512749462072765">"入力方法の選択"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -969,7 +975,7 @@
<string name="no_file_chosen" msgid="6363648562170759465">"ファイルが選択されていません"</string>
<string name="reset" msgid="2448168080964209908">"リセット"</string>
<string name="submit" msgid="1602335572089911941">"送信"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードを有効にする"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードになっています"</string>
<string name="car_mode_disable_notification_message" msgid="668663626721675614">"運転モードを終了するには選択してください。"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"タップして設定する"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 10eba59..eda018d 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"비밀번호 만료 설정"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"집"</item>
<item msgid="869923650527136615">"모바일"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
<string name="select_input_method" msgid="6865512749462072765">"입력 방법 선택"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bbb629d..f9f01e4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nustatyti įrenginio bendrąjį tarpinį serverį, kad būtų naudojamas, kol įgalinta politika. Tik pirmasis įrenginio administratorius nustato efektyvų bendrąjį tarpinį serverį."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nust. slaptaž. galiojimo pab."</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Valdyti, per kiek laiko iki ekrano užrakinimo turi būti pakeistas slaptažodis"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Pagrindinis"</item>
<item msgid="869923650527136615">"Mobilusis"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pasirinkti įvesties būdą"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7ef1e0a..6d25c54 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Iestatiet izmantojamo ierīces globālo starpniekserveri, kad ir iespējota politika. Spēkā esošo globālo starpniekserveri iestata tikai pirmās ierīces administrators."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Paroles termiņa izb. iest."</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolē ekrāna bloķēšanas paroles maiņas intervālu"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Mājas"</item>
<item msgid="869923650527136615">"Mobilais"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
<string name="select_input_method" msgid="6865512749462072765">"Atlasiet ievades metodi"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 83fd2d3c..aed9163 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angir den globale mellomtjeneren på enheten som skal brukes når regelen er aktivert. Kun den opprinnelige administratoren av enheten kan angi den globale mellomtjeneren."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Angi utløpsdato for passordet"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjemmenummer"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
<string name="select_input_method" msgid="6865512749462072765">"Velg inndatametode"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3c03980..062caee 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Stel de algemene proxy voor het apparaat in die moet worden gebruikt terwijl het beleid is geactiveerd. Alleen de eerste apparaatbeheerder stelt de algemene proxy in."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Verval wachtwoord instellen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Thuis"</item>
<item msgid="869923650527136615">"Mobiel"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
<string name="select_input_method" msgid="6865512749462072765">"Invoermethode selecteren"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e82dbca..868f168 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ustaw globalny serwer proxy urządzenia do wykorzystywania przy włączonych zasadach. Tylko pierwszy administrator urządzenia ustawia obowiązujący globalny serwer proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ustaw wygasanie hasła"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Dom"</item>
<item msgid="869923650527136615">"Komórka"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Wybierz metodę wprowadzania"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 41634f8..f306b8d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir o proxy global do aparelho a ser utilizado quando a política estiver activada. Só o primeiro administrador do aparelho define o proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Def. valid. da palavra-passe"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residência"</item>
<item msgid="869923650527136615">"Móvel"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 572cbce..7cd6cc4 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Definir validade da senha"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residencial"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9a879c7..a3d8191 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -498,6 +498,10 @@
<skip />
<!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
<skip />
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
<item msgid="869923650527136615">"Telefonin"</item>
@@ -947,6 +951,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB connectà"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Tscherner per deactivar il debugging USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Tscherner ina metoda d\'endataziun"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d0e1dc6..07a6213 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setaţi serverul proxy global pentru dispozitiv care să fie utilizat cât timp politica este activă. Numai primul administrator al dispozitivului poate seta serverul proxy global activ."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Setaţi expirarea parolei"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controlarea duratei până când parola de blocare a ecranului trebuie modificată"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domiciliu"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selectaţi pentru a dezactiva depanarea USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selectaţi metoda de intrare"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 22ee02a..dfc5d08 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Настройте глобальный прокси-сервер устройства, который будет использоваться при активной политике. Глобальный прокси-сервер должен настроить первый администратор устройства."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Задать время действия пароля"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Задать время действия пароля перед появлением экрана блокировки"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Домашний"</item>
<item msgid="869923650527136615">"Мобильный"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Выберите способ ввода"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 397688d..e7bbaf6 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globálny server proxy, ktorý sa bude používať po aktivácii pravidiel. Platný globálny server proxy nastavuje iba prvý správca zariadenia."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastav. koniec platnosti hesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládanie doby, po uplynutí ktorej treba zmeniť heslo na odomknutie obrazovky"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domovská stránka"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez rozhranie USB pripojené"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Výber metódy vstupu"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 91c42a8..c6b4302 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nastavite globalni strežnik proxy naprave, ki bo v uporabi, ko je pravilnik omogočen. Samo skrbnik prve naprave lahko nastavi veljaven globalni strežnik proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavitev poteka gesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Nastavite, koliko časa prej je treba spremeniti geslo za odklepanje zaslona"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Začetna stran"</item>
<item msgid="869923650527136615">"Mobilni"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"iskanje in odpravljanje napak USB je povezano"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Izbiranje načina vnosa"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -997,8 +1003,7 @@
<string name="media_unknown_state" msgid="729192782197290385">"Neznano stanje zunanjih nosilcev podatkov."</string>
<string name="share" msgid="1778686618230011964">"Deli z dr."</string>
<string name="find" msgid="4808270900322985960">"Najdi"</string>
- <!-- no translation found for websearch (4337157977400211589) -->
- <skip />
+ <string name="websearch" msgid="4337157977400211589">"Spletno iskanje"</string>
<!-- no translation found for gpsNotifTicker (5622683912616496172) -->
<skip />
<!-- no translation found for gpsNotifTitle (5446858717157416839) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c5c1e43..0493685 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Подесите глобални прокси сервер уређаја који ће се користити док су омогућене смернице. Само први администратор уређаја поставља ефективни глобални прокси сервер."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Подеси време истека лозинке"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролишите време када лозинка за закључавање екрана треба да се промени"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Кућа"</item>
<item msgid="869923650527136615">"Мобилни"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
<string name="select_input_method" msgid="6865512749462072765">"Избор методе уноса"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index bda3863..a60e7f9 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ange vilken global proxyserver som ska användas när policyn är aktiverad. Endast den första enhetsadministratören anger den faktiska globala proxyservern."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ange lösenordets utgångsdatum"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
<string name="select_input_method" msgid="6865512749462072765">"Välj indatametod"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 41593f2..f192c6d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ตั้งค่าพร็อกซีส่วนกลางของอุปกรณ์ที่จะใช้ขณะเปิดการใช้งานนโยบาย เฉพาะผู้ดูแลอุปกรณ์คนแรกเท่านั้นที่ตั้งค่าพร็อกซีส่วนกลางที่มีผลบังคับ"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"ตั้งค่าการหมดอายุของรหัสผ่าน"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"ควบคุมระยะเวลาก่อนที่จะต้องเปลี่ยนรหัสผ่านการล็อกหน้าจอ"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"บ้าน"</item>
<item msgid="869923650527136615">"มือถือ"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
<string name="select_input_method" msgid="6865512749462072765">"เลือกวิธีป้อนข้อมูล"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f65d77e..d42ef28 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Itakda ang pandaigdigang proxy ng device na gagamitin habang pinagana ang patakaran. Tanging ang unang admin ng device ang magtatakda sa may bisang pandaigdigang proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Itakda pag-expire ng password"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolin kung gaano katagal bago kailangang palitan ang password sa pag-lock ng screen"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Home"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Piliin upang huwag paganahin ang debugging ng USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pumili ng pamamaraan ng pag-input"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"mga kandidato"</u></string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 762ea47..8b338dd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Politika etkin olduğunda kullanılacak cihaz genelinde geçerli proxy\'yi ayarlayın. Etkin genel proxy\'yi yalnızca ilk cihaz yöneticisi ayarlar."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Şifre süre sonu tarihi ayarla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Ev"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
<string name="select_input_method" msgid="6865512749462072765">"Giriş yöntemini seç"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a2ad6dc..6e5fdaa 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Устан. використ. глоб. проксі, коли ввімкнено політику. Лише адміністратор першого пристрою встановлює активний глоб. проксі."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Установити термін дії пароля"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Регулює, за скільки часу перед блокуванням екрана треба змінювати пароль"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Дом."</item>
<item msgid="869923650527136615">"Мобільний"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB підключ."</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Вибер., щоб вимкн. налагодж. USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Виберіть метод введ-ня"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4e5220a..08c8990 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -487,6 +487,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Đặt proxy chung của điện thoại được sử dụng trong khi chính sách được bật. Chỉ quản trị viên đầu tiên của điện thoại mới có thể đặt proxy chung hiệu quả."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Đặt hết hạn mật khẩu"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kiểm soát thời lượng trước khi mật khẩu khóa màn hình cần được thay đổi"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Nhà riêng"</item>
<item msgid="869923650527136615">"ĐT di động"</item>
@@ -900,6 +904,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hoá gỡ lỗi USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Chọn phương thức nhập"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1cfc5cf..ecfdd63 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"请设置在启用政策的情况下要使用的设备全局代理。只有第一设备管理员才可设置有效的全局代理。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"设置密码有效期"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"控制屏幕锁定密码的使用期限"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住宅"</item>
<item msgid="869923650527136615">"手机"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"选择停用 USB 调试。"</string>
<string name="select_input_method" msgid="6865512749462072765">"选择输入法"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d0f460f..28cb8b2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -490,6 +490,10 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域 Proxy,只有第一個裝置管理員所設定的全域 Proxy 具有效力。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"設定密碼到期日"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"控制螢幕鎖定密碼的使用期限"</string>
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住家電話"</item>
<item msgid="869923650527136615">"行動電話"</item>
@@ -905,6 +909,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
<string name="select_input_method" msgid="6865512749462072765">"選取輸入方式"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6ca42e3..de233c8 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -362,6 +362,15 @@
pointer will go until that pointers go up thereby enabling touches
with multiple pointers to be split across multiple windows. -->
<attr name="windowEnableSplitTouch" format="boolean" />
+
+ <!-- Control whether a container should automatically close itself if
+ the user touches outside of it. This only applies to activities
+ and dialogs.
+
+ <p>Note: this attribute will only be respected for applications
+ that are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
+ or later. -->
+ <attr name="windowCloseOnTouchOutside" format="boolean" />
<!-- ============ -->
<!-- Alert Dialog styles -->
@@ -1342,6 +1351,7 @@
<attr name="windowActionModeOverlay" />
<attr name="windowActionBarOverlay" />
<attr name="windowEnableSplitTouch" />
+ <attr name="windowCloseOnTouchOutside" />
<!-- The minimum width the window is allowed to be, along the major
axis of the screen. That is, when in landscape. Can be either
an absolute dimension or a fraction of the screen size in that
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8bb05fb..e0c26d4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -81,6 +81,10 @@
specified for -large and -xlarge configurations. -->
<dimen name="config_prefDialogWidth">0px</dimen>
+ <!-- Whether dialogs should close automatically when the user touches outside
+ of them. This should not normally be modified. -->
+ <bool name="config_closeDialogWhenTouchOutside">false</bool>
+
<!-- The duration (in milliseconds) that the radio will scan for a signal
when there's no network connection. If the scan doesn't timeout, use zero -->
<integer name="config_radioScanningTimeout">0</integer>
@@ -433,7 +437,14 @@
from the touch driver. This code exists for one particular device,
and should not be enabled for any others. -->
<bool name="config_filterJumpyTouchEvents">false</bool>
-
+
+ <!-- Specifies the amount of time to disable virtual keys after the screen is touched
+ in order to filter out accidental virtual key presses due to swiping gestures
+ or taps near the edge of the display. May be 0 to disable the feature.
+ It is recommended that this value be no more than 250 ms.
+ This feature should be disabled for most devices. -->
+ <integer name="config_virtualKeyQuietTimeMillis">0</integer>
+
<!-- Component name of the default wallpaper. This will be ImageWallpaper if not
specified -->
<string name="default_wallpaper_component">@null</string>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index eabd457..1b47b54 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1425,6 +1425,7 @@
<public type="attr" name="queryHint" />
<public type="attr" name="fastScrollTextColor" />
<public type="attr" name="largeHeap" />
+ <public type="attr" name="windowCloseOnTouchOutside" />
<!-- A simple fade-in animation. -->
<public type="animator" name="fade_in" id="0x010b0000" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2658b53..9a1b42d 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -681,6 +681,12 @@
interface of a wallpaper. Should never be needed for normal applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindRemoteViews">bind to a widget service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindRemoteViews">Allows the holder to bind to the top-level
+ interface of a widget service. Should never be needed for normal applications.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindDeviceAdmin">interact with a device admin</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindDeviceAdmin">Allows the holder to send intents to
@@ -1784,6 +1790,8 @@
<string name="lockscreen_glogin_submit_button">Sign in</string>
<!-- Displayed to the user when unlocking the phone with a username and password fails. -->
<string name="lockscreen_glogin_invalid_input">Invalid username or password.</string>
+ <!-- Hint displayed on account unlock screen to advise the user on how to recover the account. -->
+ <string name="lockscreen_glogin_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b></string>
<!-- Displayed in a progress dialog while a username and password are being checked. -->
<string name="lockscreen_glogin_checking_password">Checking...</string>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 506dd07..b257a73 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -138,6 +138,7 @@
<item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">false</item>
+ <item name="windowCloseOnTouchOutside">false</item>
<!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog</item>
@@ -506,6 +507,7 @@
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+ <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
<item name="android:colorBackgroundCacheHint">@null</item>
@@ -547,6 +549,7 @@
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
+ <item name="android:windowCloseOnTouchOutside">false</item>
</style>
<!-- Default theme for alert dialog windows, which is used by the
@@ -687,6 +690,7 @@
<item name="windowIsFloating">true</item>
<item name="windowContentOverlay">@null</item>
<item name="textAppearance">@style/TextAppearance.Theme.Dialog.AppError</item>
+ <item name="android:windowCloseOnTouchOutside">false</item>
</style>
<!-- Special theme for the recent apps dialog, to allow customization
@@ -696,6 +700,7 @@
<item name="windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
<item name="android:textColor">@android:color/secondary_text_nofocus</item>
+ <item name="android:windowCloseOnTouchOutside">false</item>
</style>
<!-- Default theme for window that looks like a toast. -->
@@ -703,6 +708,7 @@
<item name="android:windowBackground">@android:drawable/toast_frame</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Toast</item>
<item name="android:backgroundDimEnabled">false</item>
+ <item name="android:windowCloseOnTouchOutside">false</item>
</style>
<!-- Default theme with an Action Bar. -->
@@ -1291,6 +1297,7 @@
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowActionModeOverlay">true</item>
+ <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
<item name="android:colorBackgroundCacheHint">@null</item>
@@ -1331,6 +1338,7 @@
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
+ <item name="android:windowCloseOnTouchOutside">false</item>
</style>
<!-- Holo theme for alert dialog windows, which is used by the
@@ -1377,6 +1385,7 @@
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowActionModeOverlay">true</item>
+ <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
<item name="android:colorBackgroundCacheHint">@null</item>
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 43cf06a3..96b028a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -19,6 +19,16 @@
import android.content.Context;
import android.test.InstrumentationTestCase;
+/**
+ * Stress test suite for Bluetooth related functions.
+ *
+ * Includes tests for enabling/disabling bluetooth, enabling/disabling discoverable mode,
+ * starting/stopping scans, connecting/disconnecting to HFP, A2DP, HID, PAN profiles, and verifying
+ * that remote connections/disconnections occur for the PAN profile.
+ * <p>
+ * This test suite uses {@link android.bluetooth.BluetoothTestRunner} to for parameters such as the
+ * number of iterations and the addresses of remote Bluetooth devices.
+ */
public class BluetoothStressTest extends InstrumentationTestCase {
private static final String TAG = "BluetoothStressTest";
private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt";
@@ -40,6 +50,9 @@
mTestUtils.close();
}
+ /**
+ * Stress test for enabling and disabling Bluetooth.
+ */
public void testEnable() {
int iterations = BluetoothTestRunner.sEnableIterations;
if (iterations == 0) {
@@ -55,6 +68,9 @@
}
}
+ /**
+ * Stress test for putting the device in and taking the device out of discoverable mode.
+ */
public void testDiscoverable() {
int iterations = BluetoothTestRunner.sDiscoverableIterations;
if (iterations == 0) {
@@ -73,6 +89,9 @@
mTestUtils.disable(adapter);
}
+ /**
+ * Stress test for starting and stopping Bluetooth scans.
+ */
public void testScan() {
int iterations = BluetoothTestRunner.sScanIterations;
if (iterations == 0) {
@@ -91,6 +110,30 @@
mTestUtils.disable(adapter);
}
+ /**
+ * Stress test for enabling and disabling the PAN NAP profile.
+ */
+ public void testEnablePan() {
+ int iterations = BluetoothTestRunner.sEnablePanIterations;
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ mTestUtils.enable(adapter);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("testEnablePan iteration " + (i + 1) + " of "
+ + iterations);
+ mTestUtils.enablePan(adapter);
+ mTestUtils.disablePan(adapter);
+ }
+
+ mTestUtils.disable(adapter);
+ }
+
+ /**
+ * Stress test for pairing and unpairing with a remote device.
+ * <p>
+ * In this test, the local device initiates pairing with a remote device, and then unpairs with
+ * the device after the pairing has successfully completed.
+ */
public void testPair() {
int iterations = BluetoothTestRunner.sPairIterations;
if (iterations == 0) {
@@ -110,6 +153,12 @@
mTestUtils.disable(adapter);
}
+ /**
+ * Stress test for accepting a pairing request and unpairing with a remote device.
+ * <p>
+ * In this test, the local device waits for a pairing request from a remote device. It accepts
+ * the request and then unpairs after the paring has successfully completed.
+ */
public void testAcceptPair() {
int iterations = BluetoothTestRunner.sPairIterations;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -125,6 +174,12 @@
mTestUtils.disable(adapter);
}
+ /**
+ * Stress test for connecting and disconnecting with an A2DP source.
+ * <p>
+ * In this test, the local device plays the role of an A2DP sink, and initiates connections and
+ * disconnections with an A2DP source.
+ */
public void testConnectA2dp() {
int iterations = BluetoothTestRunner.sConnectA2dpIterations;
if (iterations == 0) {
@@ -143,10 +198,16 @@
mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.A2DP);
}
- // TODO: Unpair from device if device can accept pairing after unpairing
+ mTestUtils.unpair(adapter, device);
mTestUtils.disable(adapter);
}
+ /**
+ * Stress test for connecting and disconnecting the HFP with a hands free device.
+ * <p>
+ * In this test, the local device plays the role of an HFP audio gateway, and initiates
+ * connections and disconnections with a hands free device.
+ */
public void testConnectHeadset() {
int iterations = BluetoothTestRunner.sConnectHeadsetIterations;
if (iterations == 0) {
@@ -165,7 +226,94 @@
mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET);
}
- // TODO: Unpair from device if device can accept pairing after unpairing
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disable(adapter);
+ }
+
+ /**
+ * Stress test for connecting and disconnecting with a HID device.
+ * <p>
+ * In this test, the local device plays the role of a HID host, and initiates connections and
+ * disconnections with a HID device.
+ */
+ public void testConnectInput() {
+ int iterations = BluetoothTestRunner.sConnectInputIterations;
+ if (iterations == 0) {
+ return;
+ }
+
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sInputAddress);
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey,
+ BluetoothTestRunner.sPairPin);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
+ mTestUtils.connectInput(adapter, device);
+ mTestUtils.disconnectInput(adapter, device);
+ }
+
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disable(adapter);
+ }
+
+ /**
+ * Stress test for connecting and disconnecting with a PAN NAP.
+ * <p>
+ * In this test, the local device plays the role of a PANU, and initiates connections and
+ * disconnections with a NAP.
+ */
+ public void testConnectPan() {
+ int iterations = BluetoothTestRunner.sConnectPanIterations;
+ if (iterations == 0) {
+ return;
+ }
+
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sPanAddress);
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey,
+ BluetoothTestRunner.sPairPin);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("connectPan iteration " + (i + 1) + " of " + iterations);
+ mTestUtils.connectPan(adapter, device);
+ mTestUtils.disconnectPan(adapter, device);
+ }
+
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disable(adapter);
+ }
+
+ /**
+ * Stress test for verifying a PANU connecting and disconnecting with the device.
+ * <p>
+ * In this test, the local device plays the role of a NAP which a remote PANU connects and
+ * disconnects from.
+ */
+ public void testIncomingPanConnection() {
+ int iterations = BluetoothTestRunner.sConnectPanIterations;
+ if (iterations == 0) {
+ return;
+ }
+
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sPanAddress);
+ mTestUtils.enable(adapter);
+ mTestUtils.enablePan(adapter);
+ mTestUtils.acceptPair(adapter, device, BluetoothTestRunner.sPairPasskey,
+ BluetoothTestRunner.sPairPin);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("incomingPanConnection iteration " + (i + 1) + " of "
+ + iterations);
+ mTestUtils.incomingPanConnection(adapter, device);
+ mTestUtils.incomingPanDisconnection(adapter, device);
+ }
+
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disablePan(adapter);
mTestUtils.disable(adapter);
}
}
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
index 3e589fc..cede05a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
@@ -23,19 +23,51 @@
import android.test.InstrumentationTestSuite;
import android.util.Log;
+/**
+ * Instrumentation test runner for Bluetooth tests.
+ * <p>
+ * To run:
+ * <pre>
+ * {@code
+ * adb shell am instrument \
+ * [-e enable_iterations <iterations>] \
+ * [-e discoverable_iterations <iterations>] \
+ * [-e scan_iterations <iterations>] \
+ * [-e enable_pan_iterations <iterations>] \
+ * [-e pair_iterations <iterations>] \
+ * [-e connect_a2dp_iterations <iterations>] \
+ * [-e connect_headset_iterations <iterations>] \
+ * [-e connect_input_iterations <iterations>] \
+ * [-e connect_pan_iterations <iterations>] \
+ * [-e pair_address <address>] \
+ * [-e headset_address <address>] \
+ * [-e a2dp_address <address>] \
+ * [-e input_address <address>] \
+ * [-e pan_address <address>] \
+ * [-e pair_pin <pin>] \
+ * [-e pair_passkey <passkey>] \
+ * -w com.android.frameworks.coretests/android.bluetooth.BluetoothTestRunner
+ * }
+ * </pre>
+ */
public class BluetoothTestRunner extends InstrumentationTestRunner {
private static final String TAG = "BluetoothTestRunner";
public static int sEnableIterations = 100;
public static int sDiscoverableIterations = 1000;
public static int sScanIterations = 1000;
+ public static int sEnablePanIterations = 1000;
public static int sPairIterations = 100;
public static int sConnectHeadsetIterations = 100;
public static int sConnectA2dpIterations = 100;
+ public static int sConnectInputIterations = 100;
+ public static int sConnectPanIterations = 100;
public static String sPairAddress = "";
public static String sHeadsetAddress = "";
public static String sA2dpAddress = "";
+ public static String sInputAddress = "";
+ public static String sPanAddress = "";
public static byte[] sPairPin = {'1', '2', '3', '4'};
public static int sPairPasskey = 123456;
@@ -81,6 +113,15 @@
}
}
+ val = arguments.getString("enable_pan_iterations");
+ if (val != null) {
+ try {
+ sEnablePanIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
+
val = arguments.getString("pair_iterations");
if (val != null) {
try {
@@ -108,6 +149,24 @@
}
}
+ val = arguments.getString("connect_input_iterations");
+ if (val != null) {
+ try {
+ sConnectInputIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
+
+ val = arguments.getString("connect_pan_iterations");
+ if (val != null) {
+ try {
+ sConnectPanIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
+
val = arguments.getString("pair_address");
if (val != null) {
sPairAddress = val;
@@ -123,6 +182,16 @@
sA2dpAddress = val;
}
+ val = arguments.getString("input_address");
+ if (val != null) {
+ sInputAddress = val;
+ }
+
+ val = arguments.getString("pan_address");
+ if (val != null) {
+ sPanAddress = val;
+ }
+
val = arguments.getString("pair_pin");
if (val != null) {
sPairPin = BluetoothDevice.convertPinToBytes(val);
@@ -143,9 +212,13 @@
Log.i(TAG, String.format("pair_iterations=%d", sPairIterations));
Log.i(TAG, String.format("connect_a2dp_iterations=%d", sConnectA2dpIterations));
Log.i(TAG, String.format("connect_headset_iterations=%d", sConnectHeadsetIterations));
+ Log.i(TAG, String.format("connect_input_iterations=%d", sConnectInputIterations));
+ Log.i(TAG, String.format("connect_pan_iterations=%d", sConnectPanIterations));
Log.i(TAG, String.format("pair_address=%s", sPairAddress));
Log.i(TAG, String.format("a2dp_address=%s", sA2dpAddress));
Log.i(TAG, String.format("headset_address=%s", sHeadsetAddress));
+ Log.i(TAG, String.format("input_address=%s", sInputAddress));
+ Log.i(TAG, String.format("pan_address=%s", sPanAddress));
Log.i(TAG, String.format("pair_pin=%s", new String(sPairPin)));
Log.i(TAG, String.format("pair_passkey=%d", sPairPasskey));
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index 6da38a7..effed76 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -35,49 +35,29 @@
public class BluetoothTestUtils extends Assert {
/**
- * Timeout for {@link BluetoothAdapter#disable()} in ms.
+ * Timeout for enable/disable in ms.
*/
- private static final int DISABLE_TIMEOUT = 20000;
+ private static final int ENABLE_DISABLE_TIMEOUT = 20000;
/**
- * Timeout for {@link BluetoothAdapter#enable()} in ms.
+ * Timeout for discoverable/undiscoverable in ms.
*/
- private static final int ENABLE_TIMEOUT = 20000;
+ private static final int DISCOVERABLE_UNDISCOVERABLE_TIMEOUT = 5000;
/**
- * Timeout for {@link BluetoothAdapter#setScanMode(int)} in ms.
+ * Timeout for starting/stopping a scan in ms.
*/
- private static final int SET_SCAN_MODE_TIMEOUT = 5000;
+ private static final int START_STOP_SCAN_TIMEOUT = 5000;
/**
- * Timeout for {@link BluetoothAdapter#startDiscovery()} in ms.
+ * Timeout for pair/unpair in ms.
*/
- private static final int START_DISCOVERY_TIMEOUT = 5000;
+ private static final int PAIR_UNPAIR_TIMEOUT = 20000;
/**
- * Timeout for {@link BluetoothAdapter#cancelDiscovery()} in ms.
+ * Timeout for connecting/disconnecting a profile in ms.
*/
- private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;
-
- /**
- * Timeout for {@link BluetoothDevice#createBond()} in ms.
- */
- private static final int PAIR_TIMEOUT = 20000;
-
- /**
- * Timeout for {@link BluetoothDevice#removeBond()} in ms.
- */
- private static final int UNPAIR_TIMEOUT = 20000;
-
- /**
- * Timeout for {@link BluetoothProfile#connect(BluetoothDevice)} in ms.
- */
- private static final int CONNECT_PROFILE_TIMEOUT = 20000;
-
- /**
- * Timeout for {@link BluetoothProfile#disconnect(BluetoothDevice)} in ms.
- */
- private static final int DISCONNECT_PROFILE_TIMEOUT = 20000;
+ private static final int CONNECT_DISCONNECT_PROFILE_TIMEOUT = 20000;
/**
* Timeout to connect a profile proxy in ms.
@@ -265,7 +245,6 @@
@Override
public void onReceive(Context context, Intent intent) {
-
if (mConnectionAction != null && mConnectionAction.equals(intent.getAction())) {
if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
return;
@@ -291,6 +270,91 @@
}
}
+ private class ConnectInputReceiver extends FlagReceiver {
+ private static final int STATE_DISCONNECTED_FLAG = 1;
+ private static final int STATE_CONNECTING_FLAG = 1 << 1;
+ private static final int STATE_CONNECTED_FLAG = 1 << 2;
+ private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
+
+ private BluetoothDevice mDevice;
+
+ public ConnectInputReceiver(BluetoothDevice device, int expectedFlags) {
+ super(expectedFlags);
+
+ mDevice = device;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
+ return;
+ }
+
+ if (BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED.equals(intent.getAction())) {
+ int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, -1);
+ assertNotSame(-1, state);
+ switch (state) {
+ case BluetoothInputDevice.STATE_DISCONNECTED:
+ setFiredFlag(STATE_DISCONNECTED_FLAG);
+ break;
+ case BluetoothInputDevice.STATE_CONNECTING:
+ setFiredFlag(STATE_CONNECTING_FLAG);
+ break;
+ case BluetoothInputDevice.STATE_CONNECTED:
+ setFiredFlag(STATE_CONNECTED_FLAG);
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ setFiredFlag(STATE_DISCONNECTING_FLAG);
+ break;
+ }
+ }
+ }
+ }
+
+ private class ConnectPanReceiver extends FlagReceiver {
+ private static final int STATE_DISCONNECTED_FLAG = 1;
+ private static final int STATE_CONNECTING_FLAG = 1 << 1;
+ private static final int STATE_CONNECTED_FLAG = 1 << 2;
+ private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
+
+ private BluetoothDevice mDevice;
+ private int mRole;
+
+ public ConnectPanReceiver(BluetoothDevice device, int role, int expectedFlags) {
+ super (expectedFlags);
+
+ mDevice = device;
+ mRole = role;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))
+ || mRole != intent.getIntExtra(BluetoothPan.EXTRA_LOCAL_ROLE, -1)) {
+ return;
+ }
+
+ if (BluetoothPan.ACTION_PAN_STATE_CHANGED.equals(intent.getAction())) {
+ int state = intent.getIntExtra(BluetoothPan.EXTRA_PAN_STATE, -1);
+ assertNotSame(-1, state);
+ switch (state) {
+ case BluetoothPan.STATE_DISCONNECTED:
+ setFiredFlag(STATE_DISCONNECTED_FLAG);
+ break;
+ case BluetoothPan.STATE_CONNECTING:
+ setFiredFlag(STATE_CONNECTING_FLAG);
+ break;
+ case BluetoothPan.STATE_CONNECTED:
+ setFiredFlag(STATE_CONNECTED_FLAG);
+ break;
+ case BluetoothPan.STATE_DISCONNECTING:
+ setFiredFlag(STATE_DISCONNECTING_FLAG);
+ break;
+ }
+ }
+ }
+ }
+
private BluetoothProfile.ServiceListener mServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
@@ -330,10 +394,24 @@
private BluetoothA2dp mA2dp;
private BluetoothHeadset mHeadset;
+ /**
+ * Creates a utility instance for testing Bluetooth.
+ *
+ * @param context The context of the application using the utility.
+ * @param tag The log tag of the application using the utility.
+ */
public BluetoothTestUtils(Context context, String tag) {
this(context, tag, null);
}
+ /**
+ * Creates a utility instance for testing Bluetooth.
+ *
+ * @param context The context of the application using the utility.
+ * @param tag The log tag of the application using the utility.
+ * @param outputFile The path to an output file if the utility is to write results to a
+ * separate file.
+ */
public BluetoothTestUtils(Context context, String tag, String outputFile) {
mContext = context;
mTag = tag;
@@ -352,6 +430,9 @@
}
}
+ /**
+ * Closes the utility instance and unregisters any BroadcastReceivers.
+ */
public void close() {
while (!mReceivers.isEmpty()) {
mContext.unregisterReceiver(mReceivers.remove(0));
@@ -366,6 +447,12 @@
}
}
+ /**
+ * Enables Bluetooth and checks to make sure that Bluetooth was turned on and that the correct
+ * actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void enable(BluetoothAdapter adapter) {
int mask = (BluetoothReceiver.STATE_TURNING_ON_FLAG | BluetoothReceiver.STATE_ON_FLAG
| BluetoothReceiver.SCAN_MODE_CONNECTABLE_FLAG);
@@ -397,22 +484,19 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < ENABLE_TIMEOUT) {
+ while (System.currentTimeMillis() - s < ENABLE_DISABLE_TIMEOUT) {
state = adapter.getState();
- if (state == BluetoothAdapter.STATE_ON) {
+ if (state == BluetoothAdapter.STATE_ON
+ && (receiver.getFiredFlags() & mask) == mask) {
assertTrue(adapter.isEnabled());
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("enable() completed in %d ms", (finish - start)));
- } else {
- writeOutput("enable() completed");
- }
- removeReceiver(receiver);
- return;
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("enable() completed in %d ms", (finish - start)));
+ } else {
+ writeOutput("enable() completed");
}
- } else {
- assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -423,6 +507,12 @@
state, BluetoothAdapter.STATE_ON, firedFlags, mask));
}
+ /**
+ * Disables Bluetooth and checks to make sure that Bluetooth was turned off and that the correct
+ * actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void disable(BluetoothAdapter adapter) {
int mask = (BluetoothReceiver.STATE_TURNING_OFF_FLAG | BluetoothReceiver.STATE_OFF_FLAG
| BluetoothReceiver.SCAN_MODE_NONE_FLAG);
@@ -454,23 +544,19 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < DISABLE_TIMEOUT) {
+ while (System.currentTimeMillis() - s < ENABLE_DISABLE_TIMEOUT) {
state = adapter.getState();
- if (state == BluetoothAdapter.STATE_OFF) {
+ if (state == BluetoothAdapter.STATE_OFF
+ && (receiver.getFiredFlags() & mask) == mask) {
assertFalse(adapter.isEnabled());
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("disable() completed in %d ms",
- (finish - start)));
- } else {
- writeOutput("disable() completed");
- }
- removeReceiver(receiver);
- return;
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("disable() completed in %d ms", (finish - start)));
+ } else {
+ writeOutput("disable() completed");
}
- } else {
- assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -481,6 +567,12 @@
state, BluetoothAdapter.STATE_OFF, firedFlags, mask));
}
+ /**
+ * Puts the local device into discoverable mode and checks to make sure that the local device
+ * is in discoverable mode and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void discoverable(BluetoothAdapter adapter) {
int mask = BluetoothReceiver.SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
@@ -499,17 +591,14 @@
long start = System.currentTimeMillis();
assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
- while (System.currentTimeMillis() - start < SET_SCAN_MODE_TIMEOUT) {
+ while (System.currentTimeMillis() - start < DISCOVERABLE_UNDISCOVERABLE_TIMEOUT) {
scanMode = adapter.getScanMode();
- if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
- if ((receiver.getFiredFlags() & mask) == mask) {
- writeOutput(String.format("discoverable() completed in %d ms",
- (receiver.getCompletedTime() - start)));
- removeReceiver(receiver);
- return;
- }
- } else {
- assertEquals(BluetoothAdapter.SCAN_MODE_CONNECTABLE, scanMode);
+ if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE
+ && (receiver.getFiredFlags() & mask) == mask) {
+ writeOutput(String.format("discoverable() completed in %d ms",
+ (receiver.getCompletedTime() - start)));
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -521,6 +610,12 @@
firedFlags, mask));
}
+ /**
+ * Puts the local device into connectable only mode and checks to make sure that the local
+ * device is in in connectable mode and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void undiscoverable(BluetoothAdapter adapter) {
int mask = BluetoothReceiver.SCAN_MODE_CONNECTABLE_FLAG;
@@ -539,17 +634,14 @@
long start = System.currentTimeMillis();
assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
- while (System.currentTimeMillis() - start < SET_SCAN_MODE_TIMEOUT) {
+ while (System.currentTimeMillis() - start < DISCOVERABLE_UNDISCOVERABLE_TIMEOUT) {
scanMode = adapter.getScanMode();
- if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
- if ((receiver.getFiredFlags() & mask) == mask) {
- writeOutput(String.format("undiscoverable() completed in %d ms",
- (receiver.getCompletedTime() - start)));
- removeReceiver(receiver);
- return;
- }
- } else {
- assertEquals(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, scanMode);
+ if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE
+ && (receiver.getFiredFlags() & mask) == mask) {
+ writeOutput(String.format("undiscoverable() completed in %d ms",
+ (receiver.getCompletedTime() - start)));
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -561,6 +653,12 @@
mask));
}
+ /**
+ * Starts a scan for remote devices and checks to make sure that the local device is scanning
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void startScan(BluetoothAdapter adapter) {
int mask = BluetoothReceiver.DISCOVERY_STARTED_FLAG;
@@ -577,7 +675,7 @@
long start = System.currentTimeMillis();
assertTrue(adapter.startDiscovery());
- while (System.currentTimeMillis() - start < START_DISCOVERY_TIMEOUT) {
+ while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
if (adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
writeOutput(String.format("startScan() completed in %d ms",
(receiver.getCompletedTime() - start)));
@@ -593,6 +691,12 @@
adapter.isDiscovering(), firedFlags, mask));
}
+ /**
+ * Stops a scan for remote devices and checks to make sure that the local device is not scanning
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ */
public void stopScan(BluetoothAdapter adapter) {
int mask = BluetoothReceiver.DISCOVERY_FINISHED_FLAG;
@@ -610,7 +714,7 @@
// TODO: put assertTrue() around cancelDiscovery() once it starts returning true.
adapter.cancelDiscovery();
- while (System.currentTimeMillis() - start < CANCEL_DISCOVERY_TIMEOUT) {
+ while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
if (!adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
writeOutput(String.format("stopScan() completed in %d ms",
(receiver.getCompletedTime() - start)));
@@ -627,20 +731,84 @@
}
+ /**
+ * Enables PAN tethering on the local device and checks to make sure that tethering is enabled.
+ *
+ * @param adapter The BT adapter.
+ */
+ public void enablePan(BluetoothAdapter adapter) {
+ BluetoothPan pan = new BluetoothPan(mContext);
+ assertNotNull(pan);
+
+ long start = System.currentTimeMillis();
+ pan.setBluetoothTethering(true);
+ long stop = System.currentTimeMillis();
+ assertTrue(pan.isTetheringOn());
+
+ writeOutput(String.format("enablePan() completed in %d ms", (stop - start)));
+ }
+
+ /**
+ * Disables PAN tethering on the local device and checks to make sure that tethering is
+ * disabled.
+ *
+ * @param adapter The BT adapter.
+ */
+ public void disablePan(BluetoothAdapter adapter) {
+ BluetoothPan pan = new BluetoothPan(mContext);
+ assertNotNull(pan);
+
+ long start = System.currentTimeMillis();
+ pan.setBluetoothTethering(false);
+ long stop = System.currentTimeMillis();
+ assertFalse(pan.isTetheringOn());
+
+ writeOutput(String.format("disablePan() completed in %d ms", (stop - start)));
+ }
+
+ /**
+ * Initiates a pairing with a remote device and checks to make sure that the devices are paired
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+ * @param pin The pairing pin if pairing requires a pin. Any value if not.
+ */
public void pair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, byte[] pin) {
pairOrAcceptPair(adapter, device, passkey, pin, true);
}
+ /**
+ * Accepts a pairing with a remote device and checks to make sure that the devices are paired
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+ * @param pin The pairing pin if pairing requires a pin. Any value if not.
+ */
public void acceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
byte[] pin) {
pairOrAcceptPair(adapter, device, passkey, pin, false);
}
+ /**
+ * Helper method used by {@link #pair(BluetoothAdapter, BluetoothDevice, int, byte[])} and
+ * {@link #acceptPair(BluetoothAdapter, BluetoothDevice, int, byte[])} to either pair or accept
+ * a pairing request.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+ * @param pin The pairing pin if pairing requires a pin. Any value if not.
+ * @param shouldPair Whether to pair or accept the pair.
+ */
private void pairOrAcceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
- byte[] pin, boolean pair) {
+ byte[] pin, boolean shouldPair) {
int mask = PairReceiver.STATE_BONDING_FLAG | PairReceiver.STATE_BONDED_FLAG;
long start = -1;
- String methodName = pair ? "pair()" : "acceptPair()";
+ String methodName = shouldPair ? "pair()" : "acceptPair()";
if (!adapter.isEnabled()) {
fail(methodName + " bluetooth not enabled");
@@ -653,7 +821,7 @@
case BluetoothDevice.BOND_NONE:
assertFalse(adapter.getBondedDevices().contains(device));
start = System.currentTimeMillis();
- if (pair) {
+ if (shouldPair) {
assertTrue(device.createBond());
}
break;
@@ -670,21 +838,19 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < PAIR_TIMEOUT) {
+ while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
state = device.getBondState();
- if (state == BluetoothDevice.BOND_BONDED) {
+ if (state == BluetoothDevice.BOND_BONDED && (receiver.getFiredFlags() & mask) == mask) {
assertTrue(adapter.getBondedDevices().contains(device));
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
- (finish - start), device));
- } else {
- writeOutput(String.format("%s completed: device=%s", methodName, device));
- }
- removeReceiver(receiver);
- return;
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("%s completed: device=%s", methodName, device));
}
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -696,6 +862,13 @@
BluetoothDevice.BOND_BONDED, firedFlags, mask));
}
+ /**
+ * Deletes a pairing with a remote device and checks to make sure that the devices are unpaired
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
public void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
int mask = PairReceiver.STATE_NONE_FLAG;
long start = -1;
@@ -727,20 +900,19 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < UNPAIR_TIMEOUT) {
- if (device.getBondState() == BluetoothDevice.BOND_NONE) {
+ while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
+ if (device.getBondState() == BluetoothDevice.BOND_NONE
+ && (receiver.getFiredFlags() & mask) == mask) {
assertFalse(adapter.getBondedDevices().contains(device));
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("unpair() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("unpair() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("unpair() completed in %d ms: device=%s",
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("unpair() completed: device=%s", device));
}
+ removeReceiver(receiver);
+ return;
}
}
@@ -751,6 +923,15 @@
firedFlags, mask));
}
+ /**
+ * Connects a profile from the local device to a remote device and checks to make sure that the
+ * profile is connected and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP} or
+ * {@link BluetoothProfile#HEADSET}.
+ */
public void connectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile) {
int mask = (ConnectProfileReceiver.STATE_CONNECTING_FLAG
| ConnectProfileReceiver.STATE_CONNECTED_FLAG);
@@ -794,21 +975,20 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_PROFILE_TIMEOUT) {
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
state = proxy.getConnectionState(device);
- if (state == BluetoothProfile.STATE_CONNECTED) {
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("connectProfile() completed in %d ms: "
- + "device=%s, profile=%d", (finish - start), device, profile));
- } else {
- writeOutput(String.format("connectProfile() completed: device=%s, "
- + "profile=%d", device, profile));
- }
- removeReceiver(receiver);
- return;
+ if (state == BluetoothProfile.STATE_CONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("connectProfile() completed in %d ms: "
+ + "device=%s, profile=%d", (finish - start), device, profile));
+ } else {
+ writeOutput(String.format("connectProfile() completed: device=%s, "
+ + "profile=%d", device, profile));
}
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -820,6 +1000,15 @@
BluetoothProfile.STATE_CONNECTED, firedFlags, mask));
}
+ /**
+ * Disconnects a profile between the local device and a remote device and checks to make sure
+ * that the profile is disconnected and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param profile The profile to disconnect. One of {@link BluetoothProfile#A2DP} or
+ * {@link BluetoothProfile#HEADSET}.
+ */
public void disconnectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile) {
int mask = (ConnectProfileReceiver.STATE_DISCONNECTING_FLAG
| ConnectProfileReceiver.STATE_DISCONNECTED_FLAG);
@@ -863,21 +1052,20 @@
}
long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < DISCONNECT_PROFILE_TIMEOUT) {
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
state = proxy.getConnectionState(device);
- if (state == BluetoothProfile.STATE_DISCONNECTED) {
- if ((receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("disconnectProfile() completed in %d ms: "
- + "device=%s, profile=%d", (finish - start), device, profile));
- } else {
- writeOutput(String.format("disconnectProfile() completed: device=%s, "
- + "profile=%d", device, profile));
- }
- removeReceiver(receiver);
- return;
+ if (state == BluetoothProfile.STATE_DISCONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("disconnectProfile() completed in %d ms: "
+ + "device=%s, profile=%d", (finish - start), device, profile));
+ } else {
+ writeOutput(String.format("disconnectProfile() completed: device=%s, "
+ + "profile=%d", device, profile));
}
+ removeReceiver(receiver);
+ return;
}
sleep(POLL_TIME);
}
@@ -889,6 +1077,360 @@
BluetoothProfile.STATE_DISCONNECTED, firedFlags, mask));
}
+ /**
+ * Connects the local device with a remote HID device and checks to make sure that the profile
+ * is connected and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void connectInput(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = (ConnectInputReceiver.STATE_CONNECTING_FLAG
+ | ConnectInputReceiver.STATE_CONNECTED_FLAG);
+ long start = -1;
+
+ if (!adapter.isEnabled()) {
+ fail(String.format("connectInput() bluetooth not enabled: device=%s", device));
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail(String.format("connectInput() device not paired: device=%s", device));
+ }
+
+ BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
+ assertNotNull(inputDevice);
+ ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
+
+ int state = inputDevice.getInputDeviceState(device);
+ switch (state) {
+ case BluetoothInputDevice.STATE_CONNECTED:
+ removeReceiver(receiver);
+ return;
+ case BluetoothInputDevice.STATE_CONNECTING:
+ mask = 0; // Don't check for received intents since we might have missed them.
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTED:
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ start = System.currentTimeMillis();
+ assertTrue(inputDevice.connectInputDevice(device));
+ break;
+ default:
+ removeReceiver(receiver);
+ fail(String.format("connectInput() invalid state: device=%s, state=%d", device,
+ state));
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+ state = inputDevice.getInputDeviceState(device);
+ if (state == BluetoothInputDevice.STATE_CONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("connectInput() completed in %d ms: device=%s",
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("connectInput() completed: device=%s", device));
+ }
+ removeReceiver(receiver);
+ return;
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = receiver.getFiredFlags();
+ removeReceiver(receiver);
+ fail(String.format("connectInput() timeout: device=%s, state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%s)", device, state, BluetoothInputDevice.STATE_CONNECTED,
+ firedFlags, mask));
+ }
+
+ /**
+ * Disconnects the local device with a remote HID device and checks to make sure that the
+ * profile is connected and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void disconnectInput(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = (ConnectInputReceiver.STATE_DISCONNECTING_FLAG
+ | ConnectInputReceiver.STATE_DISCONNECTED_FLAG);
+ long start = -1;
+
+ if (!adapter.isEnabled()) {
+ fail(String.format("disconnectInput() bluetooth not enabled: device=%s", device));
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail(String.format("disconnectInput() device not paired: device=%s", device));
+ }
+
+ BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
+ assertNotNull(inputDevice);
+ ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
+
+ int state = inputDevice.getInputDeviceState(device);
+ switch (state) {
+ case BluetoothInputDevice.STATE_CONNECTED:
+ case BluetoothInputDevice.STATE_CONNECTING:
+ start = System.currentTimeMillis();
+ assertTrue(inputDevice.disconnectInputDevice(device));
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTED:
+ removeReceiver(receiver);
+ return;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ mask = 0; // Don't check for received intents since we might have missed them.
+ break;
+ default:
+ removeReceiver(receiver);
+ fail(String.format("disconnectInput() invalid state: device=%s, state=%d", device,
+ state));
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+ state = inputDevice.getInputDeviceState(device);
+ if (state == BluetoothInputDevice.STATE_DISCONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("disconnectInput() completed in %d ms: device=%s",
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("disconnectInput() completed: device=%s", device));
+ }
+ removeReceiver(receiver);
+ return;
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = receiver.getFiredFlags();
+ removeReceiver(receiver);
+ fail(String.format("disconnectInput() timeout: device=%s, state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%s)", device, state,
+ BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
+ }
+
+ /**
+ * Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
+ * the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void connectPan(BluetoothAdapter adapter, BluetoothDevice device) {
+ connectPanOrIncomingPanConnection(adapter, device, true);
+ }
+
+ /**
+ * Checks that a remote PANU connects to the local NAP correctly and that the correct actions
+ * were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void incomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device) {
+ connectPanOrIncomingPanConnection(adapter, device, false);
+ }
+
+ /**
+ * Helper method used by {@link #connectPan(BluetoothAdapter, BluetoothDevice)} and
+ * {@link #incomingPanConnection(BluetoothAdapter, BluetoothDevice)} to either connect to a
+ * remote NAP or verify that a remote device connected to the local NAP.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param connect If the method should initiate the connection (is PANU)
+ */
+ private void connectPanOrIncomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device,
+ boolean connect) {
+ long start = -1;
+ int mask, role;
+ String methodName;
+
+ if (connect) {
+ methodName = "connectPan()";
+ mask = (ConnectPanReceiver.STATE_CONNECTED_FLAG |
+ ConnectPanReceiver.STATE_CONNECTING_FLAG);
+ role = BluetoothPan.LOCAL_PANU_ROLE;
+ } else {
+ methodName = "incomingPanConnection()";
+ mask = ConnectPanReceiver.STATE_CONNECTED_FLAG;
+ role = BluetoothPan.LOCAL_NAP_ROLE;
+ }
+
+ if (!adapter.isEnabled()) {
+ fail(String.format("%s bluetooth not enabled: device=%s", methodName, device));
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail(String.format("%s device not paired: device=%s", methodName, device));
+ }
+
+ BluetoothPan pan = new BluetoothPan(mContext);
+ assertNotNull(pan);
+ ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
+
+ int state = pan.getPanDeviceState(device);
+ switch (state) {
+ case BluetoothPan.STATE_CONNECTED:
+ removeReceiver(receiver);
+ return;
+ case BluetoothPan.STATE_CONNECTING:
+ mask = 0; // Don't check for received intents since we might have missed them.
+ break;
+ case BluetoothPan.STATE_DISCONNECTED:
+ case BluetoothPan.STATE_DISCONNECTING:
+ start = System.currentTimeMillis();
+ if (role == BluetoothPan.LOCAL_PANU_ROLE) {
+ Log.i("BT", "connect to pan");
+ assertTrue(pan.connect(device));
+ }
+ break;
+ default:
+ removeReceiver(receiver);
+ fail(String.format("%s invalid state: device=%s, state=%d", methodName, device,
+ state));
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+ state = pan.getPanDeviceState(device);
+ if (state == BluetoothPan.STATE_CONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("%s completed: device=%s", methodName, device));
+ }
+ removeReceiver(receiver);
+ return;
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = receiver.getFiredFlags();
+ removeReceiver(receiver);
+ fail(String.format("%s timeout: device=%s, state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%s)", methodName, device, state,
+ BluetoothPan.STATE_CONNECTED, firedFlags, mask));
+ }
+
+ /**
+ * Disconnects the PANU from a remote NAP and checks to make sure that the PANU is disconnected
+ * and that the correct actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void disconnectPan(BluetoothAdapter adapter, BluetoothDevice device) {
+ disconnectFromRemoteOrVerifyConnectNap(adapter, device, true);
+ }
+
+ /**
+ * Checks that a remote PANU disconnects from the local NAP correctly and that the correct
+ * actions were broadcast.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ */
+ public void incomingPanDisconnection(BluetoothAdapter adapter, BluetoothDevice device) {
+ disconnectFromRemoteOrVerifyConnectNap(adapter, device, false);
+ }
+
+ /**
+ * Helper method used by {@link #disconnectPan(BluetoothAdapter, BluetoothDevice)} and
+ * {@link #incomingPanDisconnection(BluetoothAdapter, BluetoothDevice)} to either disconnect
+ * from a remote NAP or verify that a remote device disconnected from the local NAP.
+ *
+ * @param adapter The BT adapter.
+ * @param device The remote device.
+ * @param disconnect Whether the method should connect or verify.
+ */
+ private void disconnectFromRemoteOrVerifyConnectNap(BluetoothAdapter adapter,
+ BluetoothDevice device, boolean disconnect) {
+ long start = -1;
+ int mask, role;
+ String methodName;
+
+ if (disconnect) {
+ methodName = "disconnectPan()";
+ mask = (ConnectPanReceiver.STATE_DISCONNECTED_FLAG |
+ ConnectPanReceiver.STATE_DISCONNECTING_FLAG);
+ role = BluetoothPan.LOCAL_PANU_ROLE;
+ } else {
+ methodName = "incomingPanDisconnection()";
+ mask = ConnectPanReceiver.STATE_DISCONNECTED_FLAG;
+ role = BluetoothPan.LOCAL_NAP_ROLE;
+ }
+
+ if (!adapter.isEnabled()) {
+ fail(String.format("%s bluetooth not enabled: device=%s", methodName, device));
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail(String.format("%s device not paired: device=%s", methodName, device));
+ }
+
+ BluetoothPan pan = new BluetoothPan(mContext);
+ assertNotNull(pan);
+ ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
+
+ int state = pan.getPanDeviceState(device);
+ switch (state) {
+ case BluetoothInputDevice.STATE_CONNECTED:
+ case BluetoothInputDevice.STATE_CONNECTING:
+ start = System.currentTimeMillis();
+ if (role == BluetoothPan.LOCAL_PANU_ROLE) {
+ assertTrue(pan.disconnect(device));
+ }
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTED:
+ removeReceiver(receiver);
+ return;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ mask = 0; // Don't check for received intents since we might have missed them.
+ break;
+ default:
+ removeReceiver(receiver);
+ fail(String.format("%s invalid state: device=%s, state=%d", methodName, device,
+ state));
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+ state = pan.getPanDeviceState(device);
+ if (state == BluetoothInputDevice.STATE_DISCONNECTED
+ && (receiver.getFiredFlags() & mask) == mask) {
+ long finish = receiver.getCompletedTime();
+ if (start != -1 && finish != -1) {
+ writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+ (finish - start), device));
+ } else {
+ writeOutput(String.format("%s completed: device=%s", methodName, device));
+ }
+ removeReceiver(receiver);
+ return;
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = receiver.getFiredFlags();
+ removeReceiver(receiver);
+ fail(String.format("%s timeout: device=%s, state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%s)", methodName, device, state,
+ BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
+ }
+
+ /**
+ * Writes a string to the logcat and a file if a file has been specified in the constructor.
+ *
+ * @param s The string to be written.
+ */
public void writeOutput(String s) {
Log.i(mTag, s);
if (mOutputWriter == null) {
@@ -902,38 +1444,60 @@
}
}
- private BluetoothReceiver getBluetoothReceiver(int expectedFlags) {
- BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags);
+ private void addReceiver(BroadcastReceiver receiver, String[] actions) {
IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
- filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
- filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ for (String action: actions) {
+ filter.addAction(action);
+ }
mContext.registerReceiver(receiver, filter);
mReceivers.add(receiver);
+ }
+
+ private BluetoothReceiver getBluetoothReceiver(int expectedFlags) {
+ String[] actions = {
+ BluetoothAdapter.ACTION_DISCOVERY_FINISHED,
+ BluetoothAdapter.ACTION_DISCOVERY_STARTED,
+ BluetoothAdapter.ACTION_SCAN_MODE_CHANGED,
+ BluetoothAdapter.ACTION_STATE_CHANGED};
+ BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags);
+ addReceiver(receiver, actions);
return receiver;
}
private PairReceiver getPairReceiver(BluetoothDevice device, int passkey, byte[] pin,
int expectedFlags) {
+ String[] actions = {
+ BluetoothDevice.ACTION_PAIRING_REQUEST,
+ BluetoothDevice.ACTION_BOND_STATE_CHANGED};
PairReceiver receiver = new PairReceiver(device, passkey, pin, expectedFlags);
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
- filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- mContext.registerReceiver(receiver, filter);
- mReceivers.add(receiver);
+ addReceiver(receiver, actions);
return receiver;
}
private ConnectProfileReceiver getConnectProfileReceiver(BluetoothDevice device, int profile,
int expectedFlags) {
+ String[] actions = {
+ BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
+ BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED};
ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
expectedFlags);
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
- mContext.registerReceiver(receiver, filter);
- mReceivers.add(receiver);
+ addReceiver(receiver, actions);
+ return receiver;
+ }
+
+ private ConnectInputReceiver getConnectInputReceiver(BluetoothDevice device,
+ int expectedFlags) {
+ String[] actions = {BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED};
+ ConnectInputReceiver receiver = new ConnectInputReceiver(device, expectedFlags);
+ addReceiver(receiver, actions);
+ return receiver;
+ }
+
+ private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
+ int expectedFlags) {
+ String[] actions = {BluetoothPan.ACTION_PAN_STATE_CHANGED};
+ ConnectPanReceiver receiver = new ConnectPanReceiver(device, role, expectedFlags);
+ addReceiver(receiver, actions);
return receiver;
}
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index 97b31cf..fe69d7d 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -8,14 +8,13 @@
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
- <li><a href="#object_creation">Avoid Creating Objects</a></li>
+ <li><a href="#object_creation">Avoid Creating Unnecessary Objects</a></li>
<li><a href="#myths">Performance Myths</a></li>
<li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
<li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
<li><a href="#use_final">Use Static Final For Constants</a></li>
<li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
- <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
- <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
+ <li><a href="#package_inner">Consider Package Instead of Private Access with Inner Classes</a></li>
<li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
<li><a href="#library">Know And Use The Libraries</a></li>
<li><a href="#native_methods">Use Native Methods Judiciously</a></li>
@@ -83,27 +82,31 @@
test on that device.</p>
<a name="object_creation"></a>
-<h2>Avoid Creating Objects</h2>
+<h2>Avoid Creating Unnecessary Objects</h2>
<p>Object creation is never free. A generational GC with per-thread allocation
pools for temporary objects can make allocation cheaper, but allocating memory
is always more expensive than not allocating memory.</p>
<p>If you allocate objects in a user interface loop, you will force a periodic
-garbage collection, creating little "hiccups" in the user experience.</p>
+garbage collection, creating little "hiccups" in the user experience. The
+concurrent collector introduced in Gingerbread helps, but unnecessary work
+should always be avoided.</p>
<p>Thus, you should avoid creating object instances you don't need to. Some
examples of things that can help:</p>
<ul>
- <li>When extracting strings from a set of input data, try
- to return a substring of the original data, instead of creating a copy.
- You will create a new String object, but it will share the char[]
- with the data.</li>
<li>If you have a method returning a string, and you know that its result
will always be appended to a StringBuffer anyway, change your signature
and implementation so that the function does the append directly,
instead of creating a short-lived temporary object.</li>
+ <li>When extracting strings from a set of input data, try
+ to return a substring of the original data, instead of creating a copy.
+ You will create a new String object, but it will share the char[]
+ with the data. (The trade-off being that if you're only using a small
+ part of the original input, you'll be keeping it all around in memory
+ anyway if you go this route.)</li>
</ul>
<p>A somewhat more radical idea is to slice up multidimensional arrays into
@@ -119,7 +122,7 @@
generally much better than a single array of custom (Foo,Bar) objects.
(The exception to this, of course, is when you're designing an API for
other code to access; in those cases, it's usually better to trade
- correct API design for a small hit in speed. But in your own internal
+ good API design for a small hit in speed. But in your own internal
code, you should try and be as efficient as possible.)</li>
</ul>
@@ -127,6 +130,7 @@
can. Fewer objects created mean less-frequent garbage collection, which has
a direct impact on user experience.</p>
+<a name="avoid_enums" id="avoid_enums"></a>
<a name="myths" id="myths"></a>
<h2>Performance Myths</h2>
@@ -265,43 +269,18 @@
<p>(See also <em>Effective Java</em> item 46.)</p>
-<a name="avoid_enums" id="avoid_enums"></a>
-<h2>Avoid Enums Where You Only Need Ints</h2>
-
-<p>Enums are very convenient, but unfortunately can be painful when size
-and speed matter. For example, this:</p>
-
-<pre>public enum Shrubbery { GROUND, CRAWLING, HANGING }</pre>
-
-<p>adds 740 bytes to your .dex file compared to the equivalent class
-with three public static final ints. On first use, the
-class initializer invokes the <init> method on objects representing each
-of the enumerated values. Each object gets its own static field, and the full
-set is stored in an array (a static field called "$VALUES"). That's a lot of
-code and data, just for three integers. Additionally, this:</p>
-
-<pre>Shrubbery shrub = Shrubbery.GROUND;</pre>
-
-<p>causes a static field lookup. If "GROUND" were a static final int,
-the compiler would treat it as a known constant and inline it.</p>
-
-<p>The flip side, of course, is that with enums you get nicer APIs and
-some compile-time value checking. So, the usual trade-off applies: you should
-by all means use enums for public APIs, but try to avoid them when performance
-matters.</p>
-
-<p>If you're using <code>Enum.ordinal</code>, that's usually a sign that you
-should be using ints instead. As a rule of thumb, if an enum doesn't have a
-constructor and doesn't define its own methods, and it's used in
-performance-critical code, you should consider <code>static final int</code>
-constants instead.</p>
-
<a name="package_inner" id="package_inner"></a>
-<h2>Use Package Scope with Inner Classes</h2>
+<h2>Consider Package Instead of Private Access with Private Inner Classes</h2>
<p>Consider the following class definition:</p>
<pre>public class Foo {
+ private class Inner {
+ void stuff() {
+ Foo.this.doStuff(Foo.this.mValue);
+ }
+ }
+
private int mValue;
public void run() {
@@ -313,24 +292,19 @@
private void doStuff(int value) {
System.out.println("Value is " + value);
}
-
- private class Inner {
- void stuff() {
- Foo.this.doStuff(Foo.this.mValue);
- }
- }
}</pre>
-<p>The key things to note here are that we define an inner class (Foo$Inner)
-that directly accesses a private method and a private instance field
-in the outer class. This is legal, and the code prints "Value is 27" as
-expected.</p>
+<p>The key things to note here are that we define a private inner class
+(<code>Foo$Inner</code>) that directly accesses a private method and a private
+instance field in the outer class. This is legal, and the code prints "Value is
+27" as expected.</p>
-<p>The problem is that the VM considers direct access to Foo's private members
-from Foo$Inner to be illegal because Foo and Foo$Inner are different classes,
-even though the Java language allows an inner class to access an outer class'
-private members. To bridge the gap, the compiler generates a couple of
-synthetic methods:</p>
+<p>The problem is that the VM considers direct access to <code>Foo</code>'s
+private members from <code>Foo$Inner</code> to be illegal because
+<code>Foo</code> and <code>Foo$Inner</code> are different classes, even though
+the Java language allows an inner class to access an outer class' private
+members. To bridge the gap, the compiler generates a couple of synthetic
+methods:</p>
<pre>/*package*/ static int Foo.access$100(Foo foo) {
return foo.mValue;
@@ -339,22 +313,19 @@
foo.doStuff(value);
}</pre>
-<p>The inner-class code calls these static methods whenever it needs to
-access the "mValue" field or invoke the "doStuff" method in the outer
-class. What this means is that the code above really boils down to a case
-where you're accessing member fields through accessor methods instead of
-directly. Earlier we talked about how accessors are slower than direct field
+<p>The inner class code calls these static methods whenever it needs to
+access the <code>mValue</code> field or invoke the <code>doStuff</code> method
+in the outer class. What this means is that the code above really boils down to
+a case where you're accessing member fields through accessor methods.
+Earlier we talked about how accessors are slower than direct field
accesses, so this is an example of a certain language idiom resulting in an
"invisible" performance hit.</p>
-<p>We can avoid this problem by declaring fields and methods accessed
-by inner classes to have package scope, rather than private scope.
-This runs faster and removes the overhead of the generated methods.
-(Unfortunately it also means the fields could be accessed directly by other
-classes in the same package, which runs counter to the standard
-practice of making all fields private. Once again, if you're
-designing a public API you might want to carefully consider using this
-optimization.)</p>
+<p>If you're using code like this in a performance hotspot, you can avoid the
+overhead by declaring fields and methods accessed by inner classes to have
+package access, rather than private access. Unfortunately this means the fields
+can be accessed directly by other classes in the same package, so you shouldn't
+use this in public API.</p>
<a name="avoidfloat" id="avoidfloat"></a>
<h2>Use Floating-Point Judiciously</h2>
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 28b32d5..bb9fb78 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -101,414 +101,515 @@
}
native void rsnContextDestroy(int con);
synchronized void nContextDestroy() {
+ validate();
rsnContextDestroy(mContext);
}
native void rsnContextSetSurface(int con, int w, int h, Surface sur);
synchronized void nContextSetSurface(int w, int h, Surface sur) {
+ validate();
rsnContextSetSurface(mContext, w, h, sur);
}
native void rsnContextSetPriority(int con, int p);
synchronized void nContextSetPriority(int p) {
+ validate();
rsnContextSetPriority(mContext, p);
}
native void rsnContextDump(int con, int bits);
synchronized void nContextDump(int bits) {
+ validate();
rsnContextDump(mContext, bits);
}
native void rsnContextFinish(int con);
synchronized void nContextFinish() {
+ validate();
rsnContextFinish(mContext);
}
native void rsnContextBindRootScript(int con, int script);
synchronized void nContextBindRootScript(int script) {
+ validate();
rsnContextBindRootScript(mContext, script);
}
native void rsnContextBindSampler(int con, int sampler, int slot);
synchronized void nContextBindSampler(int sampler, int slot) {
+ validate();
rsnContextBindSampler(mContext, sampler, slot);
}
native void rsnContextBindProgramStore(int con, int pfs);
synchronized void nContextBindProgramStore(int pfs) {
+ validate();
rsnContextBindProgramStore(mContext, pfs);
}
native void rsnContextBindProgramFragment(int con, int pf);
synchronized void nContextBindProgramFragment(int pf) {
+ validate();
rsnContextBindProgramFragment(mContext, pf);
}
native void rsnContextBindProgramVertex(int con, int pv);
synchronized void nContextBindProgramVertex(int pv) {
+ validate();
rsnContextBindProgramVertex(mContext, pv);
}
native void rsnContextBindProgramRaster(int con, int pr);
synchronized void nContextBindProgramRaster(int pr) {
+ validate();
rsnContextBindProgramRaster(mContext, pr);
}
native void rsnContextPause(int con);
synchronized void nContextPause() {
+ validate();
rsnContextPause(mContext);
}
native void rsnContextResume(int con);
synchronized void nContextResume() {
+ validate();
rsnContextResume(mContext);
}
native void rsnAssignName(int con, int obj, byte[] name);
synchronized void nAssignName(int obj, byte[] name) {
+ validate();
rsnAssignName(mContext, obj, name);
}
native String rsnGetName(int con, int obj);
synchronized String nGetName(int obj) {
+ validate();
return rsnGetName(mContext, obj);
}
native void rsnObjDestroy(int con, int id);
synchronized void nObjDestroy(int id) {
- rsnObjDestroy(mContext, id);
+ // There is a race condition here. The calling code may be run
+ // by the gc while teardown is occuring. This protects againts
+ // deleting dead objects.
+ if (mContext != 0) {
+ rsnObjDestroy(mContext, id);
+ }
}
native int rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
+ validate();
return rsnElementCreate(mContext, type, kind, norm, vecSize);
}
native int rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+ validate();
return rsnElementCreate2(mContext, elements, names, arraySizes);
}
native void rsnElementGetNativeData(int con, int id, int[] elementData);
synchronized void nElementGetNativeData(int id, int[] elementData) {
+ validate();
rsnElementGetNativeData(mContext, id, elementData);
}
native void rsnElementGetSubElements(int con, int id, int[] IDs, String[] names);
synchronized void nElementGetSubElements(int id, int[] IDs, String[] names) {
+ validate();
rsnElementGetSubElements(mContext, id, IDs, names);
}
native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces) {
+ validate();
return rsnTypeCreate(mContext, eid, x, y, z, mips, faces);
}
native void rsnTypeGetNativeData(int con, int id, int[] typeData);
synchronized void nTypeGetNativeData(int id, int[] typeData) {
+ validate();
rsnTypeGetNativeData(mContext, id, typeData);
}
native int rsnAllocationCreateTyped(int con, int type, int mip, int usage);
synchronized int nAllocationCreateTyped(int type, int mip, int usage) {
+ validate();
return rsnAllocationCreateTyped(mContext, type, mip, usage);
}
native int rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+ validate();
return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
}
native int rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+ validate();
return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
}
native int rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
+ validate();
return rsnAllocationCreateBitmapRef(mContext, type, bmp);
}
native int rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
+ validate();
return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
}
native void rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
+ validate();
rsnAllocationCopyToBitmap(mContext, alloc, bmp);
}
native void rsnAllocationSyncAll(int con, int alloc, int src);
synchronized void nAllocationSyncAll(int alloc, int src) {
+ validate();
rsnAllocationSyncAll(mContext, alloc, src);
}
native void rsnAllocationGenerateMipmaps(int con, int alloc);
synchronized void nAllocationGenerateMipmaps(int alloc) {
+ validate();
rsnAllocationGenerateMipmaps(mContext, alloc);
}
native void rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
+ validate();
rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
}
native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
+ validate();
rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
}
native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
+ validate();
rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
}
native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
+ validate();
rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
}
native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
+ validate();
rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
}
native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+ validate();
rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
}
native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
+ validate();
rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
}
native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
+ validate();
rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
}
native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
+ validate();
rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
}
native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
+ validate();
rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
}
native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
+ validate();
rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
}
native void rsnAllocationRead(int con, int id, byte[] d);
synchronized void nAllocationRead(int id, byte[] d) {
+ validate();
rsnAllocationRead(mContext, id, d);
}
native void rsnAllocationRead(int con, int id, short[] d);
synchronized void nAllocationRead(int id, short[] d) {
+ validate();
rsnAllocationRead(mContext, id, d);
}
native void rsnAllocationRead(int con, int id, int[] d);
synchronized void nAllocationRead(int id, int[] d) {
+ validate();
rsnAllocationRead(mContext, id, d);
}
native void rsnAllocationRead(int con, int id, float[] d);
synchronized void nAllocationRead(int id, float[] d) {
+ validate();
rsnAllocationRead(mContext, id, d);
}
native int rsnAllocationGetType(int con, int id);
synchronized int nAllocationGetType(int id) {
+ validate();
return rsnAllocationGetType(mContext, id);
}
native void rsnAllocationResize1D(int con, int id, int dimX);
synchronized void nAllocationResize1D(int id, int dimX) {
+ validate();
rsnAllocationResize1D(mContext, id, dimX);
}
native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
+ validate();
rsnAllocationResize2D(mContext, id, dimX, dimY);
}
native int rsnFileA3DCreateFromAssetStream(int con, int assetStream);
synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
+ validate();
return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
}
native int rsnFileA3DCreateFromFile(int con, String path);
synchronized int nFileA3DCreateFromFile(String path) {
+ validate();
return rsnFileA3DCreateFromFile(mContext, path);
}
native int rsnFileA3DCreateFromAsset(int con, AssetManager mgr, String path);
synchronized int nFileA3DCreateFromAsset(AssetManager mgr, String path) {
+ validate();
return rsnFileA3DCreateFromAsset(mContext, mgr, path);
}
native int rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
+ validate();
return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
}
native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
+ validate();
rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
}
native int rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
+ validate();
return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
}
native int rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
+ validate();
return rsnFontCreateFromFile(mContext, fileName, size, dpi);
}
native int rsnFontCreateFromAssetStream(int con, String name, float size, int dpi, int assetStream);
synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
+ validate();
return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
}
native int rsnFontCreateFromAsset(int con, AssetManager mgr, String path, float size, int dpi);
synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
+ validate();
return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
}
native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
+ validate();
rsnScriptBindAllocation(mContext, script, alloc, slot);
}
native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
+ validate();
rsnScriptSetTimeZone(mContext, script, timeZone);
}
native void rsnScriptInvoke(int con, int id, int slot);
synchronized void nScriptInvoke(int id, int slot) {
+ validate();
rsnScriptInvoke(mContext, id, slot);
}
native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
+ validate();
rsnScriptInvokeV(mContext, id, slot, params);
}
native void rsnScriptSetVarI(int con, int id, int slot, int val);
synchronized void nScriptSetVarI(int id, int slot, int val) {
+ validate();
rsnScriptSetVarI(mContext, id, slot, val);
}
native void rsnScriptSetVarJ(int con, int id, int slot, long val);
synchronized void nScriptSetVarJ(int id, int slot, long val) {
+ validate();
rsnScriptSetVarJ(mContext, id, slot, val);
}
native void rsnScriptSetVarF(int con, int id, int slot, float val);
synchronized void nScriptSetVarF(int id, int slot, float val) {
+ validate();
rsnScriptSetVarF(mContext, id, slot, val);
}
native void rsnScriptSetVarD(int con, int id, int slot, double val);
synchronized void nScriptSetVarD(int id, int slot, double val) {
+ validate();
rsnScriptSetVarD(mContext, id, slot, val);
}
native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
+ validate();
rsnScriptSetVarV(mContext, id, slot, val);
}
native void rsnScriptSetVarObj(int con, int id, int slot, int val);
synchronized void nScriptSetVarObj(int id, int slot, int val) {
+ validate();
rsnScriptSetVarObj(mContext, id, slot, val);
}
native void rsnScriptCBegin(int con);
synchronized void nScriptCBegin() {
+ validate();
rsnScriptCBegin(mContext);
}
native void rsnScriptCSetScript(int con, byte[] script, int offset, int length);
synchronized void nScriptCSetScript(byte[] script, int offset, int length) {
+ validate();
rsnScriptCSetScript(mContext, script, offset, length);
}
native int rsnScriptCCreate(int con, String packageName, String resName, String cacheDir);
synchronized int nScriptCCreate(String packageName, String resName, String cacheDir) {
+ validate();
return rsnScriptCCreate(mContext, packageName, resName, cacheDir);
}
native void rsnSamplerBegin(int con);
synchronized void nSamplerBegin() {
+ validate();
rsnSamplerBegin(mContext);
}
native void rsnSamplerSet(int con, int param, int value);
synchronized void nSamplerSet(int param, int value) {
+ validate();
rsnSamplerSet(mContext, param, value);
}
native void rsnSamplerSet2(int con, int param, float value);
synchronized void nSamplerSet2(int param, float value) {
+ validate();
rsnSamplerSet2(mContext, param, value);
}
native int rsnSamplerCreate(int con);
synchronized int nSamplerCreate() {
+ validate();
return rsnSamplerCreate(mContext);
}
native void rsnProgramStoreBegin(int con, int in, int out);
synchronized void nProgramStoreBegin(int in, int out) {
+ validate();
rsnProgramStoreBegin(mContext, in, out);
}
native void rsnProgramStoreDepthFunc(int con, int func);
synchronized void nProgramStoreDepthFunc(int func) {
+ validate();
rsnProgramStoreDepthFunc(mContext, func);
}
native void rsnProgramStoreDepthMask(int con, boolean enable);
synchronized void nProgramStoreDepthMask(boolean enable) {
+ validate();
rsnProgramStoreDepthMask(mContext, enable);
}
native void rsnProgramStoreColorMask(int con, boolean r, boolean g, boolean b, boolean a);
synchronized void nProgramStoreColorMask(boolean r, boolean g, boolean b, boolean a) {
+ validate();
rsnProgramStoreColorMask(mContext, r, g, b, a);
}
native void rsnProgramStoreBlendFunc(int con, int src, int dst);
synchronized void nProgramStoreBlendFunc(int src, int dst) {
+ validate();
rsnProgramStoreBlendFunc(mContext, src, dst);
}
native void rsnProgramStoreDither(int con, boolean enable);
synchronized void nProgramStoreDither(boolean enable) {
+ validate();
rsnProgramStoreDither(mContext, enable);
}
native int rsnProgramStoreCreate(int con);
synchronized int nProgramStoreCreate() {
+ validate();
return rsnProgramStoreCreate(mContext);
}
native int rsnProgramRasterCreate(int con, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
synchronized int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth, boolean pointSprite) {
+ validate();
return rsnProgramRasterCreate(mContext, pointSmooth, lineSmooth, pointSprite);
}
native void rsnProgramRasterSetLineWidth(int con, int pr, float v);
synchronized void nProgramRasterSetLineWidth(int pr, float v) {
+ validate();
rsnProgramRasterSetLineWidth(mContext, pr, v);
}
native void rsnProgramRasterSetCullMode(int con, int pr, int mode);
synchronized void nProgramRasterSetCullMode(int pr, int mode) {
+ validate();
rsnProgramRasterSetCullMode(mContext, pr, mode);
}
native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
synchronized void nProgramBindConstants(int pv, int slot, int mID) {
+ validate();
rsnProgramBindConstants(mContext, pv, slot, mID);
}
native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
synchronized void nProgramBindTexture(int vpf, int slot, int a) {
+ validate();
rsnProgramBindTexture(mContext, vpf, slot, a);
}
native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
synchronized void nProgramBindSampler(int vpf, int slot, int s) {
+ validate();
rsnProgramBindSampler(mContext, vpf, slot, s);
}
native int rsnProgramFragmentCreate(int con, String shader, int[] params);
synchronized int nProgramFragmentCreate(String shader, int[] params) {
+ validate();
return rsnProgramFragmentCreate(mContext, shader, params);
}
native int rsnProgramVertexCreate(int con, String shader, int[] params);
synchronized int nProgramVertexCreate(String shader, int[] params) {
+ validate();
return rsnProgramVertexCreate(mContext, shader, params);
}
native int rsnMeshCreate(int con, int vtxCount, int indexCount);
synchronized int nMeshCreate(int vtxCount, int indexCount) {
+ validate();
return rsnMeshCreate(mContext, vtxCount, indexCount);
}
native void rsnMeshBindVertex(int con, int id, int alloc, int slot);
synchronized void nMeshBindVertex(int id, int alloc, int slot) {
+ validate();
rsnMeshBindVertex(mContext, id, alloc, slot);
}
native void rsnMeshBindIndex(int con, int id, int alloc, int prim, int slot);
synchronized void nMeshBindIndex(int id, int alloc, int prim, int slot) {
+ validate();
rsnMeshBindIndex(mContext, id, alloc, prim, slot);
}
native void rsnMeshInitVertexAttribs(int con, int id);
synchronized void nMeshInitVertexAttribs(int id) {
+ validate();
rsnMeshInitVertexAttribs(mContext, id);
}
native int rsnMeshGetVertexBufferCount(int con, int id);
synchronized int nMeshGetVertexBufferCount(int id) {
+ validate();
return rsnMeshGetVertexBufferCount(mContext, id);
}
native int rsnMeshGetIndexCount(int con, int id);
synchronized int nMeshGetIndexCount(int id) {
+ validate();
return rsnMeshGetIndexCount(mContext, id);
}
native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
+ validate();
rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
}
native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
+ validate();
rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 35db786..f86343a 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -991,7 +991,7 @@
jint *paramPtr = _env->GetIntArrayElements(params, NULL);
jint paramLen = _env->GetArrayLength(params);
- LOG_API("nProgramFragmentCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+ LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
_env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
@@ -1008,7 +1008,7 @@
jint *paramPtr = _env->GetIntArrayElements(params, NULL);
jint paramLen = _env->GetArrayLength(params);
- LOG_API("nProgramVertexCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+ LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", con, paramLen);
jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
_env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 5170a2c..18fd90e 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -30,8 +30,10 @@
// The following keys map to int32_t data unless indicated otherwise.
enum {
kKeyMIMEType = 'mime', // cstring
- kKeyWidth = 'widt', // int32_t
- kKeyHeight = 'heig', // int32_t
+ kKeyWidth = 'widt', // int32_t, image pixel
+ kKeyHeight = 'heig', // int32_t, image pixel
+ kKeyDisplayWidth = 'dWid', // int32_t, display/presentation
+ kKeyDisplayHeight = 'dHgt', // int32_t, display/presentation
// a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
kKeyCropRect = 'crop',
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 535c0ac..999e4ea 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -154,8 +154,7 @@
float y1 = 0.0f;
float v1 = 0.0f;
- uint32_t i = 0;
- for ( ; i < mYCount; i++) {
+ for (uint32_t i = 0; i < mYCount; i++) {
float stepY = mYDivs[i];
float y2 = 0.0f;
@@ -167,8 +166,14 @@
}
float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
- generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
- bitmapWidth, quadCount, i & 1);
+ if (stepY > 0.0f) {
+ if (i == mYCount - 1 && mYDivs[i] == bitmapHeight) {
+ y2 = bottom - top;
+ v2 = 1.0f;
+ }
+ generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
+ bitmapWidth, quadCount);
+ }
y1 = y2;
v1 = (stepY + 0.5f) / bitmapHeight;
@@ -176,8 +181,10 @@
previousStepY = stepY;
}
- generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
- bitmapWidth, quadCount, i & 1);
+ if (previousStepY != bitmapHeight) {
+ generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
+ bitmapWidth, quadCount);
+ }
if (verticesCount > 0) {
Caches::getInstance().bindMeshBuffer(meshBuffer);
@@ -195,15 +202,14 @@
}
void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
- float stretchX, float width, float bitmapWidth, uint32_t& quadCount, bool isStretch) {
+ float stretchX, float width, float bitmapWidth, uint32_t& quadCount) {
float previousStepX = 0.0f;
float x1 = 0.0f;
float u1 = 0.0f;
// Generate the row quad by quad
- uint32_t i = 0;
- for ( ; i < mXCount; i++) {
+ for (uint32_t i = 0; i < mXCount; i++) {
float stepX = mXDivs[i];
float x2 = 0.0f;
@@ -215,7 +221,13 @@
}
float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
- generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount, isStretch || (i & 1));
+ if (stepX > 0.0f) {
+ if (i == mXCount - 1 && mXDivs[i] == bitmapWidth) {
+ x2 = bitmapWidth;
+ u2 = 1.0f;
+ }
+ generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
+ }
x1 = x2;
u1 = (stepX + 0.5f) / bitmapWidth;
@@ -223,19 +235,18 @@
previousStepX = stepX;
}
- generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, isStretch || (i & 1));
+ if (previousStepX != bitmapWidth) {
+ generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount);
+ }
}
void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
- float u1, float v1, float u2, float v2, uint32_t& quadCount, bool isStretch) {
+ float u1, float v1, float u2, float v2, uint32_t& quadCount) {
const uint32_t oldQuadCount = quadCount;
- const bool valid = isStretch || (x2 - x1 > 0.9999f && y2 - y1 > 0.9999f);
- if (valid) {
- quadCount++;
- }
+ quadCount++;
// Skip degenerate and transparent (empty) quads
- if (!valid || ((mColorKey >> oldQuadCount) & 0x1) == 1) {
+ if ((mColorKey >> oldQuadCount) & 0x1) {
#if DEBUG_PATCHES_EMPTY_VERTICES
PATCH_LOGD(" quad %d (empty)", oldQuadCount);
PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 4de0c76..0f0ffa2 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -70,11 +70,11 @@
void generateRow(TextureVertex*& vertex, float y1, float y2,
float v1, float v2, float stretchX, float width, float bitmapWidth,
- uint32_t& quadCount, bool isStretch);
+ uint32_t& quadCount);
void generateQuad(TextureVertex*& vertex,
float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2,
- uint32_t& quadCount, bool isStretch);
+ uint32_t& quadCount);
}; // struct Patch
}; // namespace uirenderer
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index fc3a065..541bf22 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -68,6 +68,7 @@
unitTests.add(new UT_rsdebug(this, mRes, mCtx));
unitTests.add(new UT_rstime(this, mRes, mCtx));
unitTests.add(new UT_rstypes(this, mRes, mCtx));
+ unitTests.add(new UT_math(this, mRes, mCtx));
unitTests.add(new UT_fp_mad(this, mRes, mCtx));
/*
unitTests.add(new UnitTest(null, "<Pass>", 1));
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_math.java b/libs/rs/java/tests/src/com/android/rs/test/UT_math.java
new file mode 100644
index 0000000..bf133be
--- /dev/null
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_math.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_math extends UnitTest {
+ private Resources mRes;
+
+ protected UT_math(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Math", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_math s = new ScriptC_math(pRS, mRes, R.raw.math);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_math_test(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
index 4133fda..b02f85d 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
@@ -102,7 +102,8 @@
start();
// Do ~100 M ops
- for (int ct=0; ct < 1000 * 100; ct++) {
+ int ct;
+ for (ct=0; ct < 1000 * 100; ct++) {
for (int i=0; i < (1000); i++) {
data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
}
@@ -129,7 +130,8 @@
float total = 0;
// Do ~100 M ops
- for (int ct=0; ct < 1000 * 100 /4; ct++) {
+ int ct;
+ for (ct=0; ct < 1000 * 100 /4; ct++) {
for (int i=0; i < (1000); i++) {
data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
}
@@ -140,7 +142,8 @@
}
void fp_mad_test(uint32_t index, int test_num) {
- for (int x=0; x < 1025; x++) {
+ int x;
+ for (x=0; x < 1025; x++) {
data_f1[x] = (x & 0xf) * 0.1f;
data_f4[x].x = (x & 0xf) * 0.1f;
data_f4[x].y = (x & 0xf0) * 0.1f;
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
new file mode 100644
index 0000000..5b1ad15
--- /dev/null
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -0,0 +1,65 @@
+#include "shared.rsh"
+
+// Testing math library
+
+volatile float f1;
+volatile float2 f2;
+volatile float3 f3;
+volatile float4 f4;
+
+#define TEST_F(fnc, var) \
+ rsDebug("Testing " #fnc, 0); \
+ var##1 = fnc(var##1); \
+ var##2 = fnc(var##2); \
+ var##3 = fnc(var##3); \
+ var##4 = fnc(var##4);
+
+#define TEST_FP(fnc, var) \
+ rsDebug("Testing " #fnc, 0); \
+ var##1 = fnc(var##1, (float*) &f1); \
+ var##2 = fnc(var##2, (float2*) &f2); \
+ var##3 = fnc(var##3, (float3*) &f3); \
+ var##4 = fnc(var##4, (float4*) &f4);
+
+#define TEST_F2(fnc, var) \
+ rsDebug("Testing " #fnc, 0); \
+ var##1 = fnc(var##1, var##1); \
+ var##2 = fnc(var##2, var##2); \
+ var##3 = fnc(var##3, var##3); \
+ var##4 = fnc(var##4, var##4);
+
+static bool test_math(uint32_t index) {
+ bool failed = false;
+ start();
+
+ TEST_F(cos, f);
+ TEST_FP(modf, f);
+ TEST_F2(pow, f);
+ TEST_F(sin, f);
+ TEST_F(sqrt, f);
+
+
+ float time = end(index);
+
+ if (failed) {
+ rsDebug("test_math FAILED", time);
+ }
+ else {
+ rsDebug("test_math PASSED", time);
+ }
+
+ return failed;
+}
+
+void math_test(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= test_math(index);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index 804c767..eb2af1c 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -210,3 +210,19 @@
void LocklessCommandFifo::dumpState(const char *s) const {
LOGV("%s %p put %p, get %p, buf %p, end %p", s, this, mPut, mGet, mBuffer, mEnd);
}
+
+void LocklessCommandFifo::printDebugData() const {
+ dumpState("printing fifo debug");
+ const uint32_t *pptr = (const uint32_t *)mGet;
+ pptr -= 8 * 4;
+ if (mGet < mBuffer) {
+ pptr = (const uint32_t *)mBuffer;
+ }
+
+
+ for (int ct=0; ct < 16; ct++) {
+ LOGV("fifo %p = 0x%08x 0x%08x 0x%08x 0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
+ pptr += 4;
+ }
+
+}
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
index c963963..eabdc3e 100644
--- a/libs/rs/rsLocklessFifo.h
+++ b/libs/rs/rsLocklessFifo.h
@@ -35,6 +35,8 @@
bool init(uint32_t size);
void shutdown();
+ void printDebugData() const;
+
LocklessCommandFifo();
~LocklessCommandFifo();
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 042f6c7..9f730bf 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -543,8 +543,11 @@
for (size_t i=0; i < pragmaCount; ++i) {
//LOGE("pragma %s %s", keys[i], values[i]);
if (!strcmp(keys[i], "version")) {
- // TODO: Verify that version is correct
- continue;
+ if (!strcmp(values[i], "1")) {
+ continue;
+ }
+ LOGE("Invalid version pragma value: %s\n", values[i]);
+ // Handle Fatal Error
}
if (!strcmp(keys[i], "stateVertex")) {
@@ -555,7 +558,8 @@
s->mEnviroment.mVertex.clear();
continue;
}
- LOGE("Unreconized value %s passed to stateVertex", values[i]);
+ LOGE("Unrecognized value %s passed to stateVertex", values[i]);
+ // Handle Fatal Error
}
if (!strcmp(keys[i], "stateRaster")) {
@@ -566,7 +570,8 @@
s->mEnviroment.mRaster.clear();
continue;
}
- LOGE("Unreconized value %s passed to stateRaster", values[i]);
+ LOGE("Unrecognized value %s passed to stateRaster", values[i]);
+ // Handle Fatal Error
}
if (!strcmp(keys[i], "stateFragment")) {
@@ -577,7 +582,8 @@
s->mEnviroment.mFragment.clear();
continue;
}
- LOGE("Unreconized value %s passed to stateFragment", values[i]);
+ LOGE("Unrecognized value %s passed to stateFragment", values[i]);
+ // Handle Fatal Error
}
if (!strcmp(keys[i], "stateStore")) {
@@ -588,7 +594,8 @@
s->mEnviroment.mFragmentStore.clear();
continue;
}
- LOGE("Unreconized value %s passed to stateStore", values[i]);
+ LOGE("Unrecognized value %s passed to stateStore", values[i]);
+ // Handle Fatal Error
}
}
}
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 0b21669..f550d98 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -226,51 +226,51 @@
}
static void SC_debugF(const char *s, float f) {
- LOGE("%s %f, 0x%08x", s, f, *((int *) (&f)));
+ LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
}
static void SC_debugFv2(const char *s, float f1, float f2) {
- LOGE("%s {%f, %f}", s, f1, f2);
+ LOGD("%s {%f, %f}", s, f1, f2);
}
static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
- LOGE("%s {%f, %f, %f}", s, f1, f2, f3);
+ LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
}
static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
- LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
+ LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
}
static void SC_debugD(const char *s, double d) {
- LOGE("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
+ LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
}
static void SC_debugFM4v4(const char *s, const float *f) {
- LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
- LOGE("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
- LOGE("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
- LOGE("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
+ LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
+ LOGD("%s %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
+ LOGD("%s %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
+ LOGD("%s %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
}
static void SC_debugFM3v3(const char *s, const float *f) {
- LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]);
- LOGE("%s %f, %f, %f", s, f[1], f[4], f[7]);
- LOGE("%s %f, %f, %f}",s, f[2], f[5], f[8]);
+ LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
+ LOGD("%s %f, %f, %f", s, f[1], f[4], f[7]);
+ LOGD("%s %f, %f, %f}",s, f[2], f[5], f[8]);
}
static void SC_debugFM2v2(const char *s, const float *f) {
- LOGE("%s {%f, %f", s, f[0], f[2]);
- LOGE("%s %f, %f}",s, f[1], f[3]);
+ LOGD("%s {%f, %f", s, f[0], f[2]);
+ LOGD("%s %f, %f}",s, f[1], f[3]);
}
static void SC_debugI32(const char *s, int32_t i) {
- LOGE("%s %i 0x%x", s, i, i);
+ LOGD("%s %i 0x%x", s, i, i);
}
static void SC_debugU32(const char *s, uint32_t i) {
- LOGE("%s %u 0x%x", s, i, i);
+ LOGD("%s %u 0x%x", s, i, i);
}
static void SC_debugLL64(const char *s, long long ll) {
- LOGE("%s %lld 0x%llx", s, ll, ll);
+ LOGD("%s %lld 0x%llx", s, ll, ll);
}
static void SC_debugULL64(const char *s, unsigned long long ll) {
- LOGE("%s %llu 0x%llx", s, ll, ll);
+ LOGD("%s %llu 0x%llx", s, ll, ll);
}
static void SC_debugP(const char *s, const void *p) {
- LOGE("%s %p", s, p);
+ LOGD("%s %p", s, p);
}
static uint32_t SC_toClient2(int cmdID, void *data, int len) {
diff --git a/libs/rs/rsScriptC_LibCL.cpp b/libs/rs/rsScriptC_LibCL.cpp
index 6c0e164..28c558d 100644
--- a/libs/rs/rsScriptC_LibCL.cpp
+++ b/libs/rs/rsScriptC_LibCL.cpp
@@ -221,7 +221,7 @@
{ "_Z5log1pf", (void *)&log1pf, true },
//{ "logb", (void *)&, true },
//{ "mad", (void *)&, true },
- { "modf", (void *)&modff, true },
+ { "_Z4modffPf", (void *)&modff, true },
//{ "nan", (void *)&, true },
{ "_Z9nextafterff", (void *)&nextafterf, true },
{ "_Z3powff", (void *)&powf, true },
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 001ac55..6cf07de7 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -56,6 +56,7 @@
if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
LOGE("playCoreCommands error con %p, cmd %i", con, cmdID);
+ mToCore.printDebugData();
}
gPlaybackFuncs[cmdID](con, data);
mToCore.next();
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index b9bb1f7..ab8270f40 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -1,20 +1,23 @@
#ifndef __RS_CL_RSH__
#define __RS_CL_RSH__
-#define M_PI 3.14159265358979323846264338327950288f /* pi */
-
+#ifdef BCC_PREPARE_BC
+#define _RS_STATIC extern
+#else
+#define _RS_STATIC static
+#endif
// Conversions
#define CVT_FUNC_2(typeout, typein) \
-static typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
+_RS_STATIC typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
return r; \
} \
-static typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
+_RS_STATIC typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
return r; \
} \
-static typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
+_RS_STATIC typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, (typeout)v.w}; \
return r; \
}
@@ -40,20 +43,20 @@
// Float ops, 6.11.2
#define DEF_FUNC_1(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v) { \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v) { \
float2 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
return r; \
} \
-static float3 __attribute__((overloadable)) fnc(float3 v) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v) { \
float3 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
r.z = fnc(v.z); \
return r; \
} \
-static float4 __attribute__((overloadable)) fnc(float4 v) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v) { \
float4 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
@@ -63,20 +66,20 @@
}
#define DEF_FUNC_1_RI(fnc) \
-static int2 __attribute__((overloadable)) fnc(float2 v) { \
+_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
int2 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
return r; \
} \
-static int3 __attribute__((overloadable)) fnc(float3 v) { \
+_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
int3 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
r.z = fnc(v.z); \
return r; \
} \
-static int4 __attribute__((overloadable)) fnc(float4 v) { \
+_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
int4 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
@@ -86,43 +89,43 @@
}
#define DEF_FUNC_2(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
float2 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
return r; \
} \
-static float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
float3 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
r.z = fnc(v1.z, v2.z); \
return r; \
} \
-static float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
float4 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
r.z = fnc(v1.z, v2.z); \
- r.w = fnc(v1.w, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
return r; \
}
#define DEF_FUNC_2F(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
float2 r; \
r.x = fnc(v1.x, v2); \
r.y = fnc(v1.y, v2); \
return r; \
} \
-static float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
float3 r; \
r.x = fnc(v1.x, v2); \
r.y = fnc(v1.y, v2); \
r.z = fnc(v1.z, v2); \
return r; \
} \
-static float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
float4 r; \
r.x = fnc(v1.x, v2); \
r.y = fnc(v1.y, v2); \
@@ -131,6 +134,40 @@
return r; \
}
+#define DEF_FUNC_2P(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 *v2) { \
+ float2 r; \
+ float q; \
+ r.x = fnc(v1.x, &q); \
+ v2->x = q; \
+ r.y = fnc(v1.y, &q); \
+ v2->y = q; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 *v2) { \
+ float3 r; \
+ float q; \
+ r.x = fnc(v1.x, &q); \
+ v2->x = q; \
+ r.y = fnc(v1.y, &q); \
+ v2->y = q; \
+ r.z = fnc(v1.z, &q); \
+ v2->z = q; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 *v2) { \
+ float4 r; \
+ float q; \
+ r.x = fnc(v1.x, &q); \
+ v2->x = q; \
+ r.y = fnc(v1.y, &q); \
+ v2->y = q; \
+ r.z = fnc(v1.z, &q); \
+ v2->z = q; \
+ r.w = fnc(v1.w, &q); \
+ v2->w = q; \
+ return r; \
+}
extern float __attribute__((overloadable)) acos(float);
DEF_FUNC_1(acos)
@@ -138,7 +175,7 @@
extern float __attribute__((overloadable)) acosh(float);
DEF_FUNC_1(acosh)
-static float __attribute__((overloadable)) acospi(float v) {
+_RS_STATIC float __attribute__((overloadable)) acospi(float v) {
return acos(v) / M_PI;
}
DEF_FUNC_1(acospi)
@@ -149,7 +186,7 @@
extern float __attribute__((overloadable)) asinh(float);
DEF_FUNC_1(asinh)
-static float __attribute__((overloadable)) asinpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) asinpi(float v) {
return asin(v) / M_PI;
}
DEF_FUNC_1(asinpi)
@@ -163,12 +200,12 @@
extern float __attribute__((overloadable)) atanh(float);
DEF_FUNC_1(atanh)
-static float __attribute__((overloadable)) atanpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) atanpi(float v) {
return atan(v) / M_PI;
}
DEF_FUNC_1(atanpi)
-static float __attribute__((overloadable)) atan2pi(float y, float x) {
+_RS_STATIC float __attribute__((overloadable)) atan2pi(float y, float x) {
return atan2(y, x) / M_PI;
}
DEF_FUNC_2(atan2pi)
@@ -188,7 +225,7 @@
extern float __attribute__((overloadable)) cosh(float);
DEF_FUNC_1(cosh)
-static float __attribute__((overloadable)) cospi(float v) {
+_RS_STATIC float __attribute__((overloadable)) cospi(float v) {
return cos(v * M_PI);
}
DEF_FUNC_1(cospi)
@@ -206,7 +243,7 @@
DEF_FUNC_1(exp2)
extern float __attribute__((overloadable)) pow(float, float);
-static float __attribute__((overloadable)) exp10(float v) {
+_RS_STATIC float __attribute__((overloadable)) exp10(float v) {
return pow(10.f, v);
}
DEF_FUNC_1(exp10)
@@ -239,12 +276,12 @@
extern float __attribute__((overloadable)) fmod(float, float);
DEF_FUNC_2(fmod)
-static float __attribute__((overloadable)) fract(float v, float *iptr) {
+_RS_STATIC float __attribute__((overloadable)) fract(float v, float *iptr) {
int i = (int)floor(v);
iptr[0] = i;
return fmin(v - i, 0x1.fffffep-1f);
}
-static float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
+_RS_STATIC float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
float t[2];
float2 r;
r.x = fract(v.x, &t[0]);
@@ -253,7 +290,7 @@
iptr[1] = t[1];
return r;
}
-static float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
+_RS_STATIC float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
float t[3];
float3 r;
r.x = fract(v.x, &t[0]);
@@ -264,7 +301,7 @@
iptr[2] = t[2];
return r;
}
-static float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
+_RS_STATIC float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
float t[4];
float4 r;
r.x = fract(v.x, &t[0]);
@@ -311,7 +348,7 @@
extern float __attribute__((overloadable)) log10(float);
DEF_FUNC_1(log10)
-static float __attribute__((overloadable)) log2(float v) {
+_RS_STATIC float __attribute__((overloadable)) log2(float v) {
return log10(v) / log10(2.f);
}
DEF_FUNC_1(log2)
@@ -328,9 +365,7 @@
extern float4 __attribute__((overloadable)) mad(float4, float4, float4);
extern float __attribute__((overloadable)) modf(float, float *);
-extern float2 __attribute__((overloadable)) modf(float2, float2 *);
-extern float3 __attribute__((overloadable)) modf(float3, float3 *);
-extern float4 __attribute__((overloadable)) modf(float4, float4 *);
+DEF_FUNC_2P(modf);
//extern float __attribute__((overloadable)) nan(uint);
@@ -339,29 +374,29 @@
DEF_FUNC_2(pow)
-static float __attribute__((overloadable)) pown(float v, int p) {
+_RS_STATIC float __attribute__((overloadable)) pown(float v, int p) {
return pow(v, (float)p);
}
-static float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
+_RS_STATIC float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
return pow(v, (float2)p);
}
-static float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
+_RS_STATIC float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
return pow(v, (float3)p);
}
-static float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
+_RS_STATIC float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
return pow(v, (float4)p);
}
-static float __attribute__((overloadable)) powr(float v, float p) {
+_RS_STATIC float __attribute__((overloadable)) powr(float v, float p) {
return pow(v, p);
}
-static float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
+_RS_STATIC float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
return pow(v, p);
}
-static float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
+_RS_STATIC float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
return pow(v, p);
}
-static float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
+_RS_STATIC float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
return pow(v, p);
}
@@ -376,18 +411,18 @@
extern float __attribute__((overloadable)) rint(float);
DEF_FUNC_1(rint)
-static float __attribute__((overloadable)) rootn(float v, int r) {
+_RS_STATIC float __attribute__((overloadable)) rootn(float v, int r) {
return pow(v, 1.f / r);
}
-static float2 __attribute__((overloadable)) rootn(float2 v, int2 r) {
+_RS_STATIC float2 __attribute__((overloadable)) rootn(float2 v, int2 r) {
float2 t = {1.f / r.x, 1.f / r.y};
return pow(v, t);
}
-static float3 __attribute__((overloadable)) rootn(float3 v, int3 r) {
+_RS_STATIC float3 __attribute__((overloadable)) rootn(float3 v, int3 r) {
float3 t = {1.f / r.x, 1.f / r.y, 1.f / r.z};
return pow(v, t);
}
-static float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
+_RS_STATIC float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
float4 t = {1.f / r.x, 1.f / r.y, 1.f / r.z, 1.f / r.w};
return pow(v, t);
}
@@ -396,7 +431,7 @@
DEF_FUNC_1(round)
extern float __attribute__((overloadable)) sqrt(float);
-static float __attribute__((overloadable)) rsqrt(float v) {
+_RS_STATIC float __attribute__((overloadable)) rsqrt(float v) {
return 1.f / sqrt(v);
}
DEF_FUNC_1(rsqrt)
@@ -404,19 +439,19 @@
extern float __attribute__((overloadable)) sin(float);
DEF_FUNC_1(sin)
-static float __attribute__((overloadable)) sincos(float v, float *cosptr) {
+_RS_STATIC float __attribute__((overloadable)) sincos(float v, float *cosptr) {
*cosptr = cos(v);
return sin(v);
}
-static float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
+_RS_STATIC float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
*cosptr = cos(v);
return sin(v);
}
-static float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
+_RS_STATIC float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
*cosptr = cos(v);
return sin(v);
}
-static float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
+_RS_STATIC float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
*cosptr = cos(v);
return sin(v);
}
@@ -424,7 +459,7 @@
extern float __attribute__((overloadable)) sinh(float);
DEF_FUNC_1(sinh)
-static float __attribute__((overloadable)) sinpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) sinpi(float v) {
return sin(v * M_PI);
}
DEF_FUNC_1(sinpi)
@@ -437,7 +472,7 @@
extern float __attribute__((overloadable)) tanh(float);
DEF_FUNC_1(tanh)
-static float __attribute__((overloadable)) tanpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) tanpi(float v) {
return tan(v * M_PI);
}
DEF_FUNC_1(tanpi)
@@ -452,20 +487,20 @@
#define DEF_RIFUNC_1(typeout, typein, fnc) \
extern typeout __attribute__((overloadable)) fnc(typein); \
-static typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
+_RS_STATIC typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
typeout##2 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
return r; \
} \
-static typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
+_RS_STATIC typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
typeout##3 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
r.z = fnc(v.z); \
return r; \
} \
-static typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
+_RS_STATIC typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
typeout##4 r; \
r.x = fnc(v.x); \
r.y = fnc(v.y); \
@@ -488,23 +523,23 @@
DEF_RIFUNC_1(int, int, fnc)
#define DEF_RIFUNC_2(type, fnc, body) \
-static type __attribute__((overloadable)) fnc(type v1, type v2) { \
+_RS_STATIC type __attribute__((overloadable)) fnc(type v1, type v2) { \
return body; \
} \
-static type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) { \
+_RS_STATIC type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) { \
type##2 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
return r; \
} \
-static type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) { \
+_RS_STATIC type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) { \
type##3 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
r.z = fnc(v1.z, v2.z); \
return r; \
} \
-static type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) { \
+_RS_STATIC type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) { \
type##4 r; \
r.x = fnc(v1.x, v2.x); \
r.y = fnc(v1.y, v2.y); \
@@ -533,23 +568,23 @@
// 6.11.4
-static float __attribute__((overloadable)) clamp(float amount, float low, float high) {
+_RS_STATIC float __attribute__((overloadable)) clamp(float amount, float low, float high) {
return amount < low ? low : (amount > high ? high : amount);
}
-static float2 __attribute__((overloadable)) clamp(float2 amount, float2 low, float2 high) {
+_RS_STATIC float2 __attribute__((overloadable)) clamp(float2 amount, float2 low, float2 high) {
float2 r;
r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
return r;
}
-static float3 __attribute__((overloadable)) clamp(float3 amount, float3 low, float3 high) {
+_RS_STATIC float3 __attribute__((overloadable)) clamp(float3 amount, float3 low, float3 high) {
float3 r;
r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
r.z = amount.z < low.z ? low.z : (amount.z > high.z ? high.z : amount.z);
return r;
}
-static float4 __attribute__((overloadable)) clamp(float4 amount, float4 low, float4 high) {
+_RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float4 low, float4 high) {
float4 r;
r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
@@ -557,20 +592,20 @@
r.w = amount.w < low.w ? low.w : (amount.w > high.w ? high.w : amount.w);
return r;
}
-static float2 __attribute__((overloadable)) clamp(float2 amount, float low, float high) {
+_RS_STATIC float2 __attribute__((overloadable)) clamp(float2 amount, float low, float high) {
float2 r;
r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
return r;
}
-static float3 __attribute__((overloadable)) clamp(float3 amount, float low, float high) {
+_RS_STATIC float3 __attribute__((overloadable)) clamp(float3 amount, float low, float high) {
float3 r;
r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
return r;
}
-static float4 __attribute__((overloadable)) clamp(float4 amount, float low, float high) {
+_RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float low, float high) {
float4 r;
r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
@@ -579,55 +614,55 @@
return r;
}
-static float __attribute__((overloadable)) degrees(float radians) {
+_RS_STATIC float __attribute__((overloadable)) degrees(float radians) {
return radians * (180.f / M_PI);
}
DEF_FUNC_1(degrees)
-static float __attribute__((overloadable)) mix(float start, float stop, float amount) {
+_RS_STATIC float __attribute__((overloadable)) mix(float start, float stop, float amount) {
return start + (stop - start) * amount;
}
-static float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
+_RS_STATIC float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
return start + (stop - start) * amount;
}
-static float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
+_RS_STATIC float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
return start + (stop - start) * amount;
}
-static float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
+_RS_STATIC float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
return start + (stop - start) * amount;
}
-static float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
+_RS_STATIC float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
return start + (stop - start) * amount;
}
-static float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
+_RS_STATIC float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
return start + (stop - start) * amount;
}
-static float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
+_RS_STATIC float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
return start + (stop - start) * amount;
}
-static float __attribute__((overloadable)) radians(float degrees) {
+_RS_STATIC float __attribute__((overloadable)) radians(float degrees) {
return degrees * (M_PI / 180.f);
}
DEF_FUNC_1(radians)
-static float __attribute__((overloadable)) step(float edge, float v) {
+_RS_STATIC float __attribute__((overloadable)) step(float edge, float v) {
return (v < edge) ? 0.f : 1.f;
}
-static float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
+_RS_STATIC float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
float2 r;
r.x = (v.x < edge.x) ? 0.f : 1.f;
r.y = (v.y < edge.y) ? 0.f : 1.f;
return r;
}
-static float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
+_RS_STATIC float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
float3 r;
r.x = (v.x < edge.x) ? 0.f : 1.f;
r.y = (v.y < edge.y) ? 0.f : 1.f;
r.z = (v.z < edge.z) ? 0.f : 1.f;
return r;
}
-static float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
+_RS_STATIC float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
float4 r;
r.x = (v.x < edge.x) ? 0.f : 1.f;
r.y = (v.y < edge.y) ? 0.f : 1.f;
@@ -635,20 +670,20 @@
r.w = (v.w < edge.w) ? 0.f : 1.f;
return r;
}
-static float2 __attribute__((overloadable)) step(float2 edge, float v) {
+_RS_STATIC float2 __attribute__((overloadable)) step(float2 edge, float v) {
float2 r;
r.x = (v < edge.x) ? 0.f : 1.f;
r.y = (v < edge.y) ? 0.f : 1.f;
return r;
}
-static float3 __attribute__((overloadable)) step(float3 edge, float v) {
+_RS_STATIC float3 __attribute__((overloadable)) step(float3 edge, float v) {
float3 r;
r.x = (v < edge.x) ? 0.f : 1.f;
r.y = (v < edge.y) ? 0.f : 1.f;
r.z = (v < edge.z) ? 0.f : 1.f;
return r;
}
-static float4 __attribute__((overloadable)) step(float4 edge, float v) {
+_RS_STATIC float4 __attribute__((overloadable)) step(float4 edge, float v) {
float4 r;
r.x = (v < edge.x) ? 0.f : 1.f;
r.y = (v < edge.y) ? 0.f : 1.f;
@@ -665,7 +700,7 @@
extern float3 __attribute__((overloadable)) smoothstep(float, float, float3);
extern float4 __attribute__((overloadable)) smoothstep(float, float, float4);
-static float __attribute__((overloadable)) sign(float v) {
+_RS_STATIC float __attribute__((overloadable)) sign(float v) {
if (v > 0) return 1.f;
if (v < 0) return -1.f;
return v;
@@ -673,7 +708,7 @@
DEF_FUNC_1(sign)
// 6.11.5
-static float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
+_RS_STATIC float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
float3 r;
r.x = lhs.y * rhs.z - lhs.z * rhs.y;
r.y = lhs.z * rhs.x - lhs.x * rhs.z;
@@ -681,7 +716,7 @@
return r;
}
-static float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
+_RS_STATIC float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
float4 r;
r.x = lhs.y * rhs.z - lhs.z * rhs.y;
r.y = lhs.z * rhs.x - lhs.x * rhs.z;
@@ -690,55 +725,55 @@
return r;
}
-static float __attribute__((overloadable)) dot(float lhs, float rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float lhs, float rhs) {
return lhs * rhs;
}
-static float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
return lhs.x*rhs.x + lhs.y*rhs.y;
}
-static float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
}
-static float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
}
-static float __attribute__((overloadable)) length(float v) {
+_RS_STATIC float __attribute__((overloadable)) length(float v) {
return v;
}
-static float __attribute__((overloadable)) length(float2 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float2 v) {
return sqrt(v.x*v.x + v.y*v.y);
}
-static float __attribute__((overloadable)) length(float3 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float3 v) {
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}
-static float __attribute__((overloadable)) length(float4 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float4 v) {
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
}
-static float __attribute__((overloadable)) distance(float lhs, float rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float lhs, float rhs) {
return length(lhs - rhs);
}
-static float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
return length(lhs - rhs);
}
-static float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
return length(lhs - rhs);
}
-static float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
return length(lhs - rhs);
}
-static float __attribute__((overloadable)) normalize(float v) {
+_RS_STATIC float __attribute__((overloadable)) normalize(float v) {
return 1.f;
}
-static float2 __attribute__((overloadable)) normalize(float2 v) {
+_RS_STATIC float2 __attribute__((overloadable)) normalize(float2 v) {
return v / length(v);
}
-static float3 __attribute__((overloadable)) normalize(float3 v) {
+_RS_STATIC float3 __attribute__((overloadable)) normalize(float3 v) {
return v / length(v);
}
-static float4 __attribute__((overloadable)) normalize(float4 v) {
+_RS_STATIC float4 __attribute__((overloadable)) normalize(float4 v) {
return v / length(v);
}
@@ -753,5 +788,6 @@
#undef DEF_IFUNC_1
#undef DEF_RIFUNC_2
#undef DEF_IFUNC_2
+#undef _RS_STATIC
#endif
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index 16482c1..f3e0ab0 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,6 +1,12 @@
#ifndef __RS_CORE_RSH__
#define __RS_CORE_RSH__
+#ifdef BCC_PREPARE_BC
+#define _RS_STATIC extern
+#else
+#define _RS_STATIC static
+#endif
+
// Debugging, print to the LOG a description string and a value.
extern void __attribute__((overloadable))
rsDebug(const char *, float);
@@ -35,17 +41,17 @@
#define RS_DEBUG(a) rsDebug(#a, a)
#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
-static void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
rsDebug(s, v.x, v.y);
}
-static void __attribute__((overloadable)) rsDebug(const char *s, float3 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float3 v) {
rsDebug(s, v.x, v.y, v.z);
}
-static void __attribute__((overloadable)) rsDebug(const char *s, float4 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float4 v) {
rsDebug(s, v.x, v.y, v.z, v.w);
}
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
{
uchar4 c;
c.x = (uchar)(r * 255.f);
@@ -55,7 +61,7 @@
return c;
}
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
{
uchar4 c;
c.x = (uchar)(r * 255.f);
@@ -65,21 +71,21 @@
return c;
}
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
{
color *= 255.f;
uchar4 c = {color.x, color.y, color.z, 255};
return c;
}
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
{
color *= 255.f;
uchar4 c = {color.x, color.y, color.z, color.w};
return c;
}
-static float4 rsUnpackColor8888(uchar4 c)
+_RS_STATIC float4 rsUnpackColor8888(uchar4 c)
{
float4 ret = (float4)0.0039156862745f;
ret *= convert_float4(c);
@@ -95,37 +101,37 @@
// Matrix ops
/////////////////////////////////////////////////////
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) {
m->m[row * 4 + col] = v;
}
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) {
return m->m[row * 4 + col];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) {
m->m[row * 3 + col] = v;
}
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) {
return m->m[row * 3 + col];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) {
m->m[row * 2 + col] = v;
}
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) {
return m->m[row * 2 + col];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix4x4 *m) {
m->m[0] = 1.f;
m->m[1] = 0.f;
@@ -145,7 +151,7 @@
m->m[15] = 1.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix3x3 *m) {
m->m[0] = 1.f;
m->m[1] = 0.f;
@@ -158,7 +164,7 @@
m->m[8] = 1.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadIdentity(rs_matrix2x2 *m) {
m->m[0] = 1.f;
m->m[1] = 0.f;
@@ -166,7 +172,7 @@
m->m[3] = 1.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 *m, const float *v) {
m->m[0] = v[0];
m->m[1] = v[1];
@@ -186,7 +192,7 @@
m->m[15] = v[15];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 *m, const float *v) {
m->m[0] = v[0];
m->m[1] = v[1];
@@ -199,7 +205,7 @@
m->m[8] = v[8];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 *m, const float *v) {
m->m[0] = v[0];
m->m[1] = v[1];
@@ -207,7 +213,7 @@
m->m[3] = v[3];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v) {
m->m[0] = v->m[0];
m->m[1] = v->m[1];
@@ -227,7 +233,7 @@
m->m[15] = v->m[15];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
m->m[0] = v->m[0];
m->m[1] = v->m[1];
@@ -247,7 +253,7 @@
m->m[15] = 1.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
m->m[0] = v->m[0];
m->m[1] = v->m[1];
@@ -267,7 +273,7 @@
m->m[15] = 1.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v) {
m->m[0] = v->m[0];
m->m[1] = v->m[1];
@@ -280,7 +286,7 @@
m->m[8] = v->m[8];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v) {
m->m[0] = v->m[0];
m->m[1] = v->m[1];
@@ -288,7 +294,7 @@
m->m[3] = v->m[3];
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
float c, s;
m->m[3] = 0;
@@ -327,7 +333,7 @@
m->m[10] = z*z*nc + c;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) {
rsMatrixLoadIdentity(m);
m->m[0] = x;
@@ -335,7 +341,7 @@
m->m[10] = z;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) {
rsMatrixLoadIdentity(m);
m->m[12] = x;
@@ -343,7 +349,7 @@
m->m[14] = z;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
for (int i=0 ; i<4 ; i++) {
float ri0 = 0;
@@ -364,14 +370,14 @@
}
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) {
rs_matrix4x4 mt;
rsMatrixLoadMultiply(&mt, m, rhs);
rsMatrixLoad(m, &mt);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
for (int i=0 ; i<3 ; i++) {
float ri0 = 0;
@@ -389,14 +395,14 @@
}
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) {
rs_matrix3x3 mt;
rsMatrixLoadMultiply(&mt, m, rhs);
rsMatrixLoad(m, &mt);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
for (int i=0 ; i<2 ; i++) {
float ri0 = 0;
@@ -411,35 +417,35 @@
}
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) {
rs_matrix2x2 mt;
rsMatrixLoadMultiply(&mt, m, rhs);
rsMatrixLoad(m, &mt);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
rs_matrix4x4 m1;
rsMatrixLoadRotate(&m1, rot, x, y, z);
rsMatrixMultiply(m, &m1);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z) {
rs_matrix4x4 m1;
rsMatrixLoadScale(&m1, x, y, z);
rsMatrixMultiply(m, &m1);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) {
rs_matrix4x4 m1;
rsMatrixLoadTranslate(&m1, x, y, z);
rsMatrixMultiply(m, &m1);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
rsMatrixLoadIdentity(m);
m->m[0] = 2.f / (right - left);
@@ -450,7 +456,7 @@
m->m[14]= -(far + near) / (far - near);
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
rsMatrixLoadIdentity(m);
m->m[0] = 2.f * near / (right - left);
@@ -463,7 +469,7 @@
m->m[15]= 0.f;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far) {
float top = near * tan((float) (fovy * M_PI / 360.0f));
float bottom = -top;
@@ -472,7 +478,7 @@
rsMatrixLoadFrustum(m, left, right, bottom, top, near, far);
}
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
float4 ret;
ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w);
@@ -482,7 +488,7 @@
return ret;
}
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
float4 ret;
ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12];
@@ -492,7 +498,7 @@
return ret;
}
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
float4 ret;
ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12];
@@ -502,7 +508,7 @@
return ret;
}
-static float3 __attribute__((overloadable))
+_RS_STATIC float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
float3 ret;
ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z);
@@ -511,7 +517,7 @@
return ret;
}
-static float3 __attribute__((overloadable))
+_RS_STATIC float3 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
float3 ret;
ret.x = (m->m[0] * in.x) + (m->m[3] * in.y);
@@ -520,7 +526,7 @@
return ret;
}
-static float2 __attribute__((overloadable))
+_RS_STATIC float2 __attribute__((overloadable))
rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
float2 ret;
ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
@@ -529,7 +535,7 @@
}
// Returns true if the matrix was successfully inversed
-static bool __attribute__((overloadable))
+_RS_STATIC bool __attribute__((overloadable))
rsMatrixInverse(rs_matrix4x4 *m) {
rs_matrix4x4 result;
@@ -571,7 +577,7 @@
}
// Returns true if the matrix was successfully inversed
-static bool __attribute__((overloadable))
+_RS_STATIC bool __attribute__((overloadable))
rsMatrixInverseTranspose(rs_matrix4x4 *m) {
rs_matrix4x4 result;
@@ -612,7 +618,7 @@
return true;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixTranspose(rs_matrix4x4 *m) {
int i, j;
float temp;
@@ -625,7 +631,7 @@
}
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixTranspose(rs_matrix3x3 *m) {
int i, j;
float temp;
@@ -638,7 +644,7 @@
}
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsMatrixTranspose(rs_matrix2x2 *m) {
float temp = m->m[1];
m->m[1] = m->m[2];
@@ -649,7 +655,7 @@
// quaternion ops
/////////////////////////////////////////////////////
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
q->w = w;
q->x = x;
@@ -657,7 +663,7 @@
q->z = z;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
q->w = rhs->w;
q->x = rhs->x;
@@ -665,7 +671,7 @@
q->z = rhs->z;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsQuaternionMultiply(rs_quaternion *q, float s) {
q->w *= s;
q->x *= s;
@@ -673,7 +679,7 @@
q->z *= s;
}
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
@@ -681,7 +687,7 @@
q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
}
-static void
+_RS_STATIC void
rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
q->w *= rhs->w;
q->x *= rhs->x;
@@ -689,7 +695,7 @@
q->z *= rhs->z;
}
-static void
+_RS_STATIC void
rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
rot *= (float)(M_PI / 180.0f) * 0.5f;
float c = cos(rot);
@@ -701,7 +707,7 @@
q->z = z * s;
}
-static void
+_RS_STATIC void
rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
const float len = x*x + y*y + z*z;
if (len != 1) {
@@ -713,19 +719,19 @@
rsQuaternionLoadRotateUnit(q, rot, x, y, z);
}
-static void
+_RS_STATIC void
rsQuaternionConjugate(rs_quaternion *q) {
q->x = -q->x;
q->y = -q->y;
q->z = -q->z;
}
-static float
+_RS_STATIC float
rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
}
-static void
+_RS_STATIC void
rsQuaternionNormalize(rs_quaternion *q) {
const float len = rsQuaternionDot(q, q);
if (len != 1) {
@@ -734,7 +740,7 @@
}
}
-static void
+_RS_STATIC void
rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
if (t <= 0.0f) {
rsQuaternionSet(q, q0);
@@ -776,7 +782,7 @@
tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
}
-static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
+_RS_STATIC void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
float x2 = 2.0f * q->x * q->x;
float y2 = 2.0f * q->y * q->y;
float z2 = 2.0f * q->z * q->z;
@@ -811,7 +817,7 @@
/////////////////////////////////////////////////////
// utility funcs
/////////////////////////////////////////////////////
-__inline__ static void __attribute__((overloadable, always_inline))
+__inline__ _RS_STATIC void __attribute__((overloadable, always_inline))
rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
float4 *left, float4 *right,
float4 *top, float4 *bottom,
@@ -861,7 +867,7 @@
*far /= len;
}
-__inline__ static bool __attribute__((overloadable, always_inline))
+__inline__ _RS_STATIC bool __attribute__((overloadable, always_inline))
rsIsSphereInFrustum(float4 *sphere,
float4 *left, float4 *right,
float4 *top, float4 *bottom,
@@ -899,26 +905,26 @@
// int ops
/////////////////////////////////////////////////////
-__inline__ static uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
+__inline__ _RS_STATIC uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
return amount < low ? low : (amount > high ? high : amount);
}
-__inline__ static int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
+__inline__ _RS_STATIC int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
return amount < low ? low : (amount > high ? high : amount);
}
-__inline__ static ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
+__inline__ _RS_STATIC ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
return amount < low ? low : (amount > high ? high : amount);
}
-__inline__ static short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
+__inline__ _RS_STATIC short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
return amount < low ? low : (amount > high ? high : amount);
}
-__inline__ static uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
+__inline__ _RS_STATIC uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
return amount < low ? low : (amount > high ? high : amount);
}
-__inline__ static char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
+__inline__ _RS_STATIC char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
return amount < low ? low : (amount > high ? high : amount);
}
-
+#undef _RS_STATIC
#endif
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 212eb83..0f8717f 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -1,6 +1,14 @@
#ifndef __RS_TYPES_RSH__
#define __RS_TYPES_RSH__
+#define M_PI 3.14159265358979323846264338327950288f /* pi */
+
+//#include "external/clang/lib/Headers/stdbool.h"
+#define bool _Bool
+#define true 1
+#define false 0
+#define __bool_true_false_are_defined 1
+
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 3b2ef84..af11f97 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -261,8 +261,7 @@
// NOTE: if stack.head is messed up, we could crash the client
// or cause some drawing artifacts. This is okay, as long as it is
// limited to the client.
- return (buf != stack.index[stack.head] ||
- (stack.queued > 0 && stack.inUse != buf));
+ return (buf != stack.index[stack.head]);
}
SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition(
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 3e54627..d3e9a49 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -150,7 +150,7 @@
*/
public static final int ERROR = -1;
/**
- * Internal opreation status. Not returned by any method.
+ * Internal operation status. Not returned by any method.
*/
public static final int ALREADY_EXISTS = -2;
/**
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 41309dc..bcf7b89 100755
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -95,7 +95,7 @@
*/
public static final int ERROR = -1;
/**
- * Internal opreation status. Not returned by any method.
+ * Internal operation status. Not returned by any method.
*/
public static final int ALREADY_EXISTS = -2;
/**
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 9ce6738..af67175 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -5,6 +5,7 @@
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/IOMX.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <surfaceflinger/ISurface.h>
#include <surfaceflinger/Surface.h>
@@ -449,74 +450,8 @@
}
case GET_PARAMETER:
- {
- CHECK_INTERFACE(IOMX, data, reply);
-
- node_id node = (void*)data.readIntPtr();
- OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
- size_t size = data.readInt32();
-
- // XXX I am not happy with this but Parcel::readInplace didn't work.
- void *params = malloc(size);
- data.read(params, size);
-
- status_t err = getParameter(node, index, params, size);
-
- reply->writeInt32(err);
-
- if (err == OK) {
- reply->write(params, size);
- }
-
- free(params);
- params = NULL;
-
- return NO_ERROR;
- }
-
case SET_PARAMETER:
- {
- CHECK_INTERFACE(IOMX, data, reply);
-
- node_id node = (void*)data.readIntPtr();
- OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
- size_t size = data.readInt32();
- void *params = const_cast<void *>(data.readInplace(size));
-
- reply->writeInt32(setParameter(node, index, params, size));
-
- return NO_ERROR;
- }
-
case GET_CONFIG:
- {
- CHECK_INTERFACE(IOMX, data, reply);
-
- node_id node = (void*)data.readIntPtr();
- OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
- size_t size = data.readInt32();
-
- // XXX I am not happy with this but Parcel::readInplace didn't work.
- void *params = malloc(size);
- data.read(params, size);
-
- status_t err = getConfig(node, index, params, size);
-
- reply->writeInt32(err);
-
- if (err == OK) {
- reply->write(params, size);
- }
-
- free(params);
- params = NULL;
-
- return NO_ERROR;
- }
-
case SET_CONFIG:
{
CHECK_INTERFACE(IOMX, data, reply);
@@ -525,9 +460,36 @@
OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
size_t size = data.readInt32();
- void *params = const_cast<void *>(data.readInplace(size));
- reply->writeInt32(setConfig(node, index, params, size));
+ void *params = malloc(size);
+ data.read(params, size);
+
+ status_t err;
+ switch (code) {
+ case GET_PARAMETER:
+ err = getParameter(node, index, params, size);
+ break;
+ case SET_PARAMETER:
+ err = setParameter(node, index, params, size);
+ break;
+ case GET_CONFIG:
+ err = getConfig(node, index, params, size);
+ break;
+ case SET_CONFIG:
+ err = setConfig(node, index, params, size);
+ break;
+ default:
+ TRESPASS();
+ }
+
+ reply->writeInt32(err);
+
+ if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
+ reply->write(params, size);
+ }
+
+ free(params);
+ params = NULL;
return NO_ERROR;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 992abd7..153b2a6 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1229,23 +1229,13 @@
}
if (mVideoEncoderLevel != -1) {
enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
- } else if (mCaptureTimeLapse) {
- // Check if we are using high resolution and/or high bitrate and
- // set appropriate level for the software AVCEncoder.
- if ((width * height >= 921600) // 720p
- || (videoBitRate >= 20000000)) {
- enc_meta->setInt32(kKeyVideoLevel, OMX_VIDEO_AVCLevel5);
- }
}
OMXClient client;
CHECK_EQ(client.connect(), OK);
- // Use software codec for time lapse
uint32_t encoder_flags = 0;
- if (mCaptureTimeLapse) {
- encoder_flags |= OMXCodec::kPreferSoftwareCodecs;
- } else if (mIsMetaDataStoredInVideoBuffers) {
+ if (mIsMetaDataStoredInVideoBuffers) {
encoder_flags |= OMXCodec::kHardwareCodecsOnly;
encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 49d05ed..58c4a2e 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -165,6 +165,8 @@
mTimeSource(NULL),
mVideoRendererIsPreview(false),
mAudioPlayer(NULL),
+ mDisplayWidth(0),
+ mDisplayHeight(0),
mFlags(0),
mExtractorFlags(0),
mVideoBuffer(NULL),
@@ -329,6 +331,18 @@
if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
setVideoSource(extractor->getTrack(i));
haveVideo = true;
+
+ // Set the presentation/display size
+ int32_t displayWidth, displayHeight;
+ bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
+ if (success) {
+ success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
+ }
+ if (success) {
+ mDisplayWidth = displayWidth;
+ mDisplayHeight = displayHeight;
+ }
+
} else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
setAudioSource(extractor->getTrack(i));
haveAudio = true;
@@ -370,6 +384,8 @@
void AwesomePlayer::reset_l() {
LOGI("reset_l");
+ mDisplayWidth = 0;
+ mDisplayHeight = 0;
if (mDecryptHandle != NULL) {
mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -862,6 +878,12 @@
int32_t usableWidth = cropRight - cropLeft + 1;
int32_t usableHeight = cropBottom - cropTop + 1;
+ if (mDisplayWidth != 0) {
+ usableWidth = mDisplayWidth;
+ }
+ if (mDisplayHeight != 0) {
+ usableHeight = mDisplayHeight;
+ }
int32_t rotationDegrees;
if (!mVideoTrack->getFormat()->findInt32(
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 31b6ec9..b58b9d8 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -66,7 +66,7 @@
int32_t videoFrameRate,
const sp<Surface>& surface,
int64_t timeBetweenTimeLapseFrameCaptureUs)
- : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface, false),
+ : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface, true),
mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs),
mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
mLastTimeLapseFrameRealTimestampUs(0),
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index e7f00aa..057868c 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -25,13 +25,14 @@
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/foundation/ADebug.h>
namespace android {
@@ -47,6 +48,82 @@
disconnect();
}
+static bool MakeSocketBlocking(int s, bool blocking) {
+ // Make socket non-blocking.
+ int flags = fcntl(s, F_GETFL, 0);
+ if (flags == -1) {
+ return false;
+ }
+
+ if (blocking) {
+ flags &= ~O_NONBLOCK;
+ } else {
+ flags |= O_NONBLOCK;
+ }
+
+ return fcntl(s, F_SETFL, flags) != -1;
+}
+
+static status_t MyConnect(
+ int s, const struct sockaddr *addr, socklen_t addrlen) {
+ status_t result = UNKNOWN_ERROR;
+
+ MakeSocketBlocking(s, false);
+
+ if (connect(s, addr, addrlen) == 0) {
+ result = OK;
+ } else if (errno != EINPROGRESS) {
+ result = -errno;
+ } else {
+ for (;;) {
+ fd_set rs, ws;
+ FD_ZERO(&rs);
+ FD_ZERO(&ws);
+ FD_SET(s, &rs);
+ FD_SET(s, &ws);
+
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000ll;
+
+ int nfds = ::select(s + 1, &rs, &ws, NULL, &tv);
+
+ if (nfds < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+
+ result = -errno;
+ break;
+ }
+
+ if (FD_ISSET(s, &ws) && !FD_ISSET(s, &rs)) {
+ result = OK;
+ break;
+ }
+
+ if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
+ // Get the pending error.
+ int error = 0;
+ socklen_t errorLen = sizeof(error);
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
+ // Couldn't get the real error, so report why not.
+ result = -errno;
+ } else {
+ result = -error;
+ }
+ break;
+ }
+
+ // Timeout expired. Try again.
+ }
+ }
+
+ MakeSocketBlocking(s, true);
+
+ return result;
+}
+
status_t HTTPStream::connect(const char *server, int port) {
Mutex::Autolock autoLock(mLock);
@@ -82,7 +159,7 @@
addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
- int res = ::connect(s, (const struct sockaddr *)&addr, sizeof(addr));
+ status_t res = MyConnect(s, (const struct sockaddr *)&addr, sizeof(addr));
mLock.lock();
@@ -90,12 +167,12 @@
return UNKNOWN_ERROR;
}
- if (res < 0) {
+ if (res != OK) {
close(mSocket);
mSocket = -1;
mState = READY;
- return UNKNOWN_ERROR;
+ return res;
}
mState = CONNECTED;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index bafa243..e6e98aa 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1040,8 +1040,23 @@
// have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
// and thus will grow by 2 bytes per fragment.
mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
-
*offset += chunk_size;
+
+ // Calculate average frame rate.
+ const char *mime;
+ CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
+ if (!strncasecmp("video/", mime, 6)) {
+ size_t nSamples = mLastTrack->sampleTable->countSamples();
+ int64_t durationUs;
+ if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
+ if (durationUs > 0) {
+ int32_t frameRate = (nSamples * 1000000LL +
+ (durationUs >> 1)) / durationUs;
+ mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
+ }
+ }
+ }
+
break;
}
@@ -1321,10 +1336,12 @@
mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
}
-#if 0
+ // Handle presentation display size, which could be different
+ // from the image size indicated by kKeyWidth and kKeyHeight.
uint32_t width = U32_AT(&buffer[dynSize + 52]);
uint32_t height = U32_AT(&buffer[dynSize + 56]);
-#endif
+ mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
+ mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
return OK;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index e516cb4..d842f65 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2233,7 +2233,11 @@
enablePortAsync(portIndex);
status_t err = allocateBuffersOnPort(portIndex);
- CHECK_EQ(err, (status_t)OK);
+
+ if (err != OK) {
+ CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+ setState(ERROR);
+ }
}
break;
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index fe008569..41ef181 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -150,6 +150,9 @@
AudioPlayer *mAudioPlayer;
int64_t mDurationUs;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+
uint32_t mFlags;
uint32_t mExtractorFlags;
uint32_t mSinceLastDropped;
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 4099c4c..32d1a23 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -272,7 +272,6 @@
}
/**
- * @hide
* Control whether the EGL context is preserved when the GLSurfaceView is paused and
* resumed.
* <p>
@@ -295,7 +294,6 @@
}
/**
- * @hide
* @return true if the EGL context will be preserved when paused
*/
public boolean getPreserveEGLContextOnPause() {
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 2ec2226..21f77e3 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -190,6 +190,7 @@
while ((pkg=pm.nextPackageToClean(pkg)) != null) {
eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg));
eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg));
+ eraseFiles(Environment.getExternalStorageAppObbDirectory(pkg));
}
} catch (RemoteException e) {
}
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5f01f4d..b0eac55 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index aa98f7d..53c44c6 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 583044d..168d8af 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ea5694d..1ff4a80 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b95c6cb..969a7d8 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4043c2e..cc741ee 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 39a462c..83f29ff 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 72373bb..068451e 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
index f29259a..5c9c6fc 100644
--- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
@@ -9,6 +9,8 @@
<string name="status_bar_settings_rotation_lock" msgid="9125161825884157545">"Bloquear orient. de pant."</string>
<!-- XL -->
<string name="recent_tasks_app_label" msgid="5550538721034982973">"Google Apps"</string>
+ <!-- XL -->
+ <string name="bluetooth_tethered" msgid="8017158699581472359">"Bluetooth anclado"</string>
<!-- XL xlarge -->
<string name="status_bar_settings_signal_meter_disconnected" msgid="4866302415753953027">"Sin conexión a Internet"</string>
<!-- XL xlarge -->
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 8013a19..da742e6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3acfb45..58046ab 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0528d68..3c65051 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 1ce102a..cbb2eec 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 12308fb..d199d9a 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 411336a..3e60b8d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b82aa77..dbcd29d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index db170ab..db87cd3 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ca99d86..9d751795 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f2d5621..34eb41f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 25d8873..3b59844 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 6c5970a..35d7503 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 90a5e44..a5848a9 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index fb33329..cf81e85 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 82405a8..4d6140f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4efdcbb..339d146 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 07ef5ef..b50c422 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index aa14cce..01544b5 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 17be76a..35ffabb 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index e3fec88..7b94e9b 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -57,4 +57,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2bb3c14..4e32019 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 89b9cc8..7a6a71e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9716327..6b497b9 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b05b93c..54145f2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -32,8 +32,7 @@
<string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto."\n"Uporabite priloženi polnilnik."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Uporaba baterije"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
- <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
- <skip />
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način za letalo"</string>
<string name="status_bar_settings_rotation_lock" msgid="8361452930058000609">"Zakleni usmerjenost zaslona"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"TIHO"</string>
@@ -45,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ff1d3fb..6ee4009 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 06b6880..99623c3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2d337a90..7d154a6 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e94d3cc..bb56bc2 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4c3f818..361d7ee 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 85ead1c..ae40e56 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 71df0c3..2ec07f1 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0cdc38d..cb15613 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index c85020f..960130f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -44,4 +44,6 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
</resources>
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index 63b87b1..a618423 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -328,6 +328,7 @@
public void run() {
Log.i(TAG, "VPN connectivity monitor running");
try {
+ mNotification.update(mStartTime); // to pop up notification
for (int i = 10; ; i--) {
long now = System.currentTimeMillis();
@@ -417,13 +418,27 @@
// Helper class for showing, updating notification.
private class NotificationHelper {
+ private NotificationManager mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ private Notification mNotification =
+ new Notification(R.drawable.vpn_connected, null, 0L);
+ private PendingIntent mPendingIntent = PendingIntent.getActivity(
+ mContext, 0,
+ new VpnManager(mContext).createSettingsActivityIntent(), 0);
+ private String mConnectedTitle;
+
void update(long now) {
- String title = getNotificationTitle(true);
- Notification n = new Notification(R.drawable.vpn_connected, title,
- mStartTime);
- n.setLatestEventInfo(mContext, title,
+ Notification n = mNotification;
+ if (now == mStartTime) {
+ // to pop up the notification for the first time
+ n.when = mStartTime;
+ n.tickerText = mConnectedTitle = getNotificationTitle(true);
+ } else {
+ n.tickerText = null;
+ }
+ n.setLatestEventInfo(mContext, mConnectedTitle,
getConnectedNotificationMessage(now),
- prepareNotificationIntent());
+ mPendingIntent);
n.flags |= Notification.FLAG_NO_CLEAR;
n.flags |= Notification.FLAG_ONGOING_EVENT;
enableNotification(n);
@@ -435,25 +450,18 @@
title, System.currentTimeMillis());
n.setLatestEventInfo(mContext, title,
getDisconnectedNotificationMessage(),
- prepareNotificationIntent());
+ mPendingIntent);
n.flags |= Notification.FLAG_AUTO_CANCEL;
disableNotification();
enableNotification(n);
}
void disableNotification() {
- ((NotificationManager) mContext.getSystemService(
- Context.NOTIFICATION_SERVICE)).cancel(NOTIFICATION_ID);
+ mNotificationManager.cancel(NOTIFICATION_ID);
}
private void enableNotification(Notification n) {
- ((NotificationManager) mContext.getSystemService(
- Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, n);
- }
-
- private PendingIntent prepareNotificationIntent() {
- return PendingIntent.getActivity(mContext, 0,
- new VpnManager(mContext).createSettingsActivityIntent(), 0);
+ mNotificationManager.notify(NOTIFICATION_ID, n);
}
private String getNotificationTitle(boolean connected) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 68c1453..c313713b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -166,6 +166,8 @@
private int mTitleColor = 0;
+ private boolean mAlwaysReadCloseOnTouchAttr = false;
+
private ContextMenuBuilder mContextMenu;
private MenuDialogHelper mContextMenuHelper;
private ActionButtonSubmenu mActionButtonPopup;
@@ -1983,6 +1985,7 @@
}
if (mActionModeView != null) {
+ mActionModeView.killMode();
mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback);
if (callback.onCreateActionMode(mode, mode.getMenu())) {
mode.invalidate();
@@ -2326,6 +2329,15 @@
addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
}
+ if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
+ >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ if (a.getBoolean(
+ com.android.internal.R.styleable.Window_windowCloseOnTouchOutside,
+ false)) {
+ setCloseOnTouchOutsideIfNotSet(true);
+ }
+ }
+
WindowManager.LayoutParams params = getAttributes();
if (!hasSoftInputMode()) {
@@ -2479,6 +2491,11 @@
return contentParent;
}
+ /** @hide */
+ public void alwaysReadCloseOnTouchAttr() {
+ mAlwaysReadCloseOnTouchAttr = true;
+ }
+
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 51b5947..16c042d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -131,18 +131,21 @@
: BnAudioFlinger(),
mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
{
+ Mutex::Autolock _l(mLock);
+
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
mHardwareStatus = AUDIO_HW_INIT;
if (mAudioHardware->initCheck() == NO_ERROR) {
- // open 16-bit output stream for s/w mixer
+ AutoMutex lock(mHardwareLock);
mMode = AudioSystem::MODE_NORMAL;
- setMode(mMode);
-
- setMasterVolume(1.0f);
- setMasterMute(false);
+ mHardwareStatus = AUDIO_HW_SET_MODE;
+ mAudioHardware->setMode(mMode);
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ mAudioHardware->setMasterVolume(1.0f);
+ mHardwareStatus = AUDIO_HW_IDLE;
} else {
LOGE("Couldn't even initialize the stubbed audio hardware!");
}
@@ -440,13 +443,16 @@
}
// when hw supports master volume, don't scale in sw mixer
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
- value = 1.0f;
+ { // scope for the lock
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+ value = 1.0f;
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
}
- mHardwareStatus = AUDIO_HW_IDLE;
+ Mutex::Autolock _l(mLock);
mMasterVolume = value;
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setMasterVolume(value);
@@ -517,6 +523,7 @@
return PERMISSION_DENIED;
}
+ Mutex::Autolock _l(mLock);
mMasterMute = muted;
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setMasterMute(muted);
@@ -579,6 +586,7 @@
return BAD_VALUE;
}
+ AutoMutex lock(mLock);
mStreamTypes[stream].mute = muted;
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index eeca7ab..e4086c4 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1052,25 +1052,27 @@
updateDeviceForStrategy();
#ifdef AUDIO_POLICY_TEST
- AudioParameter outputCmd = AudioParameter();
- outputCmd.addInt(String8("set_id"), 0);
- mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+ if (mHardwareOutput != 0) {
+ AudioParameter outputCmd = AudioParameter();
+ outputCmd.addInt(String8("set_id"), 0);
+ mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
- mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
- mTestSamplingRate = 44100;
- mTestFormat = AudioSystem::PCM_16_BIT;
- mTestChannels = AudioSystem::CHANNEL_OUT_STEREO;
- mTestLatencyMs = 0;
- mCurOutput = 0;
- mDirectOutput = false;
- for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
- mTestOutputs[i] = 0;
+ mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
+ mTestSamplingRate = 44100;
+ mTestFormat = AudioSystem::PCM_16_BIT;
+ mTestChannels = AudioSystem::CHANNEL_OUT_STEREO;
+ mTestLatencyMs = 0;
+ mCurOutput = 0;
+ mDirectOutput = false;
+ for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
+ mTestOutputs[i] = 0;
+ }
+
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ snprintf(buffer, SIZE, "AudioPolicyManagerTest");
+ run(buffer, ANDROID_PRIORITY_AUDIO);
}
-
- const size_t SIZE = 256;
- char buffer[SIZE];
- snprintf(buffer, SIZE, "AudioPolicyManagerTest");
- run(buffer, ANDROID_PRIORITY_AUDIO);
#endif //AUDIO_POLICY_TEST
}
@@ -1091,6 +1093,11 @@
mInputs.clear();
}
+status_t AudioPolicyManagerBase::initCheck()
+{
+ return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR;
+}
+
#ifdef AUDIO_POLICY_TEST
bool AudioPolicyManagerBase::threadLoop()
{
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index f24e08e..46a01ad 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -68,6 +68,8 @@
{
char value[PROPERTY_VALUE_MAX];
+ Mutex::Autolock _l(mLock);
+
// start tone playback thread
mTonePlaybackThread = new AudioCommandThread(String8(""));
// start audio commands thread
@@ -88,9 +90,18 @@
}
#endif
- // load properties
- property_get("ro.camera.sound.forced", value, "0");
- mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+ if ((mpPolicyManager != NULL) && (mpPolicyManager->initCheck() != NO_ERROR)) {
+ delete mpPolicyManager;
+ mpPolicyManager = NULL;
+ }
+
+ if (mpPolicyManager == NULL) {
+ LOGE("Could not create AudioPolicyManager");
+ } else {
+ // load properties
+ property_get("ro.camera.sound.forced", value, "0");
+ mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+ }
}
AudioPolicyService::~AudioPolicyService()
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 6b66791..8e9a5a4 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -121,7 +121,7 @@
const sp<InputReaderPolicyInterface>& policy,
const sp<InputDispatcherInterface>& dispatcher) :
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
- mGlobalMetaState(0) {
+ mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
configureExcludedDevices();
updateGlobalMetaState();
updateInputConfiguration();
@@ -373,6 +373,24 @@
} // release state lock
}
+void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+ mDisableVirtualKeysTimeout = time;
+}
+
+bool InputReader::shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ if (now < mDisableVirtualKeysTimeout) {
+ LOGI("Dropping virtual key from device %s because virtual keys are "
+ "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
+ device->getName().string(),
+ (mDisableVirtualKeysTimeout - now) * 0.000001,
+ keyCode, scanCode);
+ return true;
+ } else {
+ return false;
+ }
+}
+
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
{ // acquire state lock
AutoMutex _l(mStateLock);
@@ -889,6 +907,12 @@
keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
} else {
// key down
+ if ((policyFlags & POLICY_FLAG_VIRTUAL)
+ && mContext->shouldDropVirtualKey(when,
+ getDevice(), keyCode, scanCode)) {
+ return;
+ }
+
mLocked.keyDowns.push();
KeyDown& keyDown = mLocked.keyDowns.editTop();
keyDown.keyCode = keyCode;
@@ -1428,6 +1452,7 @@
mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+ mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
String8 deviceTypeString;
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
@@ -2219,6 +2244,7 @@
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
+ detectGestures(when);
dispatchTouches(when, policyFlags);
}
@@ -2304,6 +2330,11 @@
if (mCurrentTouch.pointerCount == 1) {
const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
if (virtualKey) {
+ if (mContext->shouldDropVirtualKey(when, getDevice(),
+ virtualKey->keyCode, virtualKey->scanCode)) {
+ return DROP_STROKE;
+ }
+
mLocked.currentVirtualKey.down = true;
mLocked.currentVirtualKey.downTime = when;
mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
@@ -2341,6 +2372,26 @@
return touchResult;
}
+void TouchInputMapper::detectGestures(nsecs_t when) {
+ // Disable all virtual key touches that happen within a short time interval of the
+ // most recent touch. The idea is to filter out stray virtual key presses when
+ // interacting with the touch screen.
+ //
+ // Problems we're trying to solve:
+ //
+ // 1. While scrolling a list or dragging the window shade, the user swipes down into a
+ // virtual key area that is implemented by a separate touch panel and accidentally
+ // triggers a virtual key.
+ //
+ // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
+ // area and accidentally triggers a virtual key. This often happens when virtual keys
+ // are layed out below the screen near to where the on screen keyboard's space bar
+ // is displayed.
+ if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+ mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
+ }
+}
+
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
uint32_t currentPointerCount = mCurrentTouch.pointerCount;
uint32_t lastPointerCount = mLastTouch.pointerCount;
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 8b2d40a..7619682 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -78,6 +78,12 @@
*/
virtual bool filterJumpyTouchEvents() = 0;
+ /* Gets the amount of time to disable virtual keys after the screen is touched
+ * in order to filter out accidental virtual key presses due to swiping gestures
+ * or taps near the edge of the display. May be 0 to disable the feature.
+ */
+ virtual nsecs_t getVirtualKeyQuietTime() = 0;
+
/* Gets the excluded device names for the platform. */
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
@@ -147,6 +153,10 @@
virtual void updateGlobalMetaState() = 0;
virtual int32_t getGlobalMetaState() = 0;
+ virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
+
virtual InputReaderPolicyInterface* getPolicy() = 0;
virtual InputDispatcherInterface* getDispatcher() = 0;
virtual EventHubInterface* getEventHub() = 0;
@@ -234,6 +244,11 @@
InputConfiguration mInputConfiguration;
void updateInputConfiguration();
+ nsecs_t mDisableVirtualKeysTimeout;
+ virtual void disableVirtualKeysUntil(nsecs_t time);
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode);
+
// state queries
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
@@ -603,6 +618,7 @@
bool useBadTouchFilter;
bool useJumpyTouchFilter;
bool useAveragingTouchFilter;
+ nsecs_t virtualKeyQuietTime;
} mParameters;
// Immutable calibration parameters in parsed form.
@@ -839,6 +855,7 @@
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
int32_t motionEventAction);
+ void detectGestures(nsecs_t when);
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 8ec6f53..775747c 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -127,6 +127,10 @@
mFilterJumpyTouchEvents = enabled;
}
+ virtual nsecs_t getVirtualKeyQuietTime() {
+ return 0;
+ }
+
void addExcludedDeviceName(const String8& deviceName) {
mExcludedDeviceNames.push(deviceName);
}
@@ -722,6 +726,14 @@
virtual InputDispatcherInterface* getDispatcher() {
return mDispatcher.get();
}
+
+ virtual void disableVirtualKeysUntil(nsecs_t time) {
+ }
+
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ return false;
+ }
};
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 22dd804..59a540b 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -16,6 +16,23 @@
package com.android.server;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
@@ -24,46 +41,37 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.Intent.FilterComparison;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.Pair;
import android.util.Slog;
import android.util.TypedValue;
import android.util.Xml;
import android.widget.RemoteViews;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.appwidget.IAppWidgetHost;
+import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.util.FastXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
+import com.android.internal.widget.IRemoteViewsAdapterConnection;
class AppWidgetService extends IAppWidgetService.Stub
{
@@ -107,6 +115,56 @@
Host host;
}
+ /**
+ * Acts as a proxy between the ServiceConnection and the RemoteViewsAdapterConnection.
+ * This needs to be a static inner class since a reference to the ServiceConnection is held
+ * globally and may lead us to leak AppWidgetService instances (if there were more than one).
+ */
+ static class ServiceConnectionProxy implements ServiceConnection {
+ private final AppWidgetService mAppWidgetService;
+ private final Pair<Integer, Intent.FilterComparison> mKey;
+ private final IBinder mConnectionCb;
+
+ ServiceConnectionProxy(AppWidgetService appWidgetService,
+ Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) {
+ mAppWidgetService = appWidgetService;
+ mKey = key;
+ mConnectionCb = connectionCb;
+ }
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IRemoteViewsAdapterConnection cb =
+ IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
+ try {
+ cb.onServiceConnected(service);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ public void onServiceDisconnected(ComponentName name) {
+ IRemoteViewsAdapterConnection cb =
+ IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
+ try {
+ cb.onServiceDisconnected();
+ mAppWidgetService.mServiceConnectionUpdateHandler.post(new Runnable() {
+ public void run() {
+ // We don't want to touch mBoundRemoteViewsServices from any other thread
+ // so queue this to run on the main thread.
+ if (mAppWidgetService.mBoundRemoteViewsServices.containsKey(mKey)) {
+ mAppWidgetService.mBoundRemoteViewsServices.remove(mKey);
+ }
+ }
+ });
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // Manages connections to RemoteViewsServices
+ private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection>
+ mBoundRemoteViewsServices = new HashMap<Pair<Integer,FilterComparison>,ServiceConnection>();
+ private final Handler mServiceConnectionUpdateHandler = new Handler();
+
Context mContext;
Locale mLocale;
PackageManager mPackageManager;
@@ -294,6 +352,9 @@
}
void deleteAppWidgetLocked(AppWidgetId id) {
+ // We first unbind all services that are bound to this id
+ unbindAppWidgetRemoteViewsServicesLocked(id);
+
Host host = id.host;
host.instances.remove(id);
pruneHostLocked(host);
@@ -376,6 +437,77 @@
}
}
+ public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
+ synchronized (mAppWidgetIds) {
+ AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+ if (id == null) {
+ throw new IllegalArgumentException("bad appWidgetId");
+ }
+ final ComponentName componentName = intent.getComponent();
+ try {
+ final ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
+ PackageManager.GET_PERMISSIONS);
+ if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(si.permission)) {
+ throw new SecurityException("Selected service does not require "
+ + android.Manifest.permission.BIND_REMOTEVIEWS
+ + ": " + componentName);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException("Unknown component " + componentName);
+ }
+
+ // Bind to the RemoteViewsService (which will trigger a callback to the
+ // RemoteViewsAdapter)
+ Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
+ new FilterComparison(intent));
+ final ServiceConnection conn = new ServiceConnectionProxy(this, key, connection);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+ mBoundRemoteViewsServices.put(key, conn);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ }
+
+ public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
+ synchronized (mAppWidgetIds) {
+ AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+ if (id == null) {
+ throw new IllegalArgumentException("bad appWidgetId");
+ }
+
+ // Unbind from the RemoteViewsService (which will trigger a callback to the bound
+ // RemoteViewsAdapter)
+ Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
+ new FilterComparison(intent));
+ if (mBoundRemoteViewsServices.containsKey(key)) {
+ final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
+ mBoundRemoteViewsServices.remove(key);
+ conn.onServiceDisconnected(null);
+ mContext.unbindService(conn);
+ }
+ }
+ }
+
+ private void unbindAppWidgetRemoteViewsServicesLocked(AppWidgetId id) {
+ Iterator<Pair<Integer, Intent.FilterComparison>> it =
+ mBoundRemoteViewsServices.keySet().iterator();
+ int appWidgetId = id.appWidgetId;
+
+ // Unbind all connections to AppWidgets bound to this id
+ while (it.hasNext()) {
+ final Pair<Integer, Intent.FilterComparison> key = it.next();
+ if (key.first.intValue() == appWidgetId) {
+ final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
+ it.remove();
+ conn.onServiceDisconnected(null);
+ mContext.unbindService(conn);
+ }
+ }
+ }
+
public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
synchronized (mAppWidgetIds) {
AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 06595ae..8d249ff 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -481,7 +481,13 @@
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_filterJumpyTouchEvents);
}
-
+
+ @SuppressWarnings("unused")
+ public int getVirtualKeyQuietTimeMillis() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
+ }
+
@SuppressWarnings("unused")
public String[] getExcludedDeviceNames() {
ArrayList<String> names = new ArrayList<String>();
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 1eebd6a..059c0b8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4407,10 +4407,19 @@
}
}
}
-
+
+ /**
+ * Check if the external storage media is available. This is true if there
+ * is a mounted external storage medium or if the external storage is
+ * emulated.
+ */
+ private boolean isExternalMediaAvailable() {
+ return mMediaMounted || Environment.isExternalStorageEmulated();
+ }
+
public String nextPackageToClean(String lastPackage) {
synchronized (mPackages) {
- if (!mMediaMounted) {
+ if (!isExternalMediaAvailable()) {
// If the external storage is no longer mounted at this point,
// the caller may not have been able to delete all of this
// packages files and can not delete any more. Bail.
@@ -4430,7 +4439,7 @@
void startCleaningPackages() {
synchronized (mPackages) {
- if (!mMediaMounted) {
+ if (!isExternalMediaAvailable()) {
return;
}
if (mSettings.mPackagesToBeCleaned.size() <= 0) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index dbf9a96..2ef85d5 100755
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3060,7 +3060,7 @@
}
if (uid == pkgUid || checkComponentPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA,
- pid, uid, -1)
+ pid, uid, -1, true)
== PackageManager.PERMISSION_GRANTED) {
forceStopPackageLocked(packageName, pkgUid);
} else {
@@ -4151,7 +4151,7 @@
* This can be called with or without the global lock held.
*/
int checkComponentPermission(String permission, int pid, int uid,
- int reqUid) {
+ int owningUid, boolean exported) {
// We might be performing an operation on behalf of an indirect binder
// invocation, e.g. via {@link #openContentUri}. Check and adjust the
// client identity accordingly before proceeding.
@@ -4168,9 +4168,14 @@
!Process.supportsProcesses()) {
return PackageManager.PERMISSION_GRANTED;
}
- // If the target requires a specific UID, always fail for others.
- if (reqUid >= 0 && uid != reqUid) {
- Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
+ // If there is a uid that owns whatever is being accessed, it has
+ // blanket access to it regardless of the permissions it requires.
+ if (owningUid >= 0 && uid == owningUid) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+ // If the target is not exported, then nobody else can get to it.
+ if (!exported) {
+ Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
return PackageManager.PERMISSION_DENIED;
}
if (permission == null) {
@@ -4199,7 +4204,7 @@
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
- return checkComponentPermission(permission, pid, uid, -1);
+ return checkComponentPermission(permission, pid, uid, -1, true);
}
/**
@@ -5322,12 +5327,12 @@
final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
- cpi.exported ? -1 : cpi.applicationInfo.uid)
+ cpi.applicationInfo.uid, cpi.exported)
== PackageManager.PERMISSION_GRANTED) {
return null;
}
if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
- cpi.exported ? -1 : cpi.applicationInfo.uid)
+ cpi.applicationInfo.uid, cpi.exported)
== PackageManager.PERMISSION_GRANTED) {
return null;
}
@@ -5339,12 +5344,12 @@
i--;
PathPermission pp = pps[i];
if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
- cpi.exported ? -1 : cpi.applicationInfo.uid)
+ cpi.applicationInfo.uid, cpi.exported)
== PackageManager.PERMISSION_GRANTED) {
return null;
}
if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
- cpi.exported ? -1 : cpi.applicationInfo.uid)
+ cpi.applicationInfo.uid, cpi.exported)
== PackageManager.PERMISSION_GRANTED) {
return null;
}
@@ -5360,10 +5365,18 @@
}
}
- String msg = "Permission Denial: opening provider " + cpi.name
- + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
- + ", uid=" + callingUid + ") requires "
- + cpi.readPermission + " or " + cpi.writePermission;
+ String msg;
+ if (!cpi.exported) {
+ msg = "Permission Denial: opening provider " + cpi.name
+ + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+ + ", uid=" + callingUid + ") that is not exported from uid "
+ + cpi.applicationInfo.uid;
+ } else {
+ msg = "Permission Denial: opening provider " + cpi.name
+ + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+ + ", uid=" + callingUid + ") requires "
+ + cpi.readPermission + " or " + cpi.writePermission;
+ }
Slog.w(TAG, msg);
return msg;
}
@@ -5953,7 +5966,7 @@
final int perm = checkComponentPermission(
android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
- callingUid, -1);
+ callingUid, -1, true);
if (perm == PackageManager.PERMISSION_GRANTED) {
return true;
}
@@ -8892,8 +8905,16 @@
int callingPid = Binder.getCallingPid();
int callingUid = Binder.getCallingUid();
if (checkComponentPermission(r.permission,
- callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
+ callingPid, callingUid, r.appInfo.uid, r.exported)
!= PackageManager.PERMISSION_GRANTED) {
+ if (!r.exported) {
+ Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+ + " from pid=" + callingPid
+ + ", uid=" + callingUid
+ + " that is not exported from uid " + r.appInfo.uid);
+ return new ServiceLookupResult(null, "not exported from uid "
+ + r.appInfo.uid);
+ }
Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+ " from pid=" + callingPid
+ ", uid=" + callingUid
@@ -8975,11 +8996,19 @@
}
if (r != null) {
if (checkComponentPermission(r.permission,
- callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
+ callingPid, callingUid, r.appInfo.uid, r.exported)
!= PackageManager.PERMISSION_GRANTED) {
+ if (!r.exported) {
+ Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+ + " from pid=" + callingPid
+ + ", uid=" + callingUid
+ + " that is not exported from uid " + r.appInfo.uid);
+ return new ServiceLookupResult(null, "not exported from uid "
+ + r.appInfo.uid);
+ }
Slog.w(TAG, "Permission Denial: Accessing service " + r.name
- + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
+ + " from pid=" + callingPid
+ + ", uid=" + callingUid
+ " requires " + r.permission);
return new ServiceLookupResult(null, r.permission);
}
@@ -10479,7 +10508,7 @@
|| uidRemoved) {
if (checkComponentPermission(
android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
- callingPid, callingUid, -1)
+ callingPid, callingUid, -1, true)
== PackageManager.PERMISSION_GRANTED) {
if (uidRemoved) {
final Bundle intentExtras = intent.getExtras();
@@ -11147,7 +11176,7 @@
boolean skip = false;
if (filter.requiredPermission != null) {
int perm = checkComponentPermission(filter.requiredPermission,
- r.callingPid, r.callingUid, -1);
+ r.callingPid, r.callingUid, -1, true);
if (perm != PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "Permission Denial: broadcasting "
+ r.intent.toString()
@@ -11160,7 +11189,7 @@
}
if (r.requiredPermission != null) {
int perm = checkComponentPermission(r.requiredPermission,
- filter.receiverList.pid, filter.receiverList.uid, -1);
+ filter.receiverList.pid, filter.receiverList.uid, -1, true);
if (perm != PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "Permission Denial: receiving "
+ r.intent.toString()
@@ -11426,17 +11455,26 @@
boolean skip = false;
int perm = checkComponentPermission(info.activityInfo.permission,
- r.callingPid, r.callingUid,
- info.activityInfo.exported
- ? -1 : info.activityInfo.applicationInfo.uid);
+ r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
+ info.activityInfo.exported);
if (perm != PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "Permission Denial: broadcasting "
- + r.intent.toString()
- + " from " + r.callerPackage + " (pid=" + r.callingPid
- + ", uid=" + r.callingUid + ")"
- + " requires " + info.activityInfo.permission
- + " due to receiver " + info.activityInfo.packageName
- + "/" + info.activityInfo.name);
+ if (!info.activityInfo.exported) {
+ Slog.w(TAG, "Permission Denial: broadcasting "
+ + r.intent.toString()
+ + " from " + r.callerPackage + " (pid=" + r.callingPid
+ + ", uid=" + r.callingUid + ")"
+ + " is not exported from uid " + info.activityInfo.applicationInfo.uid
+ + " due to receiver " + info.activityInfo.packageName
+ + "/" + info.activityInfo.name);
+ } else {
+ Slog.w(TAG, "Permission Denial: broadcasting "
+ + r.intent.toString()
+ + " from " + r.callerPackage + " (pid=" + r.callingPid
+ + ", uid=" + r.callingUid + ")"
+ + " requires " + info.activityInfo.permission
+ + " due to receiver " + info.activityInfo.packageName
+ + "/" + info.activityInfo.name);
+ }
skip = true;
}
if (r.callingUid != Process.SYSTEM_UID &&
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index bc00478..dd6ddd6 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2035,17 +2035,25 @@
}
final int perm = mService.checkComponentPermission(aInfo.permission, callingPid,
- callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
+ callingUid, aInfo.applicationInfo.uid, aInfo.exported);
if (perm != PackageManager.PERMISSION_GRANTED) {
if (resultRecord != null) {
sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
- String msg = "Permission Denial: starting " + intent.toString()
- + " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ")"
- + " requires " + aInfo.permission;
+ String msg;
+ if (!aInfo.exported) {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")"
+ + " not exported from uid " + aInfo.applicationInfo.uid;
+ } else {
+ msg = "Permission Denial: starting " + intent.toString()
+ + " from " + callerApp + " (pid=" + callingPid
+ + ", uid=" + callingUid + ")"
+ + " requires " + aInfo.permission;
+ }
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index e04e4c3..5b329bb 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -62,6 +62,7 @@
jmethodID checkInjectEventsPermission;
jmethodID filterTouchEvents;
jmethodID filterJumpyTouchEvents;
+ jmethodID getVirtualKeyQuietTimeMillis;
jmethodID getExcludedDeviceNames;
jmethodID getMaxEventsPerSecond;
jmethodID getPointerLayer;
@@ -159,6 +160,7 @@
int32_t* width, int32_t* height, int32_t* orientation);
virtual bool filterTouchEvents();
virtual bool filterJumpyTouchEvents();
+ virtual nsecs_t getVirtualKeyQuietTime();
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
@@ -191,6 +193,7 @@
// Cached filtering policies.
int32_t mFilterTouchEvents;
int32_t mFilterJumpyTouchEvents;
+ nsecs_t mVirtualKeyQuietTime;
// Cached throttling policy.
int32_t mMaxEventsPerSecond;
@@ -219,7 +222,7 @@
NativeInputManager::NativeInputManager(jobject callbacksObj) :
- mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
+ mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
mMaxEventsPerSecond(-1) {
JNIEnv* env = jniEnv();
@@ -355,6 +358,24 @@
return mFilterJumpyTouchEvents;
}
+nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
+ if (mVirtualKeyQuietTime < 0) {
+ JNIEnv* env = jniEnv();
+
+ jint result = env->CallIntMethod(mCallbacksObj,
+ gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
+ if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
+ result = 0;
+ }
+ if (result < 0) {
+ result = 0;
+ }
+
+ mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
+ }
+ return mVirtualKeyQuietTime;
+}
+
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
outExcludedDeviceNames.clear();
@@ -1155,6 +1176,9 @@
GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
"filterJumpyTouchEvents", "()Z");
+ GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
+ "getVirtualKeyQuietTimeMillis", "()I");
+
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
"getExcludedDeviceNames", "()[Ljava/lang/String;");
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index e5a46b9..5bcf727 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -89,13 +89,12 @@
}
private void freeMem() {
- Log.v(LOGTAG, "freeMem: calling gc/finalization...");
+ Log.v(LOGTAG, "freeMem: calling gc...");
final VMRuntime runtime = VMRuntime.getRuntime();
runtime.gcSoftReferences();
runtime.gcSoftReferences();
runtime.gcSoftReferences();
- Runtime.getRuntime().runFinalization();
Runtime.getRuntime().gc();
Runtime.getRuntime().gc();