Merge "Add support for post-decode density scaling with reuse"
diff --git a/api/current.txt b/api/current.txt
index 8b02878..2703801 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3845,6 +3845,23 @@
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
+ field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
+ field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+ field public static final java.lang.String EXTRA_PEOPLE = "android.people";
+ field public static final java.lang.String EXTRA_PICTURE = "android.picture";
+ field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
+ field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+ field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
+ field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+ field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
+ field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
+ field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
+ field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+ field public static final java.lang.String EXTRA_TEXT = "android.text";
+ field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_TITLE = "android.title";
+ field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
@@ -3859,12 +3876,14 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+ field public android.app.Notification.Action[] actions;
field public int audioStreamType;
field public android.widget.RemoteViews bigContentView;
field public android.app.PendingIntent contentIntent;
field public android.widget.RemoteViews contentView;
field public int defaults;
field public android.app.PendingIntent deleteIntent;
+ field public android.os.Bundle extras;
field public int flags;
field public android.app.PendingIntent fullScreenIntent;
field public int icon;
@@ -3882,6 +3901,18 @@
field public long when;
}
+ public static class Notification.Action implements android.os.Parcelable {
+ ctor public Notification.Action();
+ ctor public Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.app.Notification.Action clone();
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public android.app.PendingIntent actionIntent;
+ field public int icon;
+ field public java.lang.CharSequence title;
+ }
+
public static class Notification.BigPictureStyle extends android.app.Notification.Style {
ctor public Notification.BigPictureStyle();
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
@@ -3914,6 +3945,7 @@
method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence);
method public android.app.Notification.Builder setDefaults(int);
method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
+ method public android.app.Notification.Builder setExtras(android.os.Bundle);
method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
method public android.app.Notification.Builder setLights(int, int, int);
@@ -6808,6 +6840,7 @@
ctor public ComponentInfo(android.content.pm.ComponentInfo);
ctor protected ComponentInfo(android.os.Parcel);
method public final int getIconResource();
+ method public final int getLogoResource();
method public boolean isEnabled();
field public android.content.pm.ApplicationInfo applicationInfo;
field public int descriptionRes;
@@ -9858,6 +9891,7 @@
method public synchronized boolean canConstantState();
method protected void computeConstantSize();
method public int getChangingConfigurations();
+ method public final android.graphics.drawable.Drawable getChild(int);
method public final int getChildCount();
method public final android.graphics.drawable.Drawable[] getChildren();
method public final int getConstantHeight();
@@ -12057,7 +12091,6 @@
method public void start();
method public void stop();
method public void writeSampleData(int, java.nio.ByteBuffer, android.media.MediaCodec.BufferInfo);
- field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
}
public static final class MediaMuxer.OutputFormat {
@@ -12285,7 +12318,7 @@
method public void removeCallback(android.media.MediaRouter.Callback);
method public void removeUserRoute(android.media.MediaRouter.UserRouteInfo);
method public void selectRoute(int, android.media.MediaRouter.RouteInfo);
- field public static final int CALLBACK_FLAG_ACTIVE_SCAN = 1; // 0x1
+ field public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1; // 0x1
field public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 2; // 0x2
field public static final int ROUTE_TYPE_LIVE_AUDIO = 1; // 0x1
field public static final int ROUTE_TYPE_LIVE_VIDEO = 2; // 0x2
@@ -19962,6 +19995,7 @@
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS";
+ field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS";
field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS";
@@ -21550,6 +21584,7 @@
public final class SynthesisRequest {
ctor public SynthesisRequest(java.lang.String, android.os.Bundle);
+ method public int getCallerUid();
method public java.lang.String getCountry();
method public java.lang.String getLanguage();
method public android.os.Bundle getParams();
@@ -25564,6 +25599,7 @@
}
public final class MotionEvent extends android.view.InputEvent implements android.os.Parcelable {
+ method public static java.lang.String actionToString(int);
method public final void addBatch(long, float, float, float, float, int);
method public final void addBatch(long, android.view.MotionEvent.PointerCoords[], int);
method public static int axisFromString(java.lang.String);
@@ -27040,7 +27076,9 @@
method public void setFlags(int, int);
method public void setFormat(int);
method public void setGravity(int);
+ method public void setIcon(int);
method public void setLayout(int, int);
+ method public void setLogo(int);
method public void setSoftInputMode(int);
method public abstract void setTitle(java.lang.CharSequence);
method public abstract void setTitleColor(int);
@@ -28192,7 +28230,15 @@
public class Crossfade extends android.view.transition.Transition {
ctor public Crossfade();
method protected void captureValues(android.view.transition.TransitionValues, boolean);
+ method public int getFadeBehavior();
+ method public int getResizeBehavior();
method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
+ method public void setFadeBehavior(int);
+ method public void setResizeBehavior(int);
+ field public static final int FADE_BEHAVIOR_CROSSFADE = 0; // 0x0
+ field public static final int FADE_BEHAVIOR_REVEAL = 1; // 0x1
+ field public static final int RESIZE_BEHAVIOR_NONE = 0; // 0x0
+ field public static final int RESIZE_BEHAVIOR_SCALE = 1; // 0x1
}
public class Fade extends android.view.transition.Visibility {
@@ -28307,7 +28353,7 @@
public class TransitionValues {
ctor public TransitionValues();
- field public final java.util.HashMap values;
+ field public final java.util.Map values;
field public android.view.View view;
}
@@ -33145,7 +33191,7 @@
method protected final void setSigners(java.lang.Class<?>, java.lang.Object[]);
}
- public class ClassNotFoundException extends java.lang.Exception {
+ public class ClassNotFoundException extends java.lang.ReflectiveOperationException {
ctor public ClassNotFoundException();
ctor public ClassNotFoundException(java.lang.String);
ctor public ClassNotFoundException(java.lang.String, java.lang.Throwable);
@@ -33287,7 +33333,7 @@
ctor public IllegalAccessError(java.lang.String);
}
- public class IllegalAccessException extends java.lang.Exception {
+ public class IllegalAccessException extends java.lang.ReflectiveOperationException {
ctor public IllegalAccessException();
ctor public IllegalAccessException(java.lang.String);
}
@@ -33336,7 +33382,7 @@
ctor public InstantiationError(java.lang.String);
}
- public class InstantiationException extends java.lang.Exception {
+ public class InstantiationException extends java.lang.ReflectiveOperationException {
ctor public InstantiationException();
ctor public InstantiationException(java.lang.String);
}
@@ -33513,7 +33559,7 @@
ctor public NoSuchFieldError(java.lang.String);
}
- public class NoSuchFieldException extends java.lang.Exception {
+ public class NoSuchFieldException extends java.lang.ReflectiveOperationException {
ctor public NoSuchFieldException();
ctor public NoSuchFieldException(java.lang.String);
}
@@ -33523,7 +33569,7 @@
ctor public NoSuchMethodError(java.lang.String);
}
- public class NoSuchMethodException extends java.lang.Exception {
+ public class NoSuchMethodException extends java.lang.ReflectiveOperationException {
ctor public NoSuchMethodException();
ctor public NoSuchMethodException(java.lang.String);
}
@@ -33618,6 +33664,13 @@
method public abstract int read(java.nio.CharBuffer) throws java.io.IOException;
}
+ public class ReflectiveOperationException extends java.lang.Exception {
+ ctor public ReflectiveOperationException();
+ ctor public ReflectiveOperationException(java.lang.String);
+ ctor public ReflectiveOperationException(java.lang.Throwable);
+ ctor public ReflectiveOperationException(java.lang.String, java.lang.Throwable);
+ }
+
public abstract interface Runnable {
method public abstract void run();
}
@@ -34384,7 +34437,7 @@
method public abstract java.lang.Object invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) throws java.lang.Throwable;
}
- public class InvocationTargetException extends java.lang.Exception {
+ public class InvocationTargetException extends java.lang.ReflectiveOperationException {
ctor protected InvocationTargetException();
ctor public InvocationTargetException(java.lang.Throwable);
ctor public InvocationTargetException(java.lang.Throwable, java.lang.String);
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index b4a12c4..12fcdcf 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -822,7 +822,7 @@
* {@link android.Manifest.permission#USE_CREDENTIALS}.
*
* @param account The account to fetch an auth token for
- * @param authTokenType The auth token type, see {#link getAuthToken}
+ * @param authTokenType The auth token type, see {@link #getAuthToken getAuthToken()}
* @param notifyAuthFailure If true, display a notification and return null
* if authentication fails; if false, prompt and wait for the user to
* re-enter correct credentials before returning
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 58eb66f..82c2159 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -29,6 +29,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
+import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
@@ -127,6 +128,7 @@
private int mCallingUid;
private String mCallingPackage;
private boolean mDisallowAddAccounts;
+ private boolean mDontShowPicker;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -189,11 +191,23 @@
mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false);
mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
+
+ // Need to do this once here to request the window feature. Can't do it in onResume
+ mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
+ if (mAccounts.isEmpty()
+ && mDisallowAddAccounts) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.app_not_authorized);
+ mDontShowPicker = true;
+ }
}
@Override
protected void onResume() {
super.onResume();
+
+ if (mDontShowPicker) return;
+
final AccountManager accountManager = AccountManager.get(this);
mAccounts = getAcceptableAccountChoices(accountManager);
@@ -206,11 +220,6 @@
// If there are no relevant accounts and only one relevant account type go directly to
// add account. Otherwise let the user choose.
if (mAccounts.isEmpty()) {
- if (mDisallowAddAccounts) {
- setContentView(R.layout.app_not_authorized);
- setTitle(R.string.error_message_title);
- return;
- }
if (mSetOfRelevantAccountTypes.size() == 1) {
runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
} else {
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index f8ae616..e370e4a 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1024,8 +1024,10 @@
mStarted = false;
mStartListenersCalled = false;
mPlayingBackwards = false;
- Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
- System.identityHashCode(this));
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
+ System.identityHashCode(this));
+ }
}
/**
@@ -1033,8 +1035,10 @@
* called on the UI thread.
*/
private void startAnimation(AnimationHandler handler) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
- System.identityHashCode(this));
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
+ System.identityHashCode(this));
+ }
initAnimation();
handler.mAnimations.add(this);
if (mStartDelay > 0 && mListeners != null) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6b5df7f..7f2f744 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1877,9 +1877,12 @@
if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
return;
}
-
+
mActionBar = new ActionBarImpl(this);
mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
+
+ mWindow.setDefaultIcon(mActivityInfo.getIconResource());
+ mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
}
/**
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index b3d99c5..634fa30 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,6 +16,8 @@
package android.app;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import com.android.internal.app.ActionBarImpl;
import com.android.internal.policy.PolicyManager;
@@ -264,6 +266,9 @@
mDecor = mWindow.getDecorView();
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
+ final ApplicationInfo info = mContext.getApplicationInfo();
+ mWindow.setDefaultIcon(info.icon);
+ mWindow.setDefaultLogo(info.logo);
mActionBar = new ActionBarImpl(this);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fb28ae3..7a0f376 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -432,51 +432,32 @@
/**
* Additional semantic data to be carried around with this Notification.
- * @hide
*/
public Bundle extras = new Bundle();
// extras keys for Builder inputs
- /** @hide */
public static final String EXTRA_TITLE = "android.title";
- /** @hide */
public static final String EXTRA_TITLE_BIG = EXTRA_TITLE + ".big";
- /** @hide */
public static final String EXTRA_TEXT = "android.text";
- /** @hide */
public static final String EXTRA_SUB_TEXT = "android.subText";
- /** @hide */
public static final String EXTRA_INFO_TEXT = "android.infoText";
- /** @hide */
public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
- /** @hide */
public static final String EXTRA_SMALL_ICON = "android.icon";
- /** @hide */
public static final String EXTRA_LARGE_ICON = "android.largeIcon";
- /** @hide */
public static final String EXTRA_LARGE_ICON_BIG = EXTRA_LARGE_ICON + ".big";
- /** @hide */
public static final String EXTRA_PROGRESS = "android.progress";
- /** @hide */
public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
- /** @hide */
public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
- /** @hide */
public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
- /** @hide */
public static final String EXTRA_SHOW_WHEN = "android.showWhen";
- /** @hide from BigPictureStyle */
public static final String EXTRA_PICTURE = "android.picture";
- /** @hide from InboxStyle */
public static final String EXTRA_TEXT_LINES = "android.textLines";
// extras keys for other interesting pieces of information
- /** @hide */
public static final String EXTRA_PEOPLE = "android.people";
/**
* Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
- * @hide
*/
public static class Action implements Parcelable {
public int icon;
@@ -530,9 +511,6 @@
};
}
- /**
- * @hide
- */
public Action[] actions;
/**
@@ -1450,7 +1428,6 @@
* called.
*
* @see Notification#extras
- * @hide
*/
public Builder setExtras(Bundle bag) {
mExtras = bag;
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 3a355f9..f104d71 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -109,7 +109,7 @@
break;
}
case HANDLE_PROVIDERS_CHANGED: {
- onProvidersChanged(msg.arg1);
+ onProvidersChanged();
break;
}
case HANDLE_VIEW_DATA_CHANGED: {
@@ -396,14 +396,6 @@
* are added, updated or removed, or widget components are enabled or disabled.)
*/
protected void onProvidersChanged() {
- onProvidersChanged(mContext.getUserId());
- }
-
- /**
- * Private method containing a userId
- * @hide
- */
- protected void onProvidersChanged(int userId) {
// Does nothing
}
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 1166e4b..d1c7bec 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -529,9 +529,9 @@
/**
* Notifies the specified collection view in all the specified AppWidget instances
- * to invalidate their currently data.
+ * to invalidate their data.
*
- * @param appWidgetIds The AppWidget instances for which to notify of view data changes.
+ * @param appWidgetIds The AppWidget instances to notify of view data changes.
* @param viewId The collection view id.
*/
public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
@@ -544,11 +544,11 @@
}
/**
- * Notifies the specified collection view in all the specified AppWidget instance
- * to invalidate it's currently data.
+ * Notifies the specified collection view in the specified AppWidget instance
+ * to invalidate its data.
*
- * @param appWidgetId The AppWidget instance for which to notify of view data changes.
- * @param viewId The collection view id.
+ * @param appWidgetId The AppWidget instance to notify of view data changes.
+ * @param viewId The collection view id.
*/
public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 7ec73ef..79bb476 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -47,17 +47,22 @@
* device discovery, query a list of bonded (paired) devices,
* instantiate a {@link BluetoothDevice} using a known MAC address, and create
* a {@link BluetoothServerSocket} to listen for connection requests from other
- * devices.
+ * devices, and start a scan for Bluetooth LE devices.
*
* <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
- * adapter, call the static {@link #getDefaultAdapter} method.
+ * adapter, when running on JELLY_BEAN_MR1 and below, call the
+ * static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and
+ * higher, retrieve it through
+ * {@link android.content.Context#getSystemService} with
+ * {@link android.content.Context#BLUETOOTH_SERVICE}.
* Fundamentally, this is your starting point for all
* Bluetooth actions. Once you have the local adapter, you can get a set of
* {@link BluetoothDevice} objects representing all paired devices with
* {@link #getBondedDevices()}; start device discovery with
* {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to
* listen for incoming connection requests with
- * {@link #listenUsingRfcommWithServiceRecord(String,UUID)}.
+ * {@link #listenUsingRfcommWithServiceRecord(String,UUID)}; or start a scan for
+ * Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.
*
* <p class="note"><strong>Note:</strong>
* Most methods require the {@link android.Manifest.permission#BLUETOOTH}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 79a5ffe..3ee7142 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -107,7 +107,7 @@
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_CLASS}.
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
- * @see {@link BluetoothClass}
+ * {@see BluetoothClass}
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CLASS_CHANGED =
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 77e5f84..df3ec1a 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -565,6 +565,9 @@
/**
* Close this Bluetooth GATT client.
+ *
+ * Application should call this method as early as possible after it is done with
+ * this GATT client.
*/
public void close() {
if (DBG) Log.d(TAG, "close()");
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 2259c1e..80ea4a6 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -27,6 +27,7 @@
*
* @param gatt GATT client
* @param status Status of the connect or disconnect operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
* @param newState Returns the new connection state. Can be one of
* {@link BluetoothProfile#STATE_DISCONNECTED} or
* {@link BluetoothProfile#STATE_CONNECTED}
@@ -72,6 +73,7 @@
* @param characteristic Characteristic that was written to the associated
* remote device.
* @param status The result of the write operation
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
@@ -108,6 +110,7 @@
* @param descriptor Descriptor that was writte to the associated
* remote device.
* @param status The result of the write operation
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
int status) {
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index d3b85a9..58ee54f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -289,6 +289,9 @@
/**
* Close this GATT server instance.
+ *
+ * Application should call this method as early as possible after it is done with
+ * this GATT server.
*/
public void close() {
if (DBG) Log.d(TAG, "close()");
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 03a6093..897e6fe 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2269,7 +2269,7 @@
/**
* Broadcast Action: An outgoing call is about to be placed.
*
- * <p>The Intent will have the following extra value:
+ * <p>The Intent will have the following extra value:</p>
* <ul>
* <li><em>{@link android.content.Intent#EXTRA_PHONE_NUMBER}</em> -
* the phone number originally intended to be dialed.</li>
diff --git a/core/java/android/content/SyncResult.java b/core/java/android/content/SyncResult.java
index 8b0afbd..6cb0d02 100644
--- a/core/java/android/content/SyncResult.java
+++ b/core/java/android/content/SyncResult.java
@@ -56,7 +56,7 @@
/**
* Used to indicate that the SyncAdapter experienced a hard error due to an error it
- * received from interacting with the storage later. The SyncManager will record that
+ * received from interacting with the storage layer. The SyncManager will record that
* the sync request failed and it will not reschedule the request.
*/
public boolean databaseError;
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 2812477..4dbcf23 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -116,6 +116,17 @@
public final int getIconResource() {
return icon != 0 ? icon : applicationInfo.icon;
}
+
+ /**
+ * Return the logo resource identifier to use for this component. If
+ * the component defines a logo, that is used; else, the application
+ * logo is used.
+ *
+ * @return The logo associated with this component.
+ */
+ public final int getLogoResource() {
+ return logo != 0 ? logo : applicationInfo.logo;
+ }
protected void dumpFront(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 07117fe..de8e256 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -328,6 +328,7 @@
implements Comparator<ResolveInfo> {
public DisplayNameComparator(PackageManager pm) {
mPM = pm;
+ mCollator.setStrength(Collator.PRIMARY);
}
public final int compare(ResolveInfo a, ResolveInfo b) {
@@ -336,10 +337,10 @@
CharSequence sb = b.loadLabel(mPM);
if (sb == null) sb = b.activityInfo.name;
- return sCollator.compare(sa.toString(), sb.toString());
+ return mCollator.compare(sa.toString(), sb.toString());
}
- private final Collator sCollator = Collator.getInstance();
+ private final Collator mCollator = Collator.getInstance();
private PackageManager mPM;
}
}
diff --git a/core/java/android/hardware/TriggerEventListener.java b/core/java/android/hardware/TriggerEventListener.java
index 76b2796..8fa9702 100644
--- a/core/java/android/hardware/TriggerEventListener.java
+++ b/core/java/android/hardware/TriggerEventListener.java
@@ -21,15 +21,14 @@
* Trigger Sensors are sensors that trigger an event and are automatically
* disabled. {@link Sensor#TYPE_SIGNIFICANT_MOTION} is one such example.
* <p>
- * SensorManager lets you access the device's {@link android.hardware.Sensor
- * sensors}. Get an instance of this class by calling
+ * {@link SensorManager} lets you access the device's {@link android.hardware.Sensor
+ * sensors}. Get an instance of {@link SensorManager} by calling
* {@link android.content.Context#getSystemService(java.lang.String)
* Context.getSystemService()} with the argument
* {@link android.content.Context#SENSOR_SERVICE}.
- * Usage details are explained in the example below.
- * </p>
+ * <p>Here's an example setup for a TriggerEventListener:
*
- * <pre class="prettyprint">
+ * <pre>
* class TriggerListener extends TriggerEventListener {
* public void onTrigger(TriggerEvent event) {
* // Do Work.
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4881d14..7f82ce3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -381,7 +381,6 @@
if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
+ " ic=" + mInputConnection);
onUnbindInput();
- mInputStarted = false;
mInputBinding = null;
mInputConnection = null;
}
@@ -719,7 +718,7 @@
super.onDestroy();
mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
mInsetsComputer);
- finishViews();
+ doFinishInput();
if (mWindowAdded) {
// Disable exit animation for the current IME window
// to avoid the race condition between the exit and enter animations
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 476b4ea..93b1255 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -650,6 +650,12 @@
public static final native int myPid();
/**
+ * Returns the identifier of this process' parent.
+ * @hide
+ */
+ public static native int myPpid();
+
+ /**
* Returns the identifier of the calling thread, which be used with
* {@link #setThreadPriority(int, int)}.
*/
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d02a320..c1d4ae9 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -16,6 +16,8 @@
package android.os;
+import android.util.ArrayMap;
+
import java.util.HashMap;
/**
@@ -47,8 +49,8 @@
* implements the {@link #onCallbackDied} method.
*/
public class RemoteCallbackList<E extends IInterface> {
- /*package*/ HashMap<IBinder, Callback> mCallbacks
- = new HashMap<IBinder, Callback>();
+ /*package*/ ArrayMap<IBinder, Callback> mCallbacks
+ = new ArrayMap<IBinder, Callback>();
private Object[] mActiveBroadcast;
private int mBroadcastCount = -1;
private boolean mKilled = false;
@@ -159,7 +161,8 @@
*/
public void kill() {
synchronized (mCallbacks) {
- for (Callback cb : mCallbacks.values()) {
+ for (int cbi=mCallbacks.size()-1; cbi>=0; cbi--) {
+ Callback cb = mCallbacks.valueAt(cbi);
cb.mCallback.asBinder().unlinkToDeath(cb, 0);
}
mCallbacks.clear();
@@ -238,11 +241,10 @@
if (active == null || active.length < N) {
mActiveBroadcast = active = new Object[N];
}
- int i=0;
- for (Callback cb : mCallbacks.values()) {
- active[i++] = cb;
+ for (int i=0; i<N; i++) {
+ active[i] = mCallbacks.valueAt(i);
}
- return i;
+ return N;
}
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 3267939..31da091 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Printer;
import android.util.Singleton;
@@ -1069,7 +1070,7 @@
// Map from violation stacktrace hashcode -> uptimeMillis of
// last violation. No locking needed, as this is only
// accessed by the same thread.
- private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>();
+ private ArrayMap<Integer, Long> mLastViolationTime;
public AndroidBlockGuardPolicy(final int policyMask) {
mPolicyMask = policyMask;
@@ -1279,8 +1280,13 @@
// Not perfect, but fast and good enough for dup suppression.
Integer crashFingerprint = info.hashCode();
long lastViolationTime = 0;
- if (mLastViolationTime.containsKey(crashFingerprint)) {
- lastViolationTime = mLastViolationTime.get(crashFingerprint);
+ if (mLastViolationTime != null) {
+ Long vtime = mLastViolationTime.get(crashFingerprint);
+ if (vtime != null) {
+ lastViolationTime = vtime;
+ }
+ } else {
+ mLastViolationTime = new ArrayMap<Integer, Long>(1);
}
long now = SystemClock.uptimeMillis();
mLastViolationTime.put(crashFingerprint, now);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ff06df0..c1a296d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -650,7 +650,6 @@
* <p>
* Output: Nothing.
* @see android.service.dreams.DreamService
- * @hide
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index 6398d3d..917a109 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -41,6 +41,7 @@
private String mVariant;
private int mSpeechRate;
private int mPitch;
+ private int mCallerUid;
public SynthesisRequest(String text, Bundle params) {
mText = text;
@@ -98,6 +99,13 @@
}
/**
+ * Gets the request caller Uid.
+ */
+ public int getCallerUid() {
+ return mCallerUid;
+ }
+
+ /**
* Sets the locale for the request.
*/
void setLanguage(String language, String country, String variant) {
@@ -119,4 +127,11 @@
void setPitch(int pitch) {
mPitch = pitch;
}
+
+ /**
+ * Sets Caller Uid
+ */
+ void setCallerUid(int uid) {
+ mCallerUid = uid;
+ }
}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 703dcff..575855c 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -557,11 +557,13 @@
// guarded by 'this'.
private AbstractSynthesisCallback mSynthesisCallback;
private final EventLogger mEventLogger;
+ private final int mCallerUid;
public SynthesisSpeechItem(Object callerIdentity, int callerUid, int callerPid,
Bundle params, String text) {
super(callerIdentity, callerUid, callerPid, params);
mText = text;
+ mCallerUid = callerUid;
mSynthesisRequest = new SynthesisRequest(mText, mParams);
mDefaultLocale = getSettingsLocale();
setRequestParams(mSynthesisRequest);
@@ -611,7 +613,7 @@
private void setRequestParams(SynthesisRequest request) {
request.setLanguage(getLanguage(), getCountry(), getVariant());
request.setSpeechRate(getSpeechRate());
-
+ request.setCallerUid(mCallerUid);
request.setPitch(getPitch());
}
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 70f7d2e..edda779 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -206,16 +206,28 @@
}
mSize = 0;
}
+ /**
+ * Create a new ArrayMap with the mappings from the given ArrayMap.
+ */
+ public ArrayMap(ArrayMap map) {
+ this();
+ if (map != null) {
+ putAll(map);
+ }
+ }
+
/**
* Make the array map empty. All storage is released.
*/
@Override
public void clear() {
- freeArrays(mHashes, mArray, mSize);
- mHashes = SparseArray.EMPTY_INTS;
- mArray = SparseArray.EMPTY_OBJECTS;
- mSize = 0;
+ if (mSize != 0) {
+ freeArrays(mHashes, mArray, mSize);
+ mHashes = SparseArray.EMPTY_INTS;
+ mArray = SparseArray.EMPTY_OBJECTS;
+ mSize = 0;
+ }
}
/**
@@ -227,9 +239,9 @@
int[] ohashes = mHashes;
Object[] oarray = mArray;
allocArrays(minimumCapacity);
- if (mHashes.length > 0) {
- System.arraycopy(ohashes, 0, mHashes, 0, mHashes.length);
- System.arraycopy(oarray, 0, mArray, 0, mArray.length);
+ if (mSize > 0) {
+ System.arraycopy(ohashes, 0, mHashes, 0, mSize);
+ System.arraycopy(oarray, 0, mArray, 0, mSize<<1);
}
freeArrays(ohashes, oarray, mSize);
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8dada90..c07b187 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1931,11 +1931,13 @@
IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
try {
- GraphicBuffer buffer = atlas.getBuffer();
- if (buffer != null) {
- int[] map = atlas.getMap();
- if (map != null) {
- GLES20Canvas.initAtlas(buffer, map);
+ if (atlas.isCompatible(android.os.Process.myPpid())) {
+ GraphicBuffer buffer = atlas.getBuffer();
+ if (buffer != null) {
+ int[] map = atlas.getMap();
+ if (map != null) {
+ GLES20Canvas.initAtlas(buffer, map);
+ }
}
}
} catch (RemoteException e) {
diff --git a/core/java/android/view/IAssetAtlas.aidl b/core/java/android/view/IAssetAtlas.aidl
index 2595179..5f1e238 100644
--- a/core/java/android/view/IAssetAtlas.aidl
+++ b/core/java/android/view/IAssetAtlas.aidl
@@ -28,6 +28,13 @@
*/
interface IAssetAtlas {
/**
+ * Indicates whether the atlas is compatible with the specified
+ * parent process id. If the atlas' ppid does not match, this
+ * method will return false.
+ */
+ boolean isCompatible(int ppid);
+
+ /**
* Returns the atlas buffer (texture) or null if the atlas is
* not available yet.
*/
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 8007d9a..ad3082e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -97,7 +97,7 @@
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
- int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
+ int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
void setAppWillBeHidden(IBinder token);
void setAppVisibility(IBinder token, boolean visible);
void startAppFreezingScreen(IBinder token, int configChanges);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ee36097..db577f3 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -3003,13 +3003,13 @@
}
/**
- * Returns a string that represents the symbolic name of the specified action
+ * Returns a string that represents the symbolic name of the specified unmasked action
* such as "ACTION_DOWN", "ACTION_POINTER_DOWN(3)" or an equivalent numeric constant
* such as "35" if unknown.
*
- * @param action The action.
+ * @param action The unmasked action.
* @return The symbolic name of the specified action.
- * @hide
+ * @see #getAction()
*/
public static String actionToString(int action) {
switch (action) {
@@ -3047,7 +3047,7 @@
* Returns a string that represents the symbolic name of the specified axis
* such as "AXIS_X" or an equivalent numeric constant such as "42" if unknown.
*
- * @param axis The axis
+ * @param axis The axis.
* @return The symbolic name of the specified axis.
*/
public static String axisToString(int axis) {
@@ -3061,7 +3061,7 @@
*
* @param symbolicName The symbolic name of the axis.
* @return The axis or -1 if not found.
- * @see KeyEvent#keycodeToString(int)
+ * @see KeyEvent#keyCodeToString(int)
*/
public static int axisFromString(String symbolicName) {
if (symbolicName == null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d1fa455..970d041 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4575,11 +4575,8 @@
}
boolean rootViewRequestFocus() {
- View root = getRootView();
- if (root != null) {
- return root.requestFocus();
- }
- return false;
+ final View root = getRootView();
+ return root != null && root.requestFocus();
}
/**
@@ -12413,8 +12410,8 @@
/**
* <p>Specifies the type of layer backing this view. The layer can be
- * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
- * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
+ * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
+ * {@link #LAYER_TYPE_HARDWARE}.</p>
*
* <p>A layer is associated with an optional {@link android.graphics.Paint}
* instance that controls how the layer is composed on screen. The following
@@ -12835,8 +12832,7 @@
mRecreateDisplayList = true;
}
if (displayList == null) {
- final String name = getClass().getSimpleName();
- displayList = mAttachInfo.mHardwareRenderer.createDisplayList(name);
+ displayList = mAttachInfo.mHardwareRenderer.createDisplayList(getClass().getName());
// If we're creating a new display list, make sure our parent gets invalidated
// since they will need to recreate their display list to account for this
// new child display list.
@@ -13483,7 +13479,8 @@
onAnimationStart();
}
- boolean more = a.getTransformation(drawingTime, parent.mChildTransformation, 1f);
+ final Transformation t = parent.getChildTransformation();
+ boolean more = a.getTransformation(drawingTime, t, 1f);
if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
if (parent.mInvalidationTransformation == null) {
parent.mInvalidationTransformation = new Transformation();
@@ -13491,7 +13488,7 @@
invalidationTransform = parent.mInvalidationTransformation;
a.getTransformation(drawingTime, invalidationTransform, 1f);
} else {
- invalidationTransform = parent.mChildTransformation;
+ invalidationTransform = t;
}
if (more) {
@@ -13544,17 +13541,15 @@
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
ViewGroup parentVG = (ViewGroup) mParent;
- final boolean hasTransform =
- parentVG.getChildStaticTransformation(this, parentVG.mChildTransformation);
- if (hasTransform) {
- Transformation transform = parentVG.mChildTransformation;
- final int transformType = parentVG.mChildTransformation.getTransformationType();
+ final Transformation t = parentVG.getChildTransformation();
+ if (parentVG.getChildStaticTransformation(this, t)) {
+ final int transformType = t.getTransformationType();
if (transformType != Transformation.TYPE_IDENTITY) {
if ((transformType & Transformation.TYPE_ALPHA) != 0) {
- alpha = transform.getAlpha();
+ alpha = t.getAlpha();
}
if ((transformType & Transformation.TYPE_MATRIX) != 0) {
- displayList.setMatrix(transform.getMatrix());
+ displayList.setMatrix(t.getMatrix());
}
}
}
@@ -13599,7 +13594,7 @@
final int flags = parent.mGroupFlags;
if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
- parent.mChildTransformation.clear();
+ parent.getChildTransformation().clear();
parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
}
@@ -13627,7 +13622,7 @@
if (concatMatrix) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
- transformToApply = parent.mChildTransformation;
+ transformToApply = parent.getChildTransformation();
} else {
if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) ==
PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mDisplayList != null) {
@@ -13637,12 +13632,11 @@
}
if (!useDisplayListProperties &&
(flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
- final boolean hasTransform =
- parent.getChildStaticTransformation(this, parent.mChildTransformation);
+ final Transformation t = parent.getChildTransformation();
+ final boolean hasTransform = parent.getChildStaticTransformation(this, t);
if (hasTransform) {
- final int transformType = parent.mChildTransformation.getTransformationType();
- transformToApply = transformType != Transformation.TYPE_IDENTITY ?
- parent.mChildTransformation : null;
+ final int transformType = t.getTransformationType();
+ transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b0fbe84..119ba72 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -128,7 +128,7 @@
* A Transformation used when drawing children, to
* apply on the child being drawn.
*/
- final Transformation mChildTransformation = new Transformation();
+ private Transformation mChildTransformation;
/**
* Used to track the current invalidation region.
@@ -3211,6 +3211,13 @@
return false;
}
+ Transformation getChildTransformation() {
+ if (mChildTransformation == null) {
+ mChildTransformation = new Transformation();
+ }
+ return mChildTransformation;
+ }
+
/**
* {@hide}
*/
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 5510939..2d86bfe 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -15,6 +15,7 @@
*/
package android.view;
+import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -169,6 +170,14 @@
child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
}
parent.removeView(child);
+ if (parent.getLayoutTransition() != null) {
+ // LayoutTransition will cause the child to delay removal - cancel it
+ parent.getLayoutTransition().cancel(LayoutTransition.DISAPPEARING);
+ }
+ // fail-safe if view is still attached for any reason
+ if (child.getParent() != null) {
+ child.mParent = null;
+ }
}
super.addView(child);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bcc58a2..62e0d3d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5153,6 +5153,7 @@
mAdded = false;
}
+ WindowManagerGlobal.getInstance().doRemoveView(this);
}
public void requestUpdateConfiguration(Configuration config) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 06974d3..39d48a7 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1256,4 +1256,38 @@
* @param mask Flags specifying which options should be modified. Others will remain unchanged.
*/
public void setUiOptions(int uiOptions, int mask) { }
+
+ /**
+ * Set the primary icon for this window.
+ *
+ * @param resId resource ID of a drawable to set
+ */
+ public void setIcon(int resId) { }
+
+ /**
+ * Set the default icon for this window.
+ * This will be overridden by any other icon set operation which could come from the
+ * theme or another explicit set.
+ *
+ * @hide
+ */
+ public void setDefaultIcon(int resId) { }
+
+ /**
+ * Set the logo for this window. A logo is often shown in place of an
+ * {@link #setIcon(int) icon} but is generally wider and communicates window title information
+ * as well.
+ *
+ * @param resId resource ID of a drawable to set
+ */
+ public void setLogo(int resId) { }
+
+ /**
+ * Set the default logo for this window.
+ * This will be overridden by any other logo set operation which could come from the
+ * theme or another explicit set.
+ *
+ * @hide
+ */
+ public void setDefaultLogo(int resId) { }
}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 0ff46e9..6bcf863 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -22,7 +22,6 @@
import android.content.res.Configuration;
import android.opengl.ManagedEGLContext;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -33,6 +32,7 @@
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintWriter;
+import java.util.ArrayList;
/**
* Provides low-level communication with the system window manager for
@@ -107,9 +107,10 @@
private final Object mLock = new Object();
- private View[] mViews;
- private ViewRootImpl[] mRoots;
- private WindowManager.LayoutParams[] mParams;
+ private final ArrayList<View> mViews = new ArrayList<View>();
+ private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
+ private final ArrayList<WindowManager.LayoutParams> mParams =
+ new ArrayList<WindowManager.LayoutParams>();
private boolean mNeedsEglTerminate;
private Runnable mSystemPropertyUpdater;
@@ -162,11 +163,10 @@
public String[] getViewRootNames() {
synchronized (mLock) {
- if (mRoots == null) return new String[0];
- String[] mViewRoots = new String[mRoots.length];
- int i = 0;
- for (ViewRootImpl root : mRoots) {
- mViewRoots[i++] = getWindowName(root);
+ final int numRoots = mRoots.size();
+ String[] mViewRoots = new String[numRoots];
+ for (int i = 0; i < numRoots; ++i) {
+ mViewRoots[i] = getWindowName(mRoots.get(i));
}
return mViewRoots;
}
@@ -174,8 +174,8 @@
public View getRootView(String name) {
synchronized (mLock) {
- if (mRoots == null) return null;
- for (ViewRootImpl root : mRoots) {
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ final ViewRootImpl root = mRoots.get(i);
if (name.equals(getWindowName(root))) return root.getView();
}
}
@@ -209,8 +209,8 @@
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
- for (ViewRootImpl viewRoot : mRoots) {
- viewRoot.loadSystemProperties();
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ mRoots.get(i).loadSystemProperties();
}
}
}
@@ -228,10 +228,10 @@
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
- final int count = mViews != null ? mViews.length : 0;
- for (int i=0; i<count; i++) {
- if (mRoots[i].mWindow.asBinder() == wparams.token) {
- panelParentView = mViews[i];
+ final int count = mViews.size();
+ for (int i = 0; i < count; i++) {
+ if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
+ panelParentView = mViews.get(i);
}
}
}
@@ -240,28 +240,9 @@
view.setLayoutParams(wparams);
- if (mViews == null) {
- index = 1;
- mViews = new View[1];
- mRoots = new ViewRootImpl[1];
- mParams = new WindowManager.LayoutParams[1];
- } else {
- index = mViews.length + 1;
- Object[] old = mViews;
- mViews = new View[index];
- System.arraycopy(old, 0, mViews, 0, index-1);
- old = mRoots;
- mRoots = new ViewRootImpl[index];
- System.arraycopy(old, 0, mRoots, 0, index-1);
- old = mParams;
- mParams = new WindowManager.LayoutParams[index];
- System.arraycopy(old, 0, mParams, 0, index-1);
- }
- index--;
-
- mViews[index] = view;
- mRoots[index] = root;
- mParams[index] = wparams;
+ mViews.add(view);
+ mRoots.add(root);
+ mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
@@ -293,8 +274,9 @@
synchronized (mLock) {
int index = findViewLocked(view, true);
- ViewRootImpl root = mRoots[index];
- mParams[index] = wparams;
+ ViewRootImpl root = mRoots.get(index);
+ mParams.remove(index);
+ mParams.add(index, wparams);
root.setLayoutParams(wparams, false);
}
}
@@ -306,7 +288,8 @@
synchronized (mLock) {
int index = findViewLocked(view, true);
- View curView = removeViewLocked(index, immediate);
+ View curView = mRoots.get(index).getView();
+ removeViewLocked(index, immediate);
if (curView == view) {
return;
}
@@ -318,16 +301,13 @@
public void closeAll(IBinder token, String who, String what) {
synchronized (mLock) {
- if (mViews == null)
- return;
-
- int count = mViews.length;
+ int count = mViews.size();
//Log.i("foo", "Closing all windows of " + token);
- for (int i=0; i<count; i++) {
+ for (int i = 0; i < count; i++) {
//Log.i("foo", "@ " + i + " token " + mParams[i].token
// + " view " + mRoots[i].getView());
- if (token == null || mParams[i].token == token) {
- ViewRootImpl root = mRoots[i];
+ if (token == null || mParams.get(i).token == token) {
+ ViewRootImpl root = mRoots.get(i);
//Log.i("foo", "Force closing " + root);
if (who != null) {
@@ -335,77 +315,50 @@
what + " " + who + " has leaked window "
+ root.getView() + " that was originally added here");
leak.setStackTrace(root.getLocation().getStackTrace());
- Log.e(TAG, leak.getMessage(), leak);
+ Log.e(TAG, "", leak);
}
removeViewLocked(i, false);
- i--;
- count--;
}
}
}
}
- private View removeViewLocked(int index, boolean immediate) {
- ViewRootImpl root = mRoots[index];
+ private void removeViewLocked(int index, boolean immediate) {
+ ViewRootImpl root = mRoots.get(index);
View view = root.getView();
if (view != null) {
InputMethodManager imm = InputMethodManager.getInstance();
if (imm != null) {
- imm.windowDismissed(mViews[index].getWindowToken());
+ imm.windowDismissed(mViews.get(index).getWindowToken());
}
}
root.die(immediate);
-
- final int count = mViews.length;
-
- // remove it from the list
- View[] tmpViews = new View[count-1];
- removeItem(tmpViews, mViews, index);
- mViews = tmpViews;
-
- ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1];
- removeItem(tmpRoots, mRoots, index);
- mRoots = tmpRoots;
-
- WindowManager.LayoutParams[] tmpParams
- = new WindowManager.LayoutParams[count-1];
- removeItem(tmpParams, mParams, index);
- mParams = tmpParams;
-
- if (view != null) {
- view.assignParent(null);
- // func doesn't allow null... does it matter if we clear them?
- //view.setLayoutParams(null);
- }
- return view;
}
- private static void removeItem(Object[] dst, Object[] src, int index) {
- if (dst.length > 0) {
- if (index > 0) {
- System.arraycopy(src, 0, dst, 0, index);
+ void doRemoveView(ViewRootImpl root) {
+ synchronized (mLock) {
+ final View view = root.getView();
+ if (view != null) {
+ view.assignParent(null);
}
- if (index < dst.length) {
- System.arraycopy(src, index+1, dst, index, src.length-index-1);
+
+ final int index = mRoots.indexOf(root);
+ if (index >= 0) {
+ mRoots.remove(index);
+ mViews.remove(index);
+ mParams.remove(index);
}
}
}
private int findViewLocked(View view, boolean required) {
- if (mViews != null) {
- final int count = mViews.length;
- for (int i = 0; i < count; i++) {
- if (mViews[i] == view) {
- return i;
- }
- }
+ final int index = mViews.indexOf(view);
+ if (required && index < 0) {
+ throw new IllegalArgumentException("View=" + view + " not attached to window manager");
}
- if (required) {
- throw new IllegalArgumentException("View not attached to window manager");
- }
- return -1;
+ return index;
}
public void startTrimMemory(int level) {
@@ -418,10 +371,8 @@
// Destroy all hardware surfaces and resources associated to
// known windows
synchronized (mLock) {
- if (mViews == null) return;
- int count = mViews.length;
- for (int i = 0; i < count; i++) {
- mRoots[i].terminateHardwareResources();
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ mRoots.get(i).terminateHardwareResources();
}
}
// Force a full memory flush
@@ -445,10 +396,8 @@
public void trimLocalMemory() {
synchronized (mLock) {
- if (mViews == null) return;
- int count = mViews.length;
- for (int i = 0; i < count; i++) {
- mRoots[i].destroyHardwareLayers();
+ for (int i = mRoots.size() - 1; i >= 0; --i) {
+ mRoots.get(i).destroyHardwareLayers();
}
}
}
@@ -458,51 +407,49 @@
PrintWriter pw = new PrintWriter(fout);
try {
synchronized (mLock) {
- if (mViews != null) {
- final int count = mViews.length;
+ final int count = mViews.size();
- pw.println("Profile data in ms:");
+ pw.println("Profile data in ms:");
- for (int i = 0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- String name = getWindowName(root);
- pw.printf("\n\t%s", name);
+ for (int i = 0; i < count; i++) {
+ ViewRootImpl root = mRoots.get(i);
+ String name = getWindowName(root);
+ pw.printf("\n\t%s", name);
- HardwareRenderer renderer =
- root.getView().mAttachInfo.mHardwareRenderer;
- if (renderer != null) {
- renderer.dumpGfxInfo(pw);
- }
+ HardwareRenderer renderer =
+ root.getView().mAttachInfo.mHardwareRenderer;
+ if (renderer != null) {
+ renderer.dumpGfxInfo(pw);
}
-
- pw.println("\nView hierarchy:\n");
-
- int viewsCount = 0;
- int displayListsSize = 0;
- int[] info = new int[2];
-
- for (int i = 0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- root.dumpGfxInfo(info);
-
- String name = getWindowName(root);
- pw.printf(" %s\n %d views, %.2f kB of display lists",
- name, info[0], info[1] / 1024.0f);
- HardwareRenderer renderer =
- root.getView().mAttachInfo.mHardwareRenderer;
- if (renderer != null) {
- pw.printf(", %d frames rendered", renderer.getFrameCount());
- }
- pw.printf("\n\n");
-
- viewsCount += info[0];
- displayListsSize += info[1];
- }
-
- pw.printf("\nTotal ViewRootImpl: %d\n", count);
- pw.printf("Total Views: %d\n", viewsCount);
- pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f);
}
+
+ pw.println("\nView hierarchy:\n");
+
+ int viewsCount = 0;
+ int displayListsSize = 0;
+ int[] info = new int[2];
+
+ for (int i = 0; i < count; i++) {
+ ViewRootImpl root = mRoots.get(i);
+ root.dumpGfxInfo(info);
+
+ String name = getWindowName(root);
+ pw.printf(" %s\n %d views, %.2f kB of display lists",
+ name, info[0], info[1] / 1024.0f);
+ HardwareRenderer renderer =
+ root.getView().mAttachInfo.mHardwareRenderer;
+ if (renderer != null) {
+ pw.printf(", %d frames rendered", renderer.getFrameCount());
+ }
+ pw.printf("\n\n");
+
+ viewsCount += info[0];
+ displayListsSize += info[1];
+ }
+
+ pw.printf("\nTotal ViewRootImpl: %d\n", count);
+ pw.printf("Total Views: %d\n", viewsCount);
+ pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f);
}
} finally {
pw.flush();
@@ -516,13 +463,11 @@
public void setStoppedState(IBinder token, boolean stopped) {
synchronized (mLock) {
- if (mViews != null) {
- int count = mViews.length;
- for (int i=0; i < count; i++) {
- if (token == null || mParams[i].token == token) {
- ViewRootImpl root = mRoots[i];
- root.setStopped(stopped);
- }
+ int count = mViews.size();
+ for (int i = 0; i < count; i++) {
+ if (token == null || mParams.get(i).token == token) {
+ ViewRootImpl root = mRoots.get(i);
+ root.setStopped(stopped);
}
}
}
@@ -530,13 +475,11 @@
public void reportNewConfiguration(Configuration config) {
synchronized (mLock) {
- if (mViews != null) {
- int count = mViews.length;
- config = new Configuration(config);
- for (int i=0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- root.requestUpdateConfiguration(config);
- }
+ int count = mViews.size();
+ config = new Configuration(config);
+ for (int i=0; i < count; i++) {
+ ViewRootImpl root = mRoots.get(i);
+ root.requestUpdateConfiguration(config);
}
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 6a35f20..6291e62 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -642,7 +642,7 @@
*/
public View addStartingWindow(IBinder appToken, String packageName,
int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel,
- int labelRes, int icon, int windowFlags);
+ int labelRes, int icon, int logo, int windowFlags);
/**
* Called when the first window of an application has been displayed, while
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index b3ff54d..f730cf7 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -42,7 +42,8 @@
* Base class for implementors of the InputConnection interface, taking care
* of most of the common behavior for providing a connection to an Editable.
* Implementors of this class will want to be sure to implement
- * {@link #getEditable} to provide access to their own editable object.
+ * {@link #getEditable} to provide access to their own editable object, and
+ * to refer to the documentation in {@link InputConnection}.
*/
public class BaseInputConnection implements InputConnection {
private static final boolean DEBUG = false;
diff --git a/core/java/android/view/inputmethod/CompletionInfo.java b/core/java/android/view/inputmethod/CompletionInfo.java
index 3591cb1..70b8059 100644
--- a/core/java/android/view/inputmethod/CompletionInfo.java
+++ b/core/java/android/view/inputmethod/CompletionInfo.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2007-2008 The Android Open Source Project
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -23,6 +23,30 @@
/**
* Information about a single text completion that an editor has reported to
* an input method.
+ *
+ * <p>This class encapsulates a completion offered by an application
+ * that wants it to be presented to the user by the IME. Usually, apps
+ * present their completions directly in a scrolling list for example
+ * (UI developers will usually use or extend
+ * {@see android.widget.AutoCompleteTextView} to implement this).
+ * However, in some cases, the editor may not be visible, as in the
+ * case in extract mode where the IME has taken over the full
+ * screen. In this case, the editor can choose to send their
+ * completions to the IME for display.
+ *
+ * <p>Most applications who want to send completions to an IME should use
+ * {@link android.widget.AutoCompleteTextView} as this class makes this
+ * process easy. In this case, the application would not have to deal directly
+ * with this class.
+ *
+ * <p>An application who implements its own editor and wants direct control
+ * over this would create an array of CompletionInfo objects, and send it to the IME using
+ * {@link InputMethodManager#displayCompletions(View, CompletionInfo[])}.
+ * The IME would present the completions however they see fit, and
+ * call back to the editor through
+ * {@link InputConnection#commitCompletion(CompletionInfo)}.
+ * The application can then pick up the commit event by overriding
+ * {@link android.widget.TextView#onCommitCompletion(CompletionInfo)}.
*/
public final class CompletionInfo implements Parcelable {
private final long mId;
@@ -32,6 +56,12 @@
/**
* Create a simple completion with just text, no label.
+ *
+ * @param id An id that get passed as is (to the editor's discretion)
+ * @param index An index that get passed as is. Typically this is the
+ * index in the list of completions inside the editor.
+ * @param text The text that should be inserted into the editor when
+ * this completion is chosen.
*/
public CompletionInfo(long id, int index, CharSequence text) {
mId = id;
@@ -41,7 +71,18 @@
}
/**
- * Create a full completion with both text and label.
+ * Create a full completion with both text and label. The text is
+ * what will get inserted into the editor, while the label is what
+ * the IME should display. If they are the same, use the version
+ * of the constructor without a `label' argument.
+ *
+ * @param id An id that get passed as is (to the editor's discretion)
+ * @param index An index that get passed as is. Typically this is the
+ * index in the list of completions inside the editor.
+ * @param text The text that should be inserted into the editor when
+ * this completion is chosen.
+ * @param label The text that the IME should be showing among the
+ * completions list.
*/
public CompletionInfo(long id, int index, CharSequence text, CharSequence label) {
mId = id;
@@ -56,7 +97,7 @@
mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
}
-
+
/**
* Return the abstract identifier for this completion, typically
* corresponding to the id associated with it in the original adapter.
@@ -64,7 +105,7 @@
public long getId() {
return mId;
}
-
+
/**
* Return the original position of this completion, typically
* corresponding to its position in the original adapter.
@@ -72,7 +113,7 @@
public int getPosition() {
return mPosition;
}
-
+
/**
* Return the actual text associated with this completion. This is the
* real text that will be inserted into the editor if the user selects it.
@@ -80,7 +121,7 @@
public CharSequence getText() {
return mText;
}
-
+
/**
* Return the user-visible label for the completion, or null if the plain
* text should be shown. If non-null, this will be what the user sees as
@@ -89,7 +130,7 @@
public CharSequence getLabel() {
return mLabel;
}
-
+
@Override
public String toString() {
return "CompletionInfo{#" + mPosition + " \"" + mText
diff --git a/core/java/android/view/inputmethod/ExtractedText.java b/core/java/android/view/inputmethod/ExtractedText.java
index 3b2508c..0c5d9e9 100644
--- a/core/java/android/view/inputmethod/ExtractedText.java
+++ b/core/java/android/view/inputmethod/ExtractedText.java
@@ -22,6 +22,9 @@
/**
* Information about text that has been extracted for use by an input method.
+ *
+ * This contains information about a portion of the currently edited text,
+ * that the IME should display into its own interface while in extracted mode.
*/
public class ExtractedText implements Parcelable {
/**
@@ -33,7 +36,7 @@
* The offset in the overall text at which the extracted text starts.
*/
public int startOffset;
-
+
/**
* If the content is a report of a partial text change, this is the
* offset where the change starts and it runs until
@@ -41,7 +44,7 @@
* field is -1.
*/
public int partialStartOffset;
-
+
/**
* If the content is a report of a partial text change, this is the offset
* where the change ends. Note that the actual text may be larger or
@@ -49,40 +52,43 @@
* meaning a reduction or increase, respectively, in the total text.
*/
public int partialEndOffset;
-
+
/**
* The offset where the selection currently starts within the extracted
* text. The real selection start position is at
* <var>startOffset</var>+<var>selectionStart</var>.
*/
public int selectionStart;
-
+
/**
* The offset where the selection currently ends within the extracted
* text. The real selection end position is at
* <var>startOffset</var>+<var>selectionEnd</var>.
*/
public int selectionEnd;
-
+
/**
* Bit for {@link #flags}: set if the text being edited can only be on
* a single line.
*/
public static final int FLAG_SINGLE_LINE = 0x0001;
-
+
/**
* Bit for {@link #flags}: set if the editor is currently in selection mode.
+ *
+ * This happens when a hardware keyboard with latched keys is attached and
+ * the shift key is currently latched.
*/
public static final int FLAG_SELECTING = 0x0002;
-
+
/**
* Additional bit flags of information about the edited text.
*/
public int flags;
-
+
/**
* Used to package this object into a {@link Parcel}.
- *
+ *
* @param dest The {@link Parcel} to be written.
* @param flags The flags used for parceling.
*/
@@ -99,7 +105,8 @@
/**
* Used to make this class parcelable.
*/
- public static final Parcelable.Creator<ExtractedText> CREATOR = new Parcelable.Creator<ExtractedText>() {
+ public static final Parcelable.Creator<ExtractedText> CREATOR
+ = new Parcelable.Creator<ExtractedText>() {
public ExtractedText createFromParcel(Parcel source) {
ExtractedText res = new ExtractedText();
res.text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 76c6d19..e7d84c2 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2007-2008 The Android Open Source Project
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -22,60 +22,167 @@
/**
* The InputConnection interface is the communication channel from an
- * {@link InputMethod} back to the application that is receiving its input. It
- * is used to perform such things as reading text around the cursor,
- * committing text to the text box, and sending raw key events to the application.
- *
- * <p>Applications should never directly implement this interface, but instead
- * subclass from {@link BaseInputConnection}. This will ensure that the
- * application does not break when new methods are added to the interface.
+ * {@link InputMethod} back to the application that is receiving its
+ * input. It is used to perform such things as reading text around the
+ * cursor, committing text to the text box, and sending raw key events
+ * to the application.
+ *
+ * <p>Applications should never directly implement this interface, but
+ * instead subclass from {@link BaseInputConnection}. This will ensure
+ * that the application does not break when new methods are added to
+ * the interface.</p>
+ *
+ * <h3>Implementing an IME or an editor</h3>
+ * <p>Text input is the result of the synergy of two essential components:
+ * an Input Method Engine (IME) and an editor. The IME can be a
+ * software keyboard, a handwriting interface, an emoji palette, a
+ * speech-to-text engine, and so on. There are typically several IMEs
+ * installed on any given Android device. In Android, IMEs extend
+ * {@link android.inputmethodservice.InputMethodService}.
+ * For more information about how to create an IME, see the
+ * <a href="{@docRoot}guide/topics/text/creating-input-method.html">
+ * Creating an input method</a> guide.
+ *
+ * The editor is the component that receives text and displays it.
+ * Typically, this is an {@link android.widget.EditText} instance, but
+ * some applications may choose to implement their own editor for
+ * various reasons. This is a large and complicated task, and an
+ * application that does this needs to make sure the behavior is
+ * consistent with standard EditText behavior in Android. An editor
+ * needs to interact with the IME, receiving commands through
+ * this InputConnection interface, and sending commands through
+ * {@link android.view.inputmethod.InputMethodManager}. An editor
+ * should start by implementing
+ * {@link android.view.View#onCreateInputConnection(EditorInfo)}
+ * to return its own input connection.</p>
+ *
+ * <p>If you are implementing your own IME, you will need to call the
+ * methods in this interface to interact with the application. Be sure
+ * to test your IME with a wide range of applications, including
+ * browsers and rich text editors, as some may have peculiarities you
+ * need to deal with. Remember your IME may not be the only source of
+ * changes on the text, and try to be as conservative as possible in
+ * the data you send and as liberal as possible in the data you
+ * receive.</p>
+ *
+ * <p>If you are implementing your own editor, you will probably need
+ * to provide your own subclass of {@link BaseInputConnection} to
+ * answer to the commands from IMEs. Please be sure to test your
+ * editor with as many IMEs as you can as their behavior can vary a
+ * lot. Also be sure to test with various languages, including CJK
+ * languages and right-to-left languages like Arabic, as these may
+ * have different input requirements. When in doubt about the
+ * behavior you should adopt for a particular call, please mimic the
+ * default TextView implementation in the latest Android version, and
+ * if you decide to drift from it, please consider carefully that
+ * inconsistencies in text edition behavior is almost universally felt
+ * as a bad thing by users.</p>
+ *
+ * <h3>Cursors, selections and compositions</h3>
+ * <p>In Android, the cursor and the selection are one and the same
+ * thing. A "cursor" is just the special case of a zero-sized
+ * selection. As such, this documentation uses them
+ * interchangeably. Any method acting "before the cursor" would act
+ * before the start of the selection if there is one, and any method
+ * acting "after the cursor" would act after the end of the
+ * selection.</p>
+ *
+ * <p>An editor needs to be able to keep track of a currently
+ * "composing" region, like the standard edition widgets do. The
+ * composition is marked in a specific style: see
+ * {@link android.text.Spanned#SPAN_COMPOSING}. IMEs use this to help
+ * the user keep track of what part of the text they are currently
+ * focusing on, and interact with the editor using
+ * {@link InputConnection#setComposingText(CharSequence, int)},
+ * {@link InputConnection#setComposingRegion(int, int)} and
+ * {@link InputConnection#finishComposingText()}.
+ * The composing region and the selection are completely independent
+ * of each other, and the IME may use them however they see fit.</p>
*/
public interface InputConnection {
/**
* Flag for use with {@link #getTextAfterCursor} and
- * {@link #getTextBeforeCursor} to have style information returned along
- * with the text. If not set, you will receive only the raw text. If
- * set, you may receive a complex CharSequence of both text and style
- * spans.
+ * {@link #getTextBeforeCursor} to have style information returned
+ * along with the text. If not set, {@link #getTextAfterCursor}
+ * sends only the raw text, without style or other spans. If set,
+ * it may return a complex CharSequence of both text and style
+ * spans. <strong>Editor authors</strong>: you should strive to
+ * send text with styles if possible, but it is not required.
*/
static final int GET_TEXT_WITH_STYLES = 0x0001;
-
+
/**
- * Flag for use with {@link #getExtractedText} to indicate you would
- * like to receive updates when the extracted text changes.
+ * Flag for use with {@link #getExtractedText} to indicate you
+ * would like to receive updates when the extracted text changes.
*/
public static final int GET_EXTRACTED_TEXT_MONITOR = 0x0001;
-
+
/**
- * Get <var>n</var> characters of text before the current cursor position.
- *
- * <p>This method may fail either if the input connection has become invalid
- * (such as its process crashing) or the client is taking too long to
- * respond with the text (it is given a couple seconds to return).
- * In either case, a null is returned.
- *
+ * Get <var>n</var> characters of text before the current cursor
+ * position.
+ *
+ * <p>This method may fail either if the input connection has
+ * become invalid (such as its process crashing) or the editor is
+ * taking too long to respond with the text (it is given a couple
+ * seconds to return). In either case, null is returned. This
+ * method does not affect the text in the editor in any way, nor
+ * does it affect the selection or composing spans.</p>
+ *
+ * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
+ * editor should return a {@link android.text.SpannableString}
+ * with all the spans set on the text.</p>
+ *
+ * <p><strong>IME authors:</strong> please consider this will
+ * trigger an IPC round-trip that will take some time. Assume this
+ * method consumes a lot of time. Also, please keep in mind the
+ * Editor may choose to return less characters than requested even
+ * if they are available for performance reasons.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful of race
+ * conditions in implementing this call. An IME can make a change
+ * to the text and use this method right away; you need to make
+ * sure the returned value is consistent with the result of the
+ * latest edits.
+ *
* @param n The expected length of the text.
* @param flags Supplies additional options controlling how the text is
- * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
- *
- * @return Returns the text before the cursor position; the length of the
+ * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+ * @return the text before the cursor position; the length of the
* returned text might be less than <var>n</var>.
*/
public CharSequence getTextBeforeCursor(int n, int flags);
/**
- * Get <var>n</var> characters of text after the current cursor position.
- *
- * <p>This method may fail either if the input connection has become invalid
- * (such as its process crashing) or the client is taking too long to
- * respond with the text (it is given a couple seconds to return).
- * In either case, a null is returned.
- *
+ * Get <var>n</var> characters of text after the current cursor
+ * position.
+ *
+ * <p>This method may fail either if the input connection has
+ * become invalid (such as its process crashing) or the client is
+ * taking too long to respond with the text (it is given a couple
+ * seconds to return). In either case, null is returned.
+ *
+ * <p>This method does not affect the text in the editor in any
+ * way, nor does it affect the selection or composing spans.</p>
+ *
+ * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
+ * editor should return a {@link android.text.SpannableString}
+ * with all the spans set on the text.</p>
+ *
+ * <p><strong>IME authors:</strong> please consider this will
+ * trigger an IPC round-trip that will take some time. Assume this
+ * method consumes a lot of time.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful of race
+ * conditions in implementing this call. An IME can make a change
+ * to the text and use this method right away; you need to make
+ * sure the returned value is consistent with the result of the
+ * latest edits.</p>
+ *
* @param n The expected length of the text.
* @param flags Supplies additional options controlling how the text is
- * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
- *
- * @return Returns the text after the cursor position; the length of the
+ * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+ *
+ * @return the text after the cursor position; the length of the
* returned text might be less than <var>n</var>.
*/
public CharSequence getTextAfterCursor(int n, int flags);
@@ -83,139 +190,287 @@
/**
* Gets the selected text, if any.
*
- * <p>This method may fail if either the input connection has become
- * invalid (such as its process crashing) or the client is taking too
- * long to respond with the text (it is given a couple of seconds to return).
- * In either case, a null is returned.
+ * <p>This method may fail if either the input connection has
+ * become invalid (such as its process crashing) or the client is
+ * taking too long to respond with the text (it is given a couple
+ * of seconds to return). In either case, null is returned.</p>
+ *
+ * <p>This method must not cause any changes in the editor's
+ * state.</p>
+ *
+ * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
+ * editor should return a {@link android.text.SpannableString}
+ * with all the spans set on the text.</p>
+ *
+ * <p><strong>IME authors:</strong> please consider this will
+ * trigger an IPC round-trip that will take some time. Assume this
+ * method consumes a lot of time.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful of race
+ * conditions in implementing this call. An IME can make a change
+ * to the text or change the selection position and use this
+ * method right away; you need to make sure the returned value is
+ * consistent with the results of the latest edits.</p>
*
* @param flags Supplies additional options controlling how the text is
- * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
- * @return Returns the text that is currently selected, if any, or null if
+ * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
+ * @return the text that is currently selected, if any, or null if
* no text is selected.
*/
public CharSequence getSelectedText(int flags);
/**
- * Retrieve the current capitalization mode in effect at the current
- * cursor position in the text. See
- * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode} for
- * more information.
- *
- * <p>This method may fail either if the input connection has become invalid
- * (such as its process crashing) or the client is taking too long to
- * respond with the text (it is given a couple seconds to return).
- * In either case, a 0 is returned.
- *
+ * Retrieve the current capitalization mode in effect at the
+ * current cursor position in the text. See
+ * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}
+ * for more information.
+ *
+ * <p>This method may fail either if the input connection has
+ * become invalid (such as its process crashing) or the client is
+ * taking too long to respond with the text (it is given a couple
+ * seconds to return). In either case, 0 is returned.</p>
+ *
+ * <p>This method does not affect the text in the editor in any
+ * way, nor does it affect the selection or composing spans.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful of race
+ * conditions in implementing this call. An IME can change the
+ * cursor position and use this method right away; you need to make
+ * sure the returned value is consistent with the results of the
+ * latest edits and changes to the cursor position.</p>
+ *
* @param reqModes The desired modes to retrieve, as defined by
- * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}. These
+ * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}. These
* constants are defined so that you can simply pass the current
* {@link EditorInfo#inputType TextBoxAttribute.contentType} value
* directly in to here.
- *
- * @return Returns the caps mode flags that are in effect.
+ * @return the caps mode flags that are in effect at the current
+ * cursor position. See TYPE_TEXT_FLAG_CAPS_* in {@link android.text.InputType}.
*/
public int getCursorCapsMode(int reqModes);
-
+
/**
- * Retrieve the current text in the input connection's editor, and monitor
- * for any changes to it. This function returns with the current text,
- * and optionally the input connection can send updates to the
- * input method when its text changes.
- *
- * <p>This method may fail either if the input connection has become invalid
- * (such as its process crashing) or the client is taking too long to
- * respond with the text (it is given a couple seconds to return).
- * In either case, a null is returned.
- *
+ * Retrieve the current text in the input connection's editor, and
+ * monitor for any changes to it. This function returns with the
+ * current text, and optionally the input connection can send
+ * updates to the input method when its text changes.
+ *
+ * <p>This method may fail either if the input connection has
+ * become invalid (such as its process crashing) or the client is
+ * taking too long to respond with the text (it is given a couple
+ * seconds to return). In either case, null is returned.</p>
+ *
+ * <p>Editor authors: as a general rule, try to comply with the
+ * fields in <code>request</code> for how many chars to return,
+ * but if performance or convenience dictates otherwise, please
+ * feel free to do what is most appropriate for your case. Also,
+ * if the
+ * {@link #GET_EXTRACTED_TEXT_MONITOR} flag is set, you should be
+ * calling
+ * {@link InputMethodManager#updateExtractedText(View, int, ExtractedText)}
+ * whenever you call
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)}.</p>
+ *
* @param request Description of how the text should be returned.
+ * {@link android.view.inputmethod.ExtractedTextRequest}
* @param flags Additional options to control the client, either 0 or
* {@link #GET_EXTRACTED_TEXT_MONITOR}.
- *
- * @return Returns an ExtractedText object describing the state of the
- * text view and containing the extracted text itself.
+
+ * @return an {@link android.view.inputmethod.ExtractedText}
+ * object describing the state of the text view and containing the
+ * extracted text itself, or null if the input connection is no
+ * longer valid of the editor can't comply with the request for
+ * some reason.
*/
public ExtractedText getExtractedText(ExtractedTextRequest request,
int flags);
/**
- * Delete <var>beforeLength</var> characters of text before the current cursor
- * position, and delete <var>afterLength</var> characters of text after the
- * current cursor position, excluding composing text. Before and after refer
- * to the order of the characters in the string, not to their visual representation.
- *
+ * Delete <var>beforeLength</var> characters of text before the
+ * current cursor position, and delete <var>afterLength</var>
+ * characters of text after the current cursor position, excluding
+ * the selection. Before and after refer to the order of the
+ * characters in the string, not to their visual representation:
+ * this means you don't have to figure out the direction of the
+ * text and can just use the indices as-is.
+ *
+ * <p>The lengths are supplied in Java chars, not in code points
+ * or in glyphs.</p>
+ *
+ * <p>Since this method only operates on text before and after the
+ * selection, it can't affect the contents of the selection. This
+ * may affect the composing span if the span includes characters
+ * that are to be deleted, but otherwise will not change it. If
+ * some characters in the composing span are deleted, the
+ * composing span will persist but get shortened by however many
+ * chars inside it have been removed.</p>
+ *
+ * <p><strong>IME authors:</strong> please be careful not to
+ * delete only half of a surrogate pair. Also take care not to
+ * delete more characters than are in the editor, as that may have
+ * ill effects on the application. Calling this method will cause
+ * the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on your service after the batch input is over.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful of race
+ * conditions in implementing this call. An IME can make a change
+ * to the text or change the selection position and use this
+ * method right away; you need to make sure the effects are
+ * consistent with the results of the latest edits. Also, although
+ * the IME should not send lengths bigger than the contents of the
+ * string, you should check the values for overflows and trim the
+ * indices to the size of the contents to avoid crashes. Since
+ * this changes the contents of the editor, you need to make the
+ * changes known to the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress.</p>
*
* @param beforeLength The number of characters to be deleted before the
* current cursor position.
* @param afterLength The number of characters to be deleted after the
* current cursor position.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean deleteSurroundingText(int beforeLength, int afterLength);
/**
- * Set composing text around the current cursor position with the given text,
- * and set the new cursor position. Any composing text set previously will
- * be removed automatically.
- *
+ * Set composing text around the current cursor position with the
+ * given text, and set the new cursor position. Any composing text
+ * set previously will be removed automatically.
+ *
+ * <p>If there is any composing span currently active, all
+ * characters that it comprises are removed. The passed text is
+ * added in its place, and a composing span is added to this
+ * text. Finally, the cursor is moved to the location specified by
+ * <code>newCursorPosition</code>.</p>
+ *
+ * <p>This is usually called by IMEs to add or remove or change
+ * characters in the composing span. Calling this method will
+ * cause the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on the current IME after the batch input is over.</p>
+ *
+ * <p><strong>Editor authors:</strong> please keep in mind the
+ * text may be very similar or completely different than what was
+ * in the composing span at call time, or there may not be a
+ * composing span at all. Please note that although it's not
+ * typical use, the string may be empty. Treat this normally,
+ * replacing the currently composing text with an empty string.
+ * Also, be careful with the cursor position. IMEs rely on this
+ * working exactly as described above. Since this changes the
+ * contents of the editor, you need to make the changes known to
+ * the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress. Note that this method can set the cursor position
+ * on either edge of the composing text or entirely outside it,
+ * but the IME may also go on to move the cursor position to
+ * within the composing text in a subsequent call so you should
+ * make no assumption at all: the composing text and the selection
+ * are entirely independent.</p>
+ *
* @param text The composing text with styles if necessary. If no style
* object attached to the text, the default style for composing text
- * is used. See {#link android.text.Spanned} for how to attach style
- * object to the text. {#link android.text.SpannableString} and
- * {#link android.text.SpannableStringBuilder} are two
- * implementations of the interface {#link android.text.Spanned}.
- * @param newCursorPosition The new cursor position around the text. If
+ * is used. See {@link android.text.Spanned} for how to attach style
+ * object to the text. {@link android.text.SpannableString} and
+ * {@link android.text.SpannableStringBuilder} are two
+ * implementations of the interface {@link android.text.Spanned}.
+ * @param newCursorPosition The new cursor position around the text. If
* > 0, this is relative to the end of the text - 1; if <= 0, this
- * is relative to the start of the text. So a value of 1 will
+ * is relative to the start of the text. So a value of 1 will
* always advance you to the position after the full text being
- * inserted. Note that this means you can't position the cursor
+ * inserted. Note that this means you can't position the cursor
* within the text, because the editor can make modifications to
* the text you are providing so it is not possible to correctly
* specify locations there.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean setComposingText(CharSequence text, int newCursorPosition);
/**
- * Mark a certain region of text as composing text. Any composing text set
- * previously will be removed automatically. The default style for composing
- * text is used.
+ * Mark a certain region of text as composing text. If there was a
+ * composing region, the characters are left as they were and the
+ * composing span removed, as if {@link #finishComposingText()}
+ * has been called. The default style for composing text is used.
+ *
+ * <p>The passed indices are clipped to the contents bounds. If
+ * the resulting region is zero-sized, no region is marked and the
+ * effect is the same as that of calling {@link #finishComposingText()}.
+ * The order of start and end is not important. In effect, the
+ * region from start to end and the region from end to start is
+ * the same. Editor authors, be ready to accept a start that is
+ * greater than end.</p>
+ *
+ * <p>Since this does not change the contents of the text, editors should not call
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)} and
+ * IMEs should not receive
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}.
+ * </p>
+ *
+ * <p>This has no impact on the cursor/selection position. It may
+ * result in the cursor being anywhere inside or outside the
+ * composing region, including cases where the selection and the
+ * composing region overlap partially or entirely.</p>
*
* @param start the position in the text at which the composing region begins
* @param end the position in the text at which the composing region ends
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean setComposingRegion(int start, int end);
/**
- * Have the text editor finish whatever composing text is currently
- * active. This simply leaves the text as-is, removing any special
- * composing styling or other state that was around it. The cursor
- * position remains unchanged.
+ * Have the text editor finish whatever composing text is
+ * currently active. This simply leaves the text as-is, removing
+ * any special composing styling or other state that was around
+ * it. The cursor position remains unchanged.
+ *
+ * <p><strong>IME authors:</strong> be aware that this call may be
+ * expensive with some editors.</p>
+ *
+ * <p><strong>Editor authors:</strong> please note that the cursor
+ * may be anywhere in the contents when this is called, including
+ * in the middle of the composing span or in a completely
+ * unrelated place. It must not move.</p>
+ *
+ * @return true on success, false if the input connection
+ * is no longer valid.
*/
public boolean finishComposingText();
-
+
/**
* Commit text to the text box and set the new cursor position.
- * Any composing text set previously will be removed
- * automatically.
- *
- * @param text The committed text.
- * @param newCursorPosition The new cursor position around the text. If
+ *
+ * <p>This method removes the contents of the currently composing
+ * text and replaces it with the passed CharSequence, and then
+ * moves the cursor according to {@code newCursorPosition}.
+ * This behaves like calling
+ * {@link #setComposingText(CharSequence, int) setComposingText(text, newCursorPosition)}
+ * then {@link #finishComposingText()}.</p>
+ *
+ * <p>Calling this method will cause the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on the current IME after the batch input is over.
+ * <strong>Editor authors</strong>, for this to happen you need to
+ * make the changes known to the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress.</p>
+ *
+ * @param text The committed text. This may include styles.
+ * @param newCursorPosition The new cursor position around the text. If
* > 0, this is relative to the end of the text - 1; if <= 0, this
- * is relative to the start of the text. So a value of 1 will
+ * is relative to the start of the text. So a value of 1 will
* always advance you to the position after the full text being
- * inserted. Note that this means you can't position the cursor
+ * inserted. Note that this means you can't position the cursor
* within the text, because the editor can make modifications to
* the text you are providing so it is not possible to correctly
* specify locations there.
- *
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean commitText(CharSequence text, int newCursorPosition);
@@ -223,49 +478,102 @@
/**
* Commit a completion the user has selected from the possible ones
* previously reported to {@link InputMethodSession#displayCompletions
- * InputMethodSession.displayCompletions()}. This will result in the
- * same behavior as if the user had selected the completion from the
- * actual UI.
- *
+ * InputMethodSession#displayCompletions(CompletionInfo[])} or
+ * {@link InputMethodManager#displayCompletions
+ * InputMethodManager#displayCompletions(View, CompletionInfo[])}.
+ * This will result in the same behavior as if the user had
+ * selected the completion from the actual UI. In all other
+ * respects, this behaves like {@link #commitText(CharSequence, int)}.
+ *
+ * <p><strong>IME authors:</strong> please take care to send the
+ * same object that you received through
+ * {@link android.inputmethodservice.InputMethodService#onDisplayCompletions(CompletionInfo[])}.
+ * </p>
+ *
+ * <p><strong>Editor authors:</strong> if you never call
+ * {@link InputMethodSession#displayCompletions(CompletionInfo[])} or
+ * {@link InputMethodManager#displayCompletions(View, CompletionInfo[])} then
+ * a well-behaved IME should never call this on your input
+ * connection, but be ready to deal with misbehaving IMEs without
+ * crashing.</p>
+ *
+ * <p>Calling this method (with a valid {@link CompletionInfo} object)
+ * will cause the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on the current IME after the batch input is over.
+ * <strong>Editor authors</strong>, for this to happen you need to
+ * make the changes known to the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress.</p>
+ *
* @param text The committed completion.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean commitCompletion(CompletionInfo text);
/**
- * Commit a correction automatically performed on the raw user's input. A typical example would
- * be to correct typos using a dictionary.
+ * Commit a correction automatically performed on the raw user's input. A
+ * typical example would be to correct typos using a dictionary.
+ *
+ * <p>Calling this method will cause the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on the current IME after the batch input is over.
+ * <strong>Editor authors</strong>, for this to happen you need to
+ * make the changes known to the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress.</p>
*
* @param correctionInfo Detailed information about the correction.
- *
- * @return True on success, false if the input connection is no longer valid.
+ * @return true on success, false if the input connection is no longer valid.
*/
public boolean commitCorrection(CorrectionInfo correctionInfo);
/**
- * Set the selection of the text editor. To set the cursor position,
- * start and end should have the same value.
- * @return Returns true on success, false if the input connection is no longer
+ * Set the selection of the text editor. To set the cursor
+ * position, start and end should have the same value.
+ *
+ * <p>Since this moves the cursor, calling this method will cause
+ * the editor to call
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * on the current IME after the batch input is over.
+ * <strong>Editor authors</strong>, for this to happen you need to
+ * make the changes known to the input method by calling
+ * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
+ * but be careful to wait until the batch edit is over if one is
+ * in progress.</p>
+ *
+ * <p>This has no effect on the composing region which must stay
+ * unchanged. The order of start and end is not important. In
+ * effect, the region from start to end and the region from end to
+ * start is the same. Editor authors, be ready to accept a start
+ * that is greater than end.</p>
+ *
+ * @param start the character index where the selection should start.
+ * @param end the character index where the selection should end.
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean setSelection(int start, int end);
-
+
/**
* Have the editor perform an action it has said it can do.
- *
+ *
+ * <p>This is typically used by IMEs when the user presses the key
+ * associated with the action.</p>
+ *
* @param editorAction This must be one of the action constants for
* {@link EditorInfo#imeOptions EditorInfo.editorType}, such as
* {@link EditorInfo#IME_ACTION_GO EditorInfo.EDITOR_ACTION_GO}.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean performEditorAction(int editorAction);
-
+
/**
- * Perform a context menu action on the field. The given id may be one of:
+ * Perform a context menu action on the field. The given id may be one of:
* {@link android.R.id#selectAll},
* {@link android.R.id#startSelectingText}, {@link android.R.id#stopSelectingText},
* {@link android.R.id#cut}, {@link android.R.id#copy},
@@ -273,50 +581,82 @@
* or {@link android.R.id#switchInputMethod}
*/
public boolean performContextMenuAction(int id);
-
+
/**
- * Tell the editor that you are starting a batch of editor operations.
- * The editor will try to avoid sending you updates about its state
- * until {@link #endBatchEdit} is called.
+ * Tell the editor that you are starting a batch of editor
+ * operations. The editor will try to avoid sending you updates
+ * about its state until {@link #endBatchEdit} is called. Batch
+ * edits nest.
+ *
+ * <p><strong>IME authors:</strong> use this to avoid getting
+ * calls to
+ * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int, int, int)}
+ * corresponding to intermediate state. Also, use this to avoid
+ * flickers that may arise from displaying intermediate state. Be
+ * sure to call {@link #endBatchEdit} for each call to this, or
+ * you may block updates in the editor.</p>
+ *
+ * <p><strong>Editor authors:</strong> while a batch edit is in
+ * progress, take care not to send updates to the input method and
+ * not to update the display. IMEs use this intensively to this
+ * effect. Also please note that batch edits need to nest
+ * correctly.</p>
+ *
+ * @return true if a batch edit is now in progress, false otherwise. Since
+ * this method starts a batch edit, that means it will always return true
+ * unless the input connection is no longer valid.
*/
public boolean beginBatchEdit();
-
+
/**
* Tell the editor that you are done with a batch edit previously
- * initiated with {@link #beginBatchEdit}.
+ * initiated with {@link #beginBatchEdit}. This ends the latest
+ * batch only.
+ *
+ * <p><strong>IME authors:</strong> make sure you call this
+ * exactly once for each call to {@link #beginBatchEdit}.</p>
+ *
+ * <p><strong>Editor authors:</strong> please be careful about
+ * batch edit nesting. Updates still to be held back until the end
+ * of the last batch edit.</p>
+ *
+ * @return true if there is still a batch edit in progress after closing
+ * the latest one (in other words, if the nesting count is > 0), false
+ * otherwise or if the input connection is no longer valid.
*/
public boolean endBatchEdit();
-
+
/**
- * Send a key event to the process that is currently attached through
- * this input connection. The event will be dispatched like a normal
- * key event, to the currently focused; this generally is the view that
- * is providing this InputConnection, but due to the asynchronous nature
- * of this protocol that can not be guaranteed and the focus may have
- * changed by the time the event is received.
- *
- * <p>
- * This method can be used to send key events to the application. For
- * example, an on-screen keyboard may use this method to simulate a hardware
- * keyboard. There are three types of standard keyboards, numeric (12-key),
- * predictive (20-key) and ALPHA (QWERTY). You can specify the keyboard type
- * by specify the device id of the key event.
- *
- * <p>
- * You will usually want to set the flag
- * {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD} on all
- * key event objects you give to this API; the flag will not be set
- * for you.
+ * Send a key event to the process that is currently attached
+ * through this input connection. The event will be dispatched
+ * like a normal key event, to the currently focused view; this
+ * generally is the view that is providing this InputConnection,
+ * but due to the asynchronous nature of this protocol that can
+ * not be guaranteed and the focus may have changed by the time
+ * the event is received.
*
- * <p>Note that it's discouraged to send such key events in normal operation;
- * this is mainly for use with {@link android.text.InputType#TYPE_NULL} type
- * text fields. Use the {@link #commitText} family of methods to send text
- * to the application instead.
+ * <p>This method can be used to send key events to the
+ * application. For example, an on-screen keyboard may use this
+ * method to simulate a hardware keyboard. There are three types
+ * of standard keyboards, numeric (12-key), predictive (20-key)
+ * and ALPHA (QWERTY). You can specify the keyboard type by
+ * specify the device id of the key event.</p>
+ *
+ * <p>You will usually want to set the flag
+ * {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
+ * on all key event objects you give to this API; the flag will
+ * not be set for you.</p>
+ *
+ * <p>Note that it's discouraged to send such key events in normal
+ * operation; this is mainly for use with
+ * {@link android.text.InputType#TYPE_NULL} type text fields. Use
+ * the {@link #commitText} family of methods to send text to the
+ * application instead.</p>
+ *
* @param event The key event.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
- *
+ *
* @see KeyEvent
* @see KeyCharacterMap#NUMERIC
* @see KeyCharacterMap#PREDICTIVE
@@ -325,37 +665,46 @@
public boolean sendKeyEvent(KeyEvent event);
/**
- * Clear the given meta key pressed states in the given input connection.
- *
+ * Clear the given meta key pressed states in the given input
+ * connection.
+ *
+ * <p>This can be used by the IME to clear the meta key states set
+ * by a hardware keyboard with latched meta keys, if the editor
+ * keeps track of these.</p>
+ *
* @param states The states to be cleared, may be one or more bits as
* per {@link KeyEvent#getMetaState() KeyEvent.getMetaState()}.
- *
- * @return Returns true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer
* valid.
*/
public boolean clearMetaKeyStates(int states);
-
+
/**
- * Called by the IME to tell the client when it switches between fullscreen
- * and normal modes. This will normally be called for you by the standard
- * implementation of {@link android.inputmethodservice.InputMethodService}.
+ * Called by the IME to tell the client when it switches between
+ * fullscreen and normal modes. This will normally be called for
+ * you by the standard implementation of
+ * {@link android.inputmethodservice.InputMethodService}.
+ *
+ * @return true on success, false if the input connection is no longer
+ * valid.
*/
public boolean reportFullscreenMode(boolean enabled);
-
+
/**
- * API to send private commands from an input method to its connected
- * editor. This can be used to provide domain-specific features that are
- * only known between certain input methods and their clients. Note that
- * because the InputConnection protocol is asynchronous, you have no way
- * to get a result back or know if the client understood the command; you
- * can use the information in {@link EditorInfo} to determine if
- * a client supports a particular command.
- *
- * @param action Name of the command to be performed. This <em>must</em>
+ * API to send private commands from an input method to its
+ * connected editor. This can be used to provide domain-specific
+ * features that are only known between certain input methods and
+ * their clients. Note that because the InputConnection protocol
+ * is asynchronous, you have no way to get a result back or know
+ * if the client understood the command; you can use the
+ * information in {@link EditorInfo} to determine if a client
+ * supports a particular command.
+ *
+ * @param action Name of the command to be performed. This <em>must</em>
* be a scoped name, i.e. prefixed with a package name you own, so that
* different developers will not create conflicting commands.
* @param data Any data to include with the command.
- * @return Returns true if the command was sent (whether or not the
+ * @return true if the command was sent (whether or not the
* associated editor understood it), false if the input connection is no longer
* valid.
*/
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/view/transition/Crossfade.java
index babf58f..a40d0bf 100644
--- a/core/java/android/view/transition/Crossfade.java
+++ b/core/java/android/view/transition/Crossfade.java
@@ -31,8 +31,9 @@
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewOverlay;
-import java.util.HashMap;
+import java.util.Map;
/**
* This transition captures bitmap representations of target views before and
@@ -53,15 +54,99 @@
private static RectEvaluator sRectEvaluator = new RectEvaluator();
+ private int mFadeBehavior = FADE_BEHAVIOR_REVEAL;
+ private int mResizeBehavior = RESIZE_BEHAVIOR_SCALE;
+
+ /**
+ * Flag specifying that the fading animation should cross-fade
+ * between the old and new representation of all affected target
+ * views. This means that the old representation will fade out
+ * while the new one fades in. This effect may work well on views
+ * without solid backgrounds, such as TextViews.
+ *
+ * @see #setFadeBehavior(int)
+ */
+ public static final int FADE_BEHAVIOR_CROSSFADE = 0;
+ /**
+ * Flag specifying that the fading animation should reveal the
+ * new representation of all affected target views. This means
+ * that the old representation will fade out, gradually
+ * revealing the new representation, which remains opaque
+ * the whole time. This effect may work well on views
+ * with solid backgrounds, such as ImageViews.
+ *
+ * @see #setFadeBehavior(int)
+ */
+ public static final int FADE_BEHAVIOR_REVEAL = 1;
+
+ /**
+ * Flag specifying that the transition should not animate any
+ * changes in size between the old and new target views.
+ * This means that no scaling will take place as a result of
+ * this transition
+ *
+ * @see #setResizeBehavior(int)
+ */
+ public static final int RESIZE_BEHAVIOR_NONE = 0;
+ /**
+ * Flag specifying that the transition should animate any
+ * changes in size between the old and new target views.
+ * This means that the animation will scale the start/end
+ * representations of affected views from the starting size
+ * to the ending size over the course of the animation.
+ * This effect may work well on images, but is not recommended
+ * for text.
+ *
+ * @see #setResizeBehavior(int)
+ */
+ public static final int RESIZE_BEHAVIOR_SCALE = 1;
+
+ // TODO: Add fade/resize behaviors to xml resources
+
+ /**
+ * Sets the type of fading animation that will be run, one of
+ * {@link #FADE_BEHAVIOR_CROSSFADE} and {@link #FADE_BEHAVIOR_REVEAL}.
+ *
+ * @param fadeBehavior The type of fading animation to use when this
+ * transition is run.
+ */
+ public void setFadeBehavior(int fadeBehavior) {
+ if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_REVEAL) {
+ mFadeBehavior = fadeBehavior;
+ }
+ }
+
+ public int getFadeBehavior() {
+ return mFadeBehavior;
+ }
+
+ /**
+ * Sets the type of resizing behavior that will be used during the
+ * transition animation, one of {@link #RESIZE_BEHAVIOR_NONE} and
+ * {@link #RESIZE_BEHAVIOR_SCALE}.
+ *
+ * @param resizeBehavior The type of resizing behavior to use when this
+ * transition is run.
+ */
+ public void setResizeBehavior(int resizeBehavior) {
+ if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
+ mResizeBehavior = resizeBehavior;
+ }
+ }
+
+ public int getResizeBehavior() {
+ return mResizeBehavior;
+ }
+
@Override
protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return false;
}
- final View view = startValues.view;
- HashMap<String, Object> startVals = startValues.values;
- HashMap<String, Object> endVals = endValues.values;
+ final View view = endValues.view;
+ Map<String, Object> startVals = startValues.values;
+ Map<String, Object> endVals = endValues.values;
Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP);
Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP);
Drawable startDrawable = (Drawable) startVals.get(PROPNAME_DRAWABLE);
@@ -71,8 +156,12 @@
" for start, end: " + startBitmap + ", " + endBitmap);
}
if (startDrawable != null && endDrawable != null && !startBitmap.sameAs(endBitmap)) {
- view.getOverlay().add(endDrawable);
- view.getOverlay().add(startDrawable);
+ ViewOverlay overlay = (mFadeBehavior == FADE_BEHAVIOR_REVEAL) ?
+ view.getOverlay() : ((ViewGroup) view.getParent()).getOverlay();
+ if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
+ overlay.add(endDrawable);
+ }
+ overlay.add(startDrawable);
return true;
} else {
return false;
@@ -85,8 +174,8 @@
if (startValues == null || endValues == null) {
return null;
}
- HashMap<String, Object> startVals = startValues.values;
- HashMap<String, Object> endVals = endValues.values;
+ Map<String, Object> startVals = startValues.values;
+ Map<String, Object> endVals = endValues.values;
final View view = endValues.view;
Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
@@ -106,6 +195,10 @@
view.invalidate(startDrawable.getBounds());
}
});
+ ObjectAnimator anim1 = null;
+ if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
+ anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
+ }
if (Transition.DBG) {
Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
startValues + ", " + endValues);
@@ -113,23 +206,34 @@
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- view.getOverlay().remove(startDrawable);
- view.getOverlay().remove(endDrawable);
+ ViewOverlay overlay = (mFadeBehavior == FADE_BEHAVIOR_REVEAL) ?
+ view.getOverlay() : ((ViewGroup) view.getParent()).getOverlay();
+ overlay.remove(startDrawable);
+ if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
+ overlay.remove(endDrawable);
+ }
}
});
AnimatorSet set = new AnimatorSet();
set.playTogether(anim);
- if (!startBounds.equals(endBounds)) {
+ if (anim1 != null) {
+ set.playTogether(anim1);
+ }
+ if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE && !startBounds.equals(endBounds)) {
if (Transition.DBG) {
Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
startBounds + ", " + endBounds);
}
Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
sRectEvaluator, startBounds, endBounds);
- Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
- sRectEvaluator, startBounds, endBounds);
set.playTogether(anim2);
- set.playTogether(anim3);
+ if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE) {
+ // TODO: How to handle resizing with a CROSSFADE (vs. REVEAL) effect
+ // when we are animating the view directly?
+ Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
+ sRectEvaluator, startBounds, endBounds);
+ set.playTogether(anim3);
+ }
}
return set;
}
@@ -137,8 +241,11 @@
@Override
protected void captureValues(TransitionValues values, boolean start) {
View view = values.view;
- values.values.put(PROPNAME_BOUNDS, new Rect(0, 0,
- view.getWidth(), view.getHeight()));
+ Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
+ if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
+ bounds.offset(view.getLeft(), view.getTop());
+ }
+ values.values.put(PROPNAME_BOUNDS, bounds);
if (Transition.DBG) {
Log.d(LOG_TAG, "Captured bounds " + values.values.get(PROPNAME_BOUNDS) + ": start = " +
@@ -156,7 +263,7 @@
// TODO: I don't have resources, can't call the non-deprecated method?
BitmapDrawable drawable = new BitmapDrawable(bitmap);
// TODO: lrtb will be wrong if the view has transXY set
- drawable.setBounds(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+ drawable.setBounds(bounds);
values.values.put(PROPNAME_DRAWABLE, drawable);
}
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java
index 3bd57bd..1d05419 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/view/transition/Move.java
@@ -24,10 +24,12 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
+import android.util.ArrayMap;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
-import java.util.HashMap;
+import java.util.Map;
/**
* This transition captures the layout bounds of target views before and after
@@ -42,6 +44,7 @@
int[] tempLocation = new int[2];
boolean mResizeClip = false;
boolean mReparent = false;
+ private static final String LOG_TAG = "Move";
private static RectEvaluator sRectEvaluator = new RectEvaluator();
@@ -114,6 +117,13 @@
int endHeight = endBottom - endTop;
int numChanges = 0;
if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
+ if (Transition.DBG) {
+ Log.v(LOG_TAG, "Target = " + endValues.view);
+ Log.v(LOG_TAG, " start bounds: " + startLeft + ", " + startTop + ", " +
+ startRight + ", " + startBottom);
+ Log.v(LOG_TAG, " end bounds: " + endLeft + ", " + endTop + ", " +
+ endRight + ", " + endBottom);
+ }
if (startLeft != endLeft) ++numChanges;
if (startTop != endTop) ++numChanges;
if (startRight != endRight) ++numChanges;
@@ -207,8 +217,8 @@
if (startValues == null || endValues == null) {
return false;
}
- HashMap<String, Object> startParentVals = startValues.values;
- HashMap<String, Object> endParentVals = endValues.values;
+ Map<String, Object> startParentVals = startValues.values;
+ Map<String, Object> endParentVals = endValues.values;
ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
if (startParent == null || endParent == null) {
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/view/transition/Recolor.java
index 7048be9..45407e1 100644
--- a/core/java/android/view/transition/Recolor.java
+++ b/core/java/android/view/transition/Recolor.java
@@ -20,11 +20,12 @@
import android.animation.ObjectAnimator;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.util.ArrayMap;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import java.util.HashMap;
+import java.util.Map;
/**
* This transition tracks changes during scene changes to the
@@ -86,8 +87,8 @@
}
ObjectAnimator anim = null;
final View view = endValues.view;
- HashMap<String, Object> startVals = startValues.values;
- HashMap<String, Object> endVals = endValues.values;
+ Map<String, Object> startVals = startValues.values;
+ Map<String, Object> endVals = endValues.values;
Drawable startBackground = (Drawable) startVals.get(PROPNAME_BACKGROUND);
Drawable endBackground = (Drawable) endVals.get(PROPNAME_BACKGROUND);
if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/view/transition/TextChange.java
index 0ba2412..ac2852c 100644
--- a/core/java/android/view/transition/TextChange.java
+++ b/core/java/android/view/transition/TextChange.java
@@ -18,10 +18,11 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.util.ArrayMap;
import android.view.ViewGroup;
import android.widget.TextView;
-import java.util.HashMap;
+import java.util.Map;
/**
* This transition tracks changes to the text in TextView targets. If the text
@@ -51,8 +52,8 @@
return false;
}
final TextView view = (TextView) endValues.view;
- HashMap<String, Object> startVals = startValues.values;
- HashMap<String, Object> endVals = endValues.values;
+ Map<String, Object> startVals = startValues.values;
+ Map<String, Object> endVals = endValues.values;
String startText = (String) startVals.get(PROPNAME_TEXT);
String endText = (String) endVals.get(PROPNAME_TEXT);
if (!startText.equals(endText)) {
@@ -69,8 +70,8 @@
return null;
}
final TextView view = (TextView) endValues.view;
- HashMap<String, Object> startVals = startValues.values;
- HashMap<String, Object> endVals = endValues.values;
+ Map<String, Object> startVals = startValues.values;
+ Map<String, Object> endVals = endValues.values;
final String startText = (String) startVals.get(PROPNAME_TEXT);
final String endText = (String) endVals.get(PROPNAME_TEXT);
if (!startText.equals(endText)) {
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java
index 150c218..205c825 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/view/transition/Transition.java
@@ -18,6 +18,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
+import android.util.ArrayMap;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.view.SurfaceView;
@@ -28,7 +29,6 @@
import android.widget.ListView;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* A Transition holds information about animations that will be run on its
@@ -62,14 +62,13 @@
TimeInterpolator mInterpolator = null;
int[] mTargetIds;
View[] mTargets;
- // TODO: sparse arrays instead of hashmaps?
- private HashMap<View, TransitionValues> mStartValues =
- new HashMap<View, TransitionValues>();
+ private ArrayMap<View, TransitionValues> mStartValues =
+ new ArrayMap<View, TransitionValues>();
private SparseArray<TransitionValues> mStartIdValues = new SparseArray<TransitionValues>();
private LongSparseArray<TransitionValues> mStartItemIdValues =
new LongSparseArray<TransitionValues>();
- private HashMap<View, TransitionValues> mEndValues =
- new HashMap<View, TransitionValues>();
+ private ArrayMap<View, TransitionValues> mEndValues =
+ new ArrayMap<View, TransitionValues>();
private SparseArray<TransitionValues> mEndIdValues = new SparseArray<TransitionValues>();
private LongSparseArray<TransitionValues> mEndItemIdValues =
new LongSparseArray<TransitionValues>();
@@ -78,6 +77,10 @@
private ArrayList<TransitionValues> mPlayStartValuesList = new ArrayList<TransitionValues>();
private ArrayList<TransitionValues> mPlayEndValuesList = new ArrayList<TransitionValues>();
+ // Track all animators in use in case the transition gets canceled and needs to
+ // cancel running animators
+ private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>();
+
// Number of per-target instances of this Transition currently running. This count is
// determined by calls to startTransition() and endTransition()
int mNumInstances = 0;
@@ -223,15 +226,15 @@
*
* @hide
*/
- protected void prePlay(ViewGroup sceneRoot, HashMap<View, TransitionValues> startValues,
+ protected void prePlay(ViewGroup sceneRoot, ArrayMap<View, TransitionValues> startValues,
SparseArray<TransitionValues> startIdValues,
LongSparseArray<TransitionValues> startItemIdValues,
- HashMap<View, TransitionValues> endValues,
+ ArrayMap<View, TransitionValues> endValues,
SparseArray<TransitionValues> endIdValues,
LongSparseArray<TransitionValues> endItemIdValues) {
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
- HashMap<View, TransitionValues> endCopy = new HashMap<View, TransitionValues>(endValues);
+ ArrayMap<View, TransitionValues> endCopy = new ArrayMap<View, TransitionValues>(endValues);
SparseArray<TransitionValues> endIdCopy =
new SparseArray<TransitionValues>(endIdValues.size());
for (int i = 0; i < endIdValues.size(); ++i) {
@@ -388,10 +391,10 @@
* @hide
*/
protected void play(ViewGroup sceneRoot,
- final HashMap<View, TransitionValues> startValues,
+ final ArrayMap<View, TransitionValues> startValues,
final SparseArray<TransitionValues> startIdValues,
final LongSparseArray<TransitionValues> startItemIdValues,
- final HashMap<View, TransitionValues> endValues,
+ final ArrayMap<View, TransitionValues> endValues,
final SparseArray<TransitionValues> endIdValues,
final LongSparseArray<TransitionValues> endItemIdValues) {
@@ -401,13 +404,30 @@
TransitionValues start = mPlayStartValuesList.get(i);
TransitionValues end = mPlayEndValuesList.get(i);
startTransition();
- animate(play(sceneRoot, start, end));
+ runAnimator(play(sceneRoot, start, end));
}
mPlayStartValuesList.clear();
mPlayEndValuesList.clear();
endTransition();
}
+ private void runAnimator(Animator animator) {
+ if (animator != null) {
+ // TODO: could be a single listener instance for all of them since it uses the param
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mCurrentAnimators.add(animation);
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mCurrentAnimators.remove(animation);
+ }
+ });
+ animate(animator);
+ }
+ }
+
/**
* Captures the current scene of values for the properties that this
* transition monitors. These values can be either the start or end
@@ -534,10 +554,14 @@
captureValues(values, start);
if (start) {
mStartValues.put(view, values);
- mStartIdValues.put(id, values);
+ if (id >= 0) {
+ mStartIdValues.put(id, values);
+ }
} else {
mEndValues.put(view, values);
- mEndIdValues.put(id, values);
+ if (id >= 0) {
+ mEndIdValues.put(id, values);
+ }
}
}
}
@@ -599,14 +623,18 @@
if (start) {
if (!isListViewItem) {
mStartValues.put(view, values);
- mStartIdValues.put((int) id, values);
+ if (id >= 0) {
+ mStartIdValues.put((int) id, values);
+ }
} else {
mStartItemIdValues.put(id, values);
}
} else {
if (!isListViewItem) {
mEndValues.put(view, values);
- mEndIdValues.put((int) id, values);
+ if (id >= 0) {
+ mEndIdValues.put((int) id, values);
+ }
} else {
mEndItemIdValues.put(id, values);
}
@@ -660,11 +688,6 @@
}
animator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationCancel(Animator animation) {
- cancelTransition();
- }
-
- @Override
public void onAnimationEnd(Animator animation) {
endTransition();
animation.removeListener(this);
@@ -763,6 +786,7 @@
mEndValues.clear();
mEndIdValues.clear();
mEndItemIdValues.clear();
+ mCurrentAnimators.clear();
}
}
@@ -773,6 +797,11 @@
protected void cancelTransition() {
// TODO: how does this work with instances?
// TODO: this doesn't actually do *anything* yet
+ int numAnimators = mCurrentAnimators.size();
+ for (int i = numAnimators - 1; i >= 0; i--) {
+ Animator animator = mCurrentAnimators.get(i);
+ animator.cancel();
+ }
onTransitionCancel();
if (mListeners != null && mListeners.size() > 0) {
ArrayList<TransitionListener> tmpListeners =
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
index 363872a..8ff46b6 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -17,13 +17,13 @@
import android.animation.Animator;
import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* A TransitionGroup is a parent of child transitions (including other
@@ -106,11 +106,33 @@
int numTransitions = transitions.length;
for (int i = 0; i < numTransitions; ++i) {
mTransitions.add(transitions[i]);
+ if (mDuration >= 0) {
+ transitions[0].setDuration(mDuration);
+ }
}
}
}
/**
+ * Setting a non-negative duration on a TransitionGroup causes all of the child
+ * transitions (current and future) to inherit this duration.
+ *
+ * @param duration The length of the animation, in milliseconds.
+ * @return This transitionGroup object.
+ */
+ @Override
+ public Transition setDuration(long duration) {
+ super.setDuration(duration);
+ if (mDuration >= 0) {
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).setDuration(duration);
+ }
+ }
+ return this;
+ }
+
+ /**
* Removes the specified child transition from this group.
*
* @param transition The transition to be removed.
@@ -161,10 +183,10 @@
*/
@Override
protected void prePlay(ViewGroup sceneRoot,
- HashMap<View, TransitionValues> startValues,
+ ArrayMap<View, TransitionValues> startValues,
SparseArray<TransitionValues> startIdValues,
LongSparseArray<TransitionValues> startItemIdValues,
- HashMap<View, TransitionValues> endValues,
+ ArrayMap<View, TransitionValues> endValues,
SparseArray<TransitionValues> endIdValues,
LongSparseArray<TransitionValues> endItemIdValues) {
for (Transition childTransition : mTransitions) {
@@ -178,10 +200,10 @@
*/
@Override
protected void play(ViewGroup sceneRoot,
- final HashMap<View, TransitionValues> startValues,
+ final ArrayMap<View, TransitionValues> startValues,
final SparseArray<TransitionValues> startIdValues,
final LongSparseArray<TransitionValues> startItemIdValues,
- final HashMap<View, TransitionValues> endValues,
+ final ArrayMap<View, TransitionValues> endValues,
final SparseArray<TransitionValues> endIdValues,
final LongSparseArray<TransitionValues> endItemIdValues) {
setupStartEndListeners();
@@ -281,6 +303,15 @@
}
@Override
+ protected void cancelTransition() {
+ super.cancelTransition();
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).cancelTransition();
+ }
+ }
+
+ @Override
String toString(String indent) {
String result = super.toString(indent);
for (int i = 0; i < mTransitions.size(); ++i) {
diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/view/transition/TransitionInflater.java
index a5f5836..dc930d5 100644
--- a/core/java/android/view/transition/TransitionInflater.java
+++ b/core/java/android/view/transition/TransitionInflater.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.Xml;
@@ -30,7 +31,6 @@
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* This class inflates scenes and transitions from resource files.
@@ -40,8 +40,8 @@
// We only need one inflater for any given context. Also, this allows us to associate
// ids with unique instances per-Context, used to avoid re-inflating
// already-inflated resources into new/different instances
- private static final HashMap<Context, TransitionInflater> sInflaterMap =
- new HashMap<Context, TransitionInflater>();
+ private static final ArrayMap<Context, TransitionInflater> sInflaterMap =
+ new ArrayMap<Context, TransitionInflater>();
private Context mContext;
// TODO: do we need id maps for transitions and transitionMgrs as well?
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java
index 5a1991c..4971a92 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/view/transition/TransitionManager.java
@@ -15,11 +15,10 @@
*/
package android.view.transition;
+import android.util.ArrayMap;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import java.util.HashMap;
-
/**
* This class manages the set of transitions that fire when there is a
* change of {@link Scene}. To use the manager, add scenes along with
@@ -37,9 +36,11 @@
private static final Transition sDefaultTransition = new AutoTransition();
private Transition mDefaultTransition = new AutoTransition();
- HashMap<Scene, Transition> mSceneTransitions = new HashMap<Scene, Transition>();
- HashMap<Scene, HashMap<Scene, Transition>> mScenePairTransitions =
- new HashMap<Scene, HashMap<Scene, Transition>>();
+ ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
+ ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
+ new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
+ static ArrayMap<ViewGroup, Transition> sRunningTransitions =
+ new ArrayMap<ViewGroup, Transition>();
/**
* Sets the transition to be used for any scene change for which no
@@ -89,9 +90,9 @@
* using {@link AutoTransition}.
*/
public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
- HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
+ ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
if (sceneTransitionMap == null) {
- sceneTransitionMap = new HashMap<Scene, Transition>();
+ sceneTransitionMap = new ArrayMap<Scene, Transition>();
mScenePairTransitions.put(toScene, sceneTransitionMap);
}
sceneTransitionMap.put(fromScene, transition);
@@ -114,7 +115,7 @@
// TODO: cached in Scene instead? long-term, cache in View itself
Scene currScene = sceneRoot.getCurrentScene();
if (currScene != null) {
- HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
+ ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
if (sceneTransitionMap != null) {
transition = sceneTransitionMap.get(currScene);
if (transition != null) {
@@ -141,6 +142,11 @@
final ViewGroup sceneRoot = scene.getSceneRoot();
+ Transition runningTransition = sRunningTransitions.get(sceneRoot);
+ if (runningTransition != null) {
+ runningTransition.cancelTransition();
+ }
+
// Capture current values
if (transition != null) {
transition.captureValues(sceneRoot, true);
@@ -159,6 +165,14 @@
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+ // Add to running list, handle end to remove it
+ sRunningTransitions.put(sceneRoot, transition);
+ transition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ sRunningTransitions.remove(sceneRoot);
+ }
+ });
transition.captureValues(sceneRoot, false);
transition.play(sceneRoot);
return true;
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java
index 120ace8..1ef6bf4 100644
--- a/core/java/android/view/transition/TransitionValues.java
+++ b/core/java/android/view/transition/TransitionValues.java
@@ -15,15 +15,16 @@
*/
package android.view.transition;
+import android.util.ArrayMap;
import android.view.View;
import android.view.ViewGroup;
-import java.util.HashMap;
+import java.util.Map;
/**
* Data structure which holds cached values for the transition.
* The view field is the target which all of the values pertain to.
- * The values field is a hashmap which holds information for fields
+ * The values field is a map which holds information for fields
* according to names selected by the transitions. These names should
* be unique to avoid clobbering values stored by other transitions,
* such as the convention project:transition_name:property_name. For
@@ -48,7 +49,7 @@
/**
* The set of values tracked by transitions for this scene
*/
- public final HashMap<String, Object> values = new HashMap<String, Object>();
+ public final Map<String, Object> values = new ArrayMap<String, Object>();
@Override
public String toString() {
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 8ae0021..19492c2 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -500,6 +500,12 @@
* Sets the default zoom density of the page. This must be called from the UI
* thread. The default is {@link ZoomDensity#MEDIUM}.
*
+ * This setting is not recommended for use in new applications. If the WebView
+ * is utilized to display mobile-oriented pages, the desired effect can be achieved by
+ * adjusting 'width' and 'initial-scale' attributes of page's 'meta viewport'
+ * tag. For pages lacking the tag, {@link android.webkit.WebView#setInitialScale}
+ * and {@link #setUseWideViewPort} can be used.
+ *
* @param zoom the zoom density
*/
public void setDefaultZoom(ZoomDensity zoom) {
@@ -510,6 +516,8 @@
* Gets the default zoom density of the page. This should be called from
* the UI thread.
*
+ * This setting is not recommended for use in new applications.
+ *
* @return the zoom density
* @see #setDefaultZoom
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4c0ccca..ddc8d82 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,11 +25,11 @@
import android.graphics.drawable.TransitionDrawable;
import android.os.Bundle;
import android.os.Debug;
-import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.StrictMode;
import android.text.Editable;
+import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
@@ -61,9 +61,12 @@
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputConnectionWrapper;
import android.view.inputmethod.InputMethodManager;
import android.widget.RemoteViews.OnClickHandler;
@@ -1615,10 +1618,12 @@
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
+ @Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
+ @Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
@@ -1943,8 +1948,8 @@
}
final int top = getChildAt(0).getTop();
- final float fadeLength = (float) getVerticalFadingEdgeLength();
- return top < mPaddingTop ? (float) -(top - mPaddingTop) / fadeLength : fadeEdge;
+ final float fadeLength = getVerticalFadingEdgeLength();
+ return top < mPaddingTop ? -(top - mPaddingTop) / fadeLength : fadeEdge;
}
}
@@ -1961,9 +1966,9 @@
final int bottom = getChildAt(count - 1).getBottom();
final int height = getHeight();
- final float fadeLength = (float) getVerticalFadingEdgeLength();
+ final float fadeLength = getVerticalFadingEdgeLength();
return bottom > height - mPaddingBottom ?
- (float) (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
+ (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
}
}
@@ -2426,7 +2431,7 @@
* @return True if the selector should be shown
*/
boolean shouldShowSelector() {
- return (!isInTouchMode()) || touchModeDrawsInPressedState();
+ return (!isInTouchMode()) || (touchModeDrawsInPressedState() && isPressed());
}
private void drawSelector(Canvas canvas) {
@@ -2771,6 +2776,7 @@
private class PerformClick extends WindowRunnnable implements Runnable {
int mClickMotionPosition;
+ @Override
public void run() {
// The data has changed since we posted this action in the event queue,
// bail out before bad things happen
@@ -2792,6 +2798,7 @@
}
private class CheckForLongPress extends WindowRunnnable implements Runnable {
+ @Override
public void run() {
final int motionPosition = mMotionPosition;
final View child = getChildAt(motionPosition - mFirstPosition);
@@ -2815,6 +2822,7 @@
}
private class CheckForKeyLongPress extends WindowRunnnable implements Runnable {
+ @Override
public void run() {
if (isPressed() && mSelectedPosition >= 0) {
int index = mSelectedPosition - mFirstPosition;
@@ -2989,6 +2997,7 @@
}
final class CheckForTap implements Runnable {
+ @Override
public void run() {
if (mTouchMode == TOUCH_MODE_DOWN) {
mTouchMode = TOUCH_MODE_TAP;
@@ -3049,15 +3058,9 @@
mTouchMode = TOUCH_MODE_SCROLL;
mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
}
- final Handler handler = getHandler();
- // Handler should not be null unless the AbsListView is not attached to a
- // window, which would make it very hard to scroll it... but the monkeys
- // say it's possible.
- if (handler != null) {
- handler.removeCallbacks(mPendingCheckForLongPress);
- }
+ removeCallbacks(mPendingCheckForLongPress);
setPressed(false);
- View motionView = getChildAt(mMotionPosition - mFirstPosition);
+ final View motionView = getChildAt(mMotionPosition - mFirstPosition);
if (motionView != null) {
motionView.setPressed(false);
}
@@ -3239,6 +3242,7 @@
}
}
+ @Override
public void onTouchModeChanged(boolean isInTouchMode) {
if (isInTouchMode) {
// Get rid of the selection when we enter touch mode
@@ -3299,126 +3303,200 @@
}
}
- final int action = ev.getAction();
-
- View v;
-
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN: {
- switch (mTouchMode) {
- case TOUCH_MODE_OVERFLING: {
- mFlingRunnable.endFling();
- if (mPositionScroller != null) {
- mPositionScroller.stop();
- }
- mTouchMode = TOUCH_MODE_OVERSCROLL;
- mMotionX = (int) ev.getX();
- mMotionY = mLastY = (int) ev.getY();
- mMotionCorrection = 0;
- mActivePointerId = ev.getPointerId(0);
- mDirection = 0;
+ final int actionMasked = ev.getActionMasked();
+ switch (actionMasked) {
+ case MotionEvent.ACTION_DOWN: {
+ onTouchDown(ev);
break;
}
- default: {
- mActivePointerId = ev.getPointerId(0);
- final int x = (int) ev.getX();
- final int y = (int) ev.getY();
- int motionPosition = pointToPosition(x, y);
- if (!mDataChanged) {
- if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
- && (getAdapter().isEnabled(motionPosition))) {
- // User clicked on an actual view (and was not stopping a fling).
- // It might be a click or a scroll. Assume it is a click until
- // proven otherwise
- mTouchMode = TOUCH_MODE_DOWN;
- // FIXME Debounce
- if (mPendingCheckForTap == null) {
- mPendingCheckForTap = new CheckForTap();
- }
- postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
- } else {
- if (mTouchMode == TOUCH_MODE_FLING) {
- // Stopped a fling. It is a scroll.
- createScrollingCache();
- mTouchMode = TOUCH_MODE_SCROLL;
- mMotionCorrection = 0;
- motionPosition = findMotionRow(y);
- mFlingRunnable.flywheelTouch();
- }
- }
- }
+ case MotionEvent.ACTION_MOVE: {
+ onTouchMove(ev);
+ break;
+ }
+ case MotionEvent.ACTION_UP: {
+ onTouchUp(ev);
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ onTouchCancel();
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ onSecondaryPointerUp(ev);
+ final int x = mMotionX;
+ final int y = mMotionY;
+ final int motionPosition = pointToPosition(x, y);
if (motionPosition >= 0) {
// Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
+ final View child = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = child.getTop();
+ mMotionPosition = motionPosition;
}
- mMotionX = x;
- mMotionY = y;
- mMotionPosition = motionPosition;
- mLastY = Integer.MIN_VALUE;
+ mLastY = y;
break;
}
- }
- if (performButtonActionOnTouchDown(ev)) {
- if (mTouchMode == TOUCH_MODE_DOWN) {
- removeCallbacks(mPendingCheckForTap);
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ // New pointers take over dragging duties
+ final int index = ev.getActionIndex();
+ final int id = ev.getPointerId(index);
+ final int x = (int) ev.getX(index);
+ final int y = (int) ev.getY(index);
+ mMotionCorrection = 0;
+ mActivePointerId = id;
+ mMotionX = x;
+ mMotionY = y;
+ final int motionPosition = pointToPosition(x, y);
+ if (motionPosition >= 0) {
+ // Remember where the motion event started
+ final View child = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = child.getTop();
+ mMotionPosition = motionPosition;
}
+ mLastY = y;
+ break;
}
+ }
+
+ return true;
+ }
+
+ private void onTouchDown(MotionEvent ev) {
+ View v;
+ switch (mTouchMode) {
+ case TOUCH_MODE_OVERFLING: {
+ mFlingRunnable.endFling();
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+ mTouchMode = TOUCH_MODE_OVERSCROLL;
+ mMotionX = (int) ev.getX();
+ mMotionY = mLastY = (int) ev.getY();
+ mMotionCorrection = 0;
+ mActivePointerId = ev.getPointerId(0);
+ mDirection = 0;
break;
}
- case MotionEvent.ACTION_MOVE: {
- int pointerIndex = ev.findPointerIndex(mActivePointerId);
- if (pointerIndex == -1) {
- pointerIndex = 0;
- mActivePointerId = ev.getPointerId(pointerIndex);
- }
- final int y = (int) ev.getY(pointerIndex);
-
- if (mDataChanged) {
- // Re-sync everything if data has been changed
- // since the scroll operation can query the adapter.
- layoutChildren();
+ default: {
+ mActivePointerId = ev.getPointerId(0);
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
+ int motionPosition = pointToPosition(x, y);
+ if (!mDataChanged) {
+ if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
+ && (getAdapter().isEnabled(motionPosition))) {
+ // User clicked on an actual view (and was not stopping a fling).
+ // It might be a click or a scroll. Assume it is a click until
+ // proven otherwise
+ mTouchMode = TOUCH_MODE_DOWN;
+ // FIXME Debounce
+ if (mPendingCheckForTap == null) {
+ mPendingCheckForTap = new CheckForTap();
+ }
+ postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
+ } else {
+ if (mTouchMode == TOUCH_MODE_FLING) {
+ // Stopped a fling. It is a scroll.
+ createScrollingCache();
+ mTouchMode = TOUCH_MODE_SCROLL;
+ mMotionCorrection = 0;
+ motionPosition = findMotionRow(y);
+ mFlingRunnable.flywheelTouch();
+ }
+ }
}
- switch (mTouchMode) {
+ if (motionPosition >= 0) {
+ // Remember where the motion event started
+ v = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = v.getTop();
+ }
+ mMotionX = x;
+ mMotionY = y;
+ mMotionPosition = motionPosition;
+ mLastY = Integer.MIN_VALUE;
+ break;
+ }
+ }
+
+ if (performButtonActionOnTouchDown(ev)) {
+ if (mTouchMode == TOUCH_MODE_DOWN) {
+ removeCallbacks(mPendingCheckForTap);
+ }
+ }
+ }
+
+ private void onTouchMove(MotionEvent ev) {
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ pointerIndex = 0;
+ mActivePointerId = ev.getPointerId(pointerIndex);
+ }
+
+ if (mDataChanged) {
+ // Re-sync everything if data has been changed
+ // since the scroll operation can query the adapter.
+ layoutChildren();
+ }
+
+ final int y = (int) ev.getY(pointerIndex);
+
+ switch (mTouchMode) {
case TOUCH_MODE_DOWN:
case TOUCH_MODE_TAP:
case TOUCH_MODE_DONE_WAITING:
// Check if we have moved far enough that it looks more like a
- // scroll than a tap
- startScrollIfNeeded(y);
+ // scroll than a tap. If so, we'll enter scrolling mode.
+ if (startScrollIfNeeded(y)) {
+ break;
+ }
+ // Otherwise, check containment within list bounds. If we're
+ // outside bounds, cancel any active presses.
+ final float x = ev.getX();
+ final boolean inList = (x > mListPadding.left)
+ && (x < getWidth() - mListPadding.right);
+ if (!inList) {
+ setPressed(false);
+ final View motionView = getChildAt(mMotionPosition - mFirstPosition);
+ if (motionView != null) {
+ motionView.setPressed(false);
+ }
+ removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
+ mPendingCheckForTap : mPendingCheckForLongPress);
+ mTouchMode = TOUCH_MODE_DONE_WAITING;
+ updateSelectorState();
+ }
break;
case TOUCH_MODE_SCROLL:
case TOUCH_MODE_OVERSCROLL:
scrollIfNeeded(y);
break;
- }
- break;
}
+ }
- case MotionEvent.ACTION_UP: {
- switch (mTouchMode) {
- case TOUCH_MODE_DOWN:
- case TOUCH_MODE_TAP:
- case TOUCH_MODE_DONE_WAITING:
- final int motionPosition = mMotionPosition;
- final View child = getChildAt(motionPosition - mFirstPosition);
+ private void onTouchUp(MotionEvent ev) {
+ switch (mTouchMode) {
+ case TOUCH_MODE_DOWN:
+ case TOUCH_MODE_TAP:
+ case TOUCH_MODE_DONE_WAITING:
+ final int motionPosition = mMotionPosition;
+ final View child = getChildAt(motionPosition - mFirstPosition);
+ if (child != null) {
+ if (mTouchMode != TOUCH_MODE_DOWN) {
+ child.setPressed(false);
+ }
final float x = ev.getX();
final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;
-
- if (child != null && !child.hasFocusable() && inList) {
- if (mTouchMode != TOUCH_MODE_DOWN) {
- child.setPressed(false);
- }
-
+ if (inList && !child.hasFocusable()) {
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
@@ -3430,11 +3508,8 @@
mResurrectToPosition = motionPosition;
if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
- mPendingCheckForTap : mPendingCheckForLongPress);
- }
+ removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
+ mPendingCheckForTap : mPendingCheckForLongPress);
mLayoutMode = LAYOUT_NORMAL;
if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
mTouchMode = TOUCH_MODE_TAP;
@@ -3470,191 +3545,140 @@
mTouchMode = TOUCH_MODE_REST;
updateSelectorState();
}
- return true;
+ return;
} else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
performClick.run();
}
}
- mTouchMode = TOUCH_MODE_REST;
- updateSelectorState();
- break;
- case TOUCH_MODE_SCROLL:
- final int childCount = getChildCount();
- if (childCount > 0) {
- final int firstChildTop = getChildAt(0).getTop();
- final int lastChildBottom = getChildAt(childCount - 1).getBottom();
- final int contentTop = mListPadding.top;
- final int contentBottom = getHeight() - mListPadding.bottom;
- if (mFirstPosition == 0 && firstChildTop >= contentTop &&
- mFirstPosition + childCount < mItemCount &&
- lastChildBottom <= getHeight() - contentBottom) {
- mTouchMode = TOUCH_MODE_REST;
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- } else {
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-
- final int initialVelocity = (int)
- (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
- // Fling if we have enough velocity and we aren't at a boundary.
- // Since we can potentially overfling more than we can overscroll, don't
- // allow the weird behavior where you can scroll to a boundary then
- // fling further.
- if (Math.abs(initialVelocity) > mMinimumVelocity &&
- !((mFirstPosition == 0 &&
- firstChildTop == contentTop - mOverscrollDistance) ||
- (mFirstPosition + childCount == mItemCount &&
- lastChildBottom == contentBottom + mOverscrollDistance))) {
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
-
- mFlingRunnable.start(-initialVelocity);
- } else {
- mTouchMode = TOUCH_MODE_REST;
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- if (mFlingRunnable != null) {
- mFlingRunnable.endFling();
- }
- if (mPositionScroller != null) {
- mPositionScroller.stop();
- }
- }
- }
- } else {
+ }
+ mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
+ break;
+ case TOUCH_MODE_SCROLL:
+ final int childCount = getChildCount();
+ if (childCount > 0) {
+ final int firstChildTop = getChildAt(0).getTop();
+ final int lastChildBottom = getChildAt(childCount - 1).getBottom();
+ final int contentTop = mListPadding.top;
+ final int contentBottom = getHeight() - mListPadding.bottom;
+ if (mFirstPosition == 0 && firstChildTop >= contentTop &&
+ mFirstPosition + childCount < mItemCount &&
+ lastChildBottom <= getHeight() - contentBottom) {
mTouchMode = TOUCH_MODE_REST;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- }
- break;
-
- case TOUCH_MODE_OVERSCROLL:
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
- if (Math.abs(initialVelocity) > mMinimumVelocity) {
- mFlingRunnable.startOverfling(-initialVelocity);
} else {
- mFlingRunnable.startSpringback();
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+
+ final int initialVelocity = (int)
+ (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
+ // Fling if we have enough velocity and we aren't at a boundary.
+ // Since we can potentially overfling more than we can overscroll, don't
+ // allow the weird behavior where you can scroll to a boundary then
+ // fling further.
+ if (Math.abs(initialVelocity) > mMinimumVelocity &&
+ !((mFirstPosition == 0 &&
+ firstChildTop == contentTop - mOverscrollDistance) ||
+ (mFirstPosition + childCount == mItemCount &&
+ lastChildBottom == contentBottom + mOverscrollDistance))) {
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+
+ mFlingRunnable.start(-initialVelocity);
+ } else {
+ mTouchMode = TOUCH_MODE_REST;
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+ if (mFlingRunnable != null) {
+ mFlingRunnable.endFling();
+ }
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
+ }
+ }
}
-
- break;
- }
-
- setPressed(false);
-
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
- }
-
- // Need to redraw since we probably aren't drawing the selector anymore
- invalidate();
-
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mPendingCheckForLongPress);
- }
-
- recycleVelocityTracker();
-
- mActivePointerId = INVALID_POINTER;
-
- if (PROFILE_SCROLLING) {
- if (mScrollProfilingStarted) {
- Debug.stopMethodTracing();
- mScrollProfilingStarted = false;
- }
- }
-
- if (mScrollStrictSpan != null) {
- mScrollStrictSpan.finish();
- mScrollStrictSpan = null;
- }
- break;
- }
-
- case MotionEvent.ACTION_CANCEL: {
- switch (mTouchMode) {
- case TOUCH_MODE_OVERSCROLL:
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- mFlingRunnable.startSpringback();
- break;
-
- case TOUCH_MODE_OVERFLING:
- // Do nothing - let it play out.
- break;
-
- default:
+ } else {
mTouchMode = TOUCH_MODE_REST;
- setPressed(false);
- View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
- if (motionView != null) {
- motionView.setPressed(false);
- }
- clearScrollingCache();
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+ }
+ break;
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mPendingCheckForLongPress);
- }
+ case TOUCH_MODE_OVERSCROLL:
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
- recycleVelocityTracker();
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+ if (Math.abs(initialVelocity) > mMinimumVelocity) {
+ mFlingRunnable.startOverfling(-initialVelocity);
+ } else {
+ mFlingRunnable.startSpringback();
}
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
- }
- mActivePointerId = INVALID_POINTER;
break;
}
- case MotionEvent.ACTION_POINTER_UP: {
- onSecondaryPointerUp(ev);
- final int x = mMotionX;
- final int y = mMotionY;
- final int motionPosition = pointToPosition(x, y);
- if (motionPosition >= 0) {
- // Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
- mMotionPosition = motionPosition;
- }
- mLastY = y;
- break;
+ setPressed(false);
+
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
}
- case MotionEvent.ACTION_POINTER_DOWN: {
- // New pointers take over dragging duties
- final int index = ev.getActionIndex();
- final int id = ev.getPointerId(index);
- final int x = (int) ev.getX(index);
- final int y = (int) ev.getY(index);
- mMotionCorrection = 0;
- mActivePointerId = id;
- mMotionX = x;
- mMotionY = y;
- final int motionPosition = pointToPosition(x, y);
- if (motionPosition >= 0) {
- // Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
- mMotionPosition = motionPosition;
+ // Need to redraw since we probably aren't drawing the selector anymore
+ invalidate();
+ removeCallbacks(mPendingCheckForLongPress);
+ recycleVelocityTracker();
+
+ mActivePointerId = INVALID_POINTER;
+
+ if (PROFILE_SCROLLING) {
+ if (mScrollProfilingStarted) {
+ Debug.stopMethodTracing();
+ mScrollProfilingStarted = false;
}
- mLastY = y;
- break;
- }
}
- return true;
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
+ }
+ }
+
+ private void onTouchCancel() {
+ switch (mTouchMode) {
+ case TOUCH_MODE_OVERSCROLL:
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ mFlingRunnable.startSpringback();
+ break;
+
+ case TOUCH_MODE_OVERFLING:
+ // Do nothing - let it play out.
+ break;
+
+ default:
+ mTouchMode = TOUCH_MODE_REST;
+ setPressed(false);
+ final View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
+ if (motionView != null) {
+ motionView.setPressed(false);
+ }
+ clearScrollingCache();
+ removeCallbacks(mPendingCheckForLongPress);
+ recycleVelocityTracker();
+ }
+
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
+ }
+ mActivePointerId = INVALID_POINTER;
}
@Override
@@ -3733,7 +3757,7 @@
if (scrollY != 0) {
// Pin to the top/bottom during overscroll
int restoreCount = canvas.save();
- canvas.translate(0, (float) scrollY);
+ canvas.translate(0, scrollY);
mFastScroller.draw(canvas);
canvas.restoreToCount(restoreCount);
} else {
@@ -3945,6 +3969,7 @@
private int mLastFlingY;
private final Runnable mCheckFlywheel = new Runnable() {
+ @Override
public void run() {
final int activeId = mActivePointerId;
final VelocityTracker vt = mVelocityTracker;
@@ -4066,6 +4091,7 @@
postDelayed(mCheckFlywheel, FLYWHEEL_TIMEOUT);
}
+ @Override
public void run() {
switch (mTouchMode) {
default:
@@ -4455,6 +4481,7 @@
removeCallbacks(this);
}
+ @Override
public void run() {
final int listHeight = getHeight();
final int firstPos = mFirstPosition;
@@ -4637,9 +4664,6 @@
/**
* The amount of friction applied to flings. The default value
* is {@link ViewConfiguration#getScrollFriction}.
- *
- * @return A scalar dimensionless value representing the coefficient of
- * friction.
*/
public void setFriction(float friction) {
if (mFlingRunnable == null) {
@@ -4806,6 +4830,7 @@
if (!isHardwareAccelerated()) {
if (mClearScrollingCache == null) {
mClearScrollingCache = new Runnable() {
+ @Override
public void run() {
if (mCachingStarted) {
mCachingStarted = mCachingActive = false;
@@ -5083,7 +5108,7 @@
requestLayout();
invalidate();
}
-
+
/**
* If there is a selection returns false.
* Otherwise resurrects the selection and returns true if resurrected.
@@ -5591,54 +5616,139 @@
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
if (isTextFilterEnabled()) {
- // XXX we need to have the text filter created, so we can get an
- // InputConnection to proxy to. Unfortunately this means we pretty
- // much need to make it as soon as a list view gets focus.
- createTextFilter(false);
if (mPublicInputConnection == null) {
mDefInputConnection = new BaseInputConnection(this, false);
- mPublicInputConnection = new InputConnectionWrapper(
- mTextFilter.onCreateInputConnection(outAttrs), true) {
- @Override
- public boolean reportFullscreenMode(boolean enabled) {
- // Use our own input connection, since it is
- // the "real" one the IME is talking with.
- return mDefInputConnection.reportFullscreenMode(enabled);
- }
-
- @Override
- public boolean performEditorAction(int editorAction) {
- // The editor is off in its own window; we need to be
- // the one that does this.
- if (editorAction == EditorInfo.IME_ACTION_DONE) {
- InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(
- Context.INPUT_METHOD_SERVICE);
- if (imm != null) {
- imm.hideSoftInputFromWindow(getWindowToken(), 0);
- }
- return true;
- }
- return false;
- }
-
- @Override
- public boolean sendKeyEvent(KeyEvent event) {
- // Use our own input connection, since the filter
- // text view may not be shown in a window so has
- // no ViewAncestor to dispatch events with.
- return mDefInputConnection.sendKeyEvent(event);
- }
- };
+ mPublicInputConnection = new InputConnectionWrapper(outAttrs);
}
- outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_FILTER;
+ outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_FILTER;
outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
return mPublicInputConnection;
}
return null;
}
+ private class InputConnectionWrapper implements InputConnection {
+ private final EditorInfo mOutAttrs;
+ private InputConnection mTarget;
+
+ public InputConnectionWrapper(EditorInfo outAttrs) {
+ mOutAttrs = outAttrs;
+ }
+
+ private InputConnection getTarget() {
+ if (mTarget == null) {
+ mTarget = getTextFilterInput().onCreateInputConnection(mOutAttrs);
+ }
+ return mTarget;
+ }
+
+ @Override
+ public boolean reportFullscreenMode(boolean enabled) {
+ // Use our own input connection, since it is
+ // the "real" one the IME is talking with.
+ return mDefInputConnection.reportFullscreenMode(enabled);
+ }
+
+ @Override
+ public boolean performEditorAction(int editorAction) {
+ // The editor is off in its own window; we need to be
+ // the one that does this.
+ if (editorAction == EditorInfo.IME_ACTION_DONE) {
+ InputMethodManager imm = (InputMethodManager)
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ imm.hideSoftInputFromWindow(getWindowToken(), 0);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean sendKeyEvent(KeyEvent event) {
+ // Use our own input connection, since the filter
+ // text view may not be shown in a window so has
+ // no ViewAncestor to dispatch events with.
+ return mDefInputConnection.sendKeyEvent(event);
+ }
+
+ public CharSequence getTextBeforeCursor(int n, int flags) {
+ if (mTarget == null) return "";
+ return mTarget.getTextBeforeCursor(n, flags);
+ }
+
+ public CharSequence getTextAfterCursor(int n, int flags) {
+ if (mTarget == null) return "";
+ return mTarget.getTextAfterCursor(n, flags);
+ }
+
+ public CharSequence getSelectedText(int flags) {
+ if (mTarget == null) return "";
+ return mTarget.getSelectedText(flags);
+ }
+
+ public int getCursorCapsMode(int reqModes) {
+ if (mTarget == null) return InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
+ return mTarget.getCursorCapsMode(reqModes);
+ }
+
+ public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
+ return getTarget().getExtractedText(request, flags);
+ }
+
+ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+ return getTarget().deleteSurroundingText(beforeLength, afterLength);
+ }
+
+ public boolean setComposingText(CharSequence text, int newCursorPosition) {
+ return getTarget().setComposingText(text, newCursorPosition);
+ }
+
+ public boolean setComposingRegion(int start, int end) {
+ return getTarget().setComposingRegion(start, end);
+ }
+
+ public boolean finishComposingText() {
+ return mTarget == null || mTarget.finishComposingText();
+ }
+
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+ return getTarget().commitText(text, newCursorPosition);
+ }
+
+ public boolean commitCompletion(CompletionInfo text) {
+ return getTarget().commitCompletion(text);
+ }
+
+ public boolean commitCorrection(CorrectionInfo correctionInfo) {
+ return getTarget().commitCorrection(correctionInfo);
+ }
+
+ public boolean setSelection(int start, int end) {
+ return getTarget().setSelection(start, end);
+ }
+
+ public boolean performContextMenuAction(int id) {
+ return getTarget().performContextMenuAction(id);
+ }
+
+ public boolean beginBatchEdit() {
+ return getTarget().beginBatchEdit();
+ }
+
+ public boolean endBatchEdit() {
+ return getTarget().endBatchEdit();
+ }
+
+ public boolean clearMetaKeyStates(int states) {
+ return getTarget().clearMetaKeyStates(states);
+ }
+
+ public boolean performPrivateCommand(String action, Bundle data) {
+ return getTarget().performPrivateCommand(action, data);
+ }
+ }
+
/**
* For filtering we proxy an input connection to an internal text editor,
* and this allows the proxying to happen.
@@ -5655,23 +5765,11 @@
*/
private void createTextFilter(boolean animateEntrance) {
if (mPopup == null) {
- Context c = getContext();
- PopupWindow p = new PopupWindow(c);
- LayoutInflater layoutInflater = (LayoutInflater)
- c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mTextFilter = (EditText) layoutInflater.inflate(
- com.android.internal.R.layout.typing_filter, null);
- // For some reason setting this as the "real" input type changes
- // the text view in some way that it doesn't work, and I don't
- // want to figure out why this is.
- mTextFilter.setRawInputType(EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_FILTER);
- mTextFilter.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
- mTextFilter.addTextChangedListener(this);
+ PopupWindow p = new PopupWindow(getContext());
p.setFocusable(false);
p.setTouchable(false);
p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
- p.setContentView(mTextFilter);
+ p.setContentView(getTextFilterInput());
p.setWidth(LayoutParams.WRAP_CONTENT);
p.setHeight(LayoutParams.WRAP_CONTENT);
p.setBackgroundDrawable(null);
@@ -5686,12 +5784,28 @@
}
}
+ private EditText getTextFilterInput() {
+ if (mTextFilter == null) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ mTextFilter = (EditText) layoutInflater.inflate(
+ com.android.internal.R.layout.typing_filter, null);
+ // For some reason setting this as the "real" input type changes
+ // the text view in some way that it doesn't work, and I don't
+ // want to figure out why this is.
+ mTextFilter.setRawInputType(EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_VARIATION_FILTER);
+ mTextFilter.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+ mTextFilter.addTextChangedListener(this);
+ }
+ return mTextFilter;
+ }
+
/**
* Clear the text filter.
*/
public void clearTextFilter() {
if (mFiltered) {
- mTextFilter.setText("");
+ getTextFilterInput().setText("");
mFiltered = false;
if (mPopup != null && mPopup.isShowing()) {
dismissPopup();
@@ -5706,6 +5820,7 @@
return mFiltered;
}
+ @Override
public void onGlobalLayout() {
if (isShown()) {
// Show the popup if we are filtered
@@ -5725,6 +5840,7 @@
* For our text watcher that is associated with the text filter. Does
* nothing.
*/
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@@ -5733,8 +5849,10 @@
* the actual filtering as the text changes, and takes care of hiding and
* showing the popup displaying the currently entered filter text.
*/
+ @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- if (mPopup != null && isTextFilterEnabled()) {
+ if (isTextFilterEnabled()) {
+ createTextFilter(true);
int length = s.length();
boolean showing = mPopup.isShowing();
if (!showing && length > 0) {
@@ -5763,9 +5881,11 @@
* For our text watcher that is associated with the text filter. Does
* nothing.
*/
+ @Override
public void afterTextChanged(Editable s) {
}
+ @Override
public void onFilterComplete(int count) {
if (mSelectedPosition < 0 && count > 0) {
mResurrectToPosition = INVALID_POSITION;
@@ -5934,6 +6054,7 @@
* This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not
* connected yet.
*/
+ @Override
public void deferNotifyDataSetChanged() {
mDeferNotifyDataSetChanged = true;
}
@@ -5941,6 +6062,7 @@
/**
* Called back when the adapter connects to the RemoteViewsService.
*/
+ @Override
public boolean onRemoteAdapterConnected() {
if (mRemoteAdapter != mAdapter) {
setAdapter(mRemoteAdapter);
@@ -5959,6 +6081,7 @@
/**
* Called back when the adapter disconnects from the RemoteViewsService.
*/
+ @Override
public void onRemoteAdapterDisconnected() {
// If the remote adapter disconnects, we keep it around
// since the currently displayed items are still cached.
@@ -6041,6 +6164,7 @@
return mWrapped != null;
}
+ @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
if (mWrapped.onCreateActionMode(mode, menu)) {
// Initialize checked graphic state?
@@ -6050,14 +6174,17 @@
return false;
}
+ @Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return mWrapped.onPrepareActionMode(mode, menu);
}
+ @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return mWrapped.onActionItemClicked(mode, item);
}
+ @Override
public void onDestroyActionMode(ActionMode mode) {
mWrapped.onDestroyActionMode(mode);
mChoiceActionMode = null;
@@ -6072,6 +6199,7 @@
setLongClickable(true);
}
+ @Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
mWrapped.onItemCheckedStateChanged(mode, position, id, checked);
@@ -6296,6 +6424,7 @@
}
mFirstActivePosition = firstActivePosition;
+ //noinspection MismatchedReadAndWriteOfArray
final View[] activeViews = mActiveViews;
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index a19c6a8..6970cde 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1248,17 +1248,14 @@
* @param calendar A day in the new focus month.
*/
private void setMonthDisplayed(Calendar calendar) {
- final int newMonthDisplayed = calendar.get(Calendar.MONTH);
- if (mCurrentMonthDisplayed != newMonthDisplayed) {
- mCurrentMonthDisplayed = newMonthDisplayed;
- mAdapter.setFocusMonth(mCurrentMonthDisplayed);
- final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
- | DateUtils.FORMAT_SHOW_YEAR;
- final long millis = calendar.getTimeInMillis();
- String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
- mMonthName.setText(newMonthName);
- mMonthName.invalidate();
- }
+ mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+ mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+ final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
+ | DateUtils.FORMAT_SHOW_YEAR;
+ final long millis = calendar.getTimeInMillis();
+ String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
+ mMonthName.setText(newMonthName);
+ mMonthName.invalidate();
}
/**
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index ff0579c..55cfd27 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -595,12 +595,13 @@
final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
(overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
+ // Calling overScrollBy will call onOverScrolled, which
+ // calls onScrollChanged if applicable.
if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
mOverscrollDistance, 0, true)) {
// Break our velocity if we hit a scroll barrier.
mVelocityTracker.clear();
}
- onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (canOverscroll) {
final int pulledToX = oldX + deltaX;
@@ -732,9 +733,12 @@
boolean clampedX, boolean clampedY) {
// Treat animating scrolls differently; see #computeScroll() for why.
if (!mScroller.isFinished()) {
+ final int oldX = mScrollX;
+ final int oldY = mScrollY;
mScrollX = scrollX;
mScrollY = scrollY;
invalidateParentIfNeeded();
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (clampedX) {
mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index a82bebd..001d99c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3208,7 +3208,7 @@
final int count = getChildCount();
final int headerCount = mHeaderViewInfos.size();
final int itemCount = mItemCount;
- final int footerLimit = itemCount - mFooterViewInfos.size() - 1;
+ final int footerLimit = (itemCount - mFooterViewInfos.size());
final boolean headerDividers = mHeaderDividersEnabled;
final boolean footerDividers = mFooterDividersEnabled;
final int first = mFirstPosition;
@@ -3252,17 +3252,25 @@
}
for (int i = 0; i < count; i++) {
- if ((headerDividers || first + i >= headerCount) &&
- (footerDividers || first + i < footerLimit)) {
- View child = getChildAt(i);
+ final int itemIndex = (first + i);
+ final boolean isHeader = (itemIndex < headerCount);
+ final boolean isFooter = (itemIndex >= footerLimit);
+ if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+ final View child = getChildAt(i);
bottom = child.getBottom();
- // Don't draw dividers next to items that are not enabled
+ final boolean isLastItem = (i == (count - 1));
- if (drawDividers &&
- (bottom < listBottom && !(drawOverscrollFooter && i == count - 1))) {
- if ((areAllItemsSelectable ||
- (adapter.isEnabled(first + i) && (i == count - 1 ||
- adapter.isEnabled(first + i + 1))))) {
+ if (drawDividers && (bottom < listBottom)
+ && !(drawOverscrollFooter && isLastItem)) {
+ final int nextIndex = (itemIndex + 1);
+ // Draw dividers between enabled items, headers and/or
+ // footers when enabled, and the end of the list.
+ if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
+ || (headerDividers && isHeader)
+ || (footerDividers && isFooter)) && (isLastItem
+ || adapter.isEnabled(nextIndex)
+ || (headerDividers && (nextIndex < headerCount))
+ || (footerDividers && (nextIndex >= footerLimit))))) {
bounds.top = bottom;
bounds.bottom = bottom + dividerHeight;
drawDivider(canvas, bounds, i);
@@ -3295,20 +3303,28 @@
final int start = drawOverscrollHeader ? 1 : 0;
for (int i = start; i < count; i++) {
- if ((headerDividers || first + i >= headerCount) &&
- (footerDividers || first + i < footerLimit)) {
- View child = getChildAt(i);
+ final int itemIndex = (first + i);
+ final boolean isHeader = (itemIndex < headerCount);
+ final boolean isFooter = (itemIndex >= footerLimit);
+ if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+ final View child = getChildAt(i);
top = child.getTop();
- // Don't draw dividers next to items that are not enabled
- if (top > effectivePaddingTop) {
- if ((areAllItemsSelectable ||
- (adapter.isEnabled(first + i) && (i == count - 1 ||
- adapter.isEnabled(first + i + 1))))) {
+ if (drawDividers && (top > effectivePaddingTop)) {
+ final boolean isFirstItem = (i == start);
+ final int previousIndex = (itemIndex - 1);
+ // Draw dividers between enabled items, headers and/or
+ // footers when enabled, and the end of the list.
+ if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
+ || (headerDividers && isHeader)
+ || (footerDividers && isFooter)) && (isFirstItem
+ || adapter.isEnabled(previousIndex)
+ || (headerDividers && (previousIndex < headerCount))
+ || (footerDividers && (previousIndex >= footerLimit))))) {
bounds.top = top - dividerHeight;
bounds.bottom = top;
- // Give the method the child ABOVE the divider, so we
- // subtract one from our child
- // position. Give -1 when there is no child above the
+ // Give the method the child ABOVE the divider,
+ // so we subtract one from our child position.
+ // Give -1 when there is no child above the
// divider.
drawDivider(canvas, bounds, i - 1);
} else if (fillForMissingDividers) {
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index f940226..fd3dc03 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -16,22 +16,21 @@
package android.widget;
+import android.util.ArrayMap;
import com.android.internal.R;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.Pools.SimplePool;
+import android.util.Pools.SynchronizedPool;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.View;
@@ -42,7 +41,6 @@
import android.widget.RemoteViews.RemoteView;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static android.util.Log.d;
/**
* A Layout where the positions of the children can be described in relation to each other or to the
@@ -83,10 +81,6 @@
*/
@RemoteView
public class RelativeLayout extends ViewGroup {
- private static final String LOG_TAG = "RelativeLayout";
-
- private static final boolean DEBUG_GRAPH = false;
-
public static final int TRUE = -1;
/**
@@ -212,8 +206,8 @@
private SortedSet<View> mTopToBottomLeftToRightSet = null;
private boolean mDirtyHierarchy;
- private View[] mSortedHorizontalChildren = new View[0];
- private View[] mSortedVerticalChildren = new View[0];
+ private View[] mSortedHorizontalChildren;
+ private View[] mSortedVerticalChildren;
private final DependencyGraph mGraph = new DependencyGraph();
// Compatibility hack. Old versions of the platform had problems
@@ -360,42 +354,26 @@
}
private void sortChildren() {
- int count = getChildCount();
- if (mSortedVerticalChildren.length != count) mSortedVerticalChildren = new View[count];
- if (mSortedHorizontalChildren.length != count) mSortedHorizontalChildren = new View[count];
+ final int count = getChildCount();
+ if (mSortedVerticalChildren == null || mSortedVerticalChildren.length != count) {
+ mSortedVerticalChildren = new View[count];
+ }
+
+ if (mSortedHorizontalChildren == null || mSortedHorizontalChildren.length != count) {
+ mSortedHorizontalChildren = new View[count];
+ }
final DependencyGraph graph = mGraph;
graph.clear();
for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- graph.add(child);
- }
-
- if (DEBUG_GRAPH) {
- d(LOG_TAG, "=== Sorted vertical children");
- graph.log(getResources(), RULES_VERTICAL);
- d(LOG_TAG, "=== Sorted horizontal children");
- graph.log(getResources(), RULES_HORIZONTAL);
+ graph.add(getChildAt(i));
}
graph.getSortedViews(mSortedVerticalChildren, RULES_VERTICAL);
graph.getSortedViews(mSortedHorizontalChildren, RULES_HORIZONTAL);
-
- if (DEBUG_GRAPH) {
- d(LOG_TAG, "=== Ordered list of vertical children");
- for (View view : mSortedVerticalChildren) {
- DependencyGraph.printViewId(getResources(), view);
- }
- d(LOG_TAG, "=== Ordered list of horizontal children");
- for (View view : mSortedHorizontalChildren) {
- DependencyGraph.printViewId(getResources(), view);
- }
- }
}
- // TODO: we need to find another way to implement RelativeLayout
- // This implementation cannot handle every case
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mDirtyHierarchy) {
@@ -900,8 +878,6 @@
} else if (childParams.alignWithParent && rules[LEFT_OF] != 0) {
if (myWidth >= 0) {
childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
- } else {
- // FIXME uh oh...
}
}
@@ -926,8 +902,6 @@
} else if (childParams.alignWithParent && rules[ALIGN_RIGHT] != 0) {
if (myWidth >= 0) {
childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
- } else {
- // FIXME uh oh...
}
}
@@ -938,8 +912,6 @@
if (0 != rules[ALIGN_PARENT_RIGHT]) {
if (myWidth >= 0) {
childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
- } else {
- // FIXME uh oh...
}
}
}
@@ -958,8 +930,6 @@
} else if (childParams.alignWithParent && rules[ABOVE] != 0) {
if (myHeight >= 0) {
childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
- } else {
- // FIXME uh oh...
}
}
@@ -984,8 +954,6 @@
} else if (childParams.alignWithParent && rules[ALIGN_BOTTOM] != 0) {
if (myHeight >= 0) {
childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
- } else {
- // FIXME uh oh...
}
}
@@ -996,8 +964,6 @@
if (0 != rules[ALIGN_PARENT_BOTTOM]) {
if (myHeight >= 0) {
childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
- } else {
- // FIXME uh oh...
}
}
@@ -1677,8 +1643,10 @@
sorted[index++] = view;
- final HashMap<Node, DependencyGraph> dependents = node.dependents;
- for (Node dependent : dependents.keySet()) {
+ final ArrayMap<Node, DependencyGraph> dependents = node.dependents;
+ final int count = dependents.size();
+ for (int i = 0; i < count; i++) {
+ final Node dependent = dependents.keyAt(i);
final SparseArray<Node> dependencies = dependent.dependencies;
dependencies.remove(key);
@@ -1756,61 +1724,6 @@
}
/**
- * Prints the dependency graph for the specified rules.
- *
- * @param resources The context's resources to print the ids.
- * @param rules The list of rules to take into account.
- */
- void log(Resources resources, int... rules) {
- final ArrayDeque<Node> roots = findRoots(rules);
- for (Node node : roots) {
- printNode(resources, node);
- }
- }
-
- static void printViewId(Resources resources, View view) {
- if (view.getId() != View.NO_ID) {
- d(LOG_TAG, resources.getResourceEntryName(view.getId()));
- } else {
- d(LOG_TAG, "NO_ID");
- }
- }
-
- private static void appendViewId(Resources resources, Node node, StringBuilder buffer) {
- if (node.view.getId() != View.NO_ID) {
- buffer.append(resources.getResourceEntryName(node.view.getId()));
- } else {
- buffer.append("NO_ID");
- }
- }
-
- private static void printNode(Resources resources, Node node) {
- if (node.dependents.size() == 0) {
- printViewId(resources, node.view);
- } else {
- for (Node dependent : node.dependents.keySet()) {
- StringBuilder buffer = new StringBuilder();
- appendViewId(resources, node, buffer);
- printdependents(resources, dependent, buffer);
- }
- }
- }
-
- private static void printdependents(Resources resources, Node node, StringBuilder buffer) {
- buffer.append(" -> ");
- appendViewId(resources, node, buffer);
-
- if (node.dependents.size() == 0) {
- d(LOG_TAG, buffer.toString());
- } else {
- for (Node dependent : node.dependents.keySet()) {
- StringBuilder subBuffer = new StringBuilder(buffer);
- printdependents(resources, dependent, subBuffer);
- }
- }
- }
-
- /**
* A node in the dependency graph. A node is a view, its list of dependencies
* and its list of dependents.
*
@@ -1826,7 +1739,8 @@
* The list of dependents for this node; a dependent is a node
* that needs this node to be processed first.
*/
- final HashMap<Node, DependencyGraph> dependents = new HashMap<Node, DependencyGraph>();
+ final ArrayMap<Node, DependencyGraph> dependents =
+ new ArrayMap<Node, DependencyGraph>();
/**
* The list of dependencies for this node.
@@ -1839,7 +1753,8 @@
// The pool is static, so all nodes instances are shared across
// activities, that's why we give it a rather high limit
private static final int POOL_LIMIT = 100;
- private static final SimplePool<Node> sPool = new SimplePool<Node>(POOL_LIMIT);
+ private static final SynchronizedPool<Node> sPool =
+ new SynchronizedPool<Node>(POOL_LIMIT);
static Node acquire(View view) {
Node node = sPool.acquire();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index bc41931..0545d24 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -631,12 +631,13 @@
final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
(overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
+ // Calling overScrollBy will call onOverScrolled, which
+ // calls onScrollChanged if applicable.
if (overScrollBy(0, deltaY, 0, mScrollY,
0, range, 0, mOverscrollDistance, true)) {
// Break our velocity if we hit a scroll barrier.
mVelocityTracker.clear();
}
- onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (canOverscroll) {
final int pulledToY = oldY + deltaY;
@@ -753,9 +754,12 @@
boolean clampedX, boolean clampedY) {
// Treat animating scrolls differently; see #computeScroll() for why.
if (!mScroller.isFinished()) {
+ final int oldX = mScrollX;
+ final int oldY = mScrollY;
mScrollX = scrollX;
mScrollY = scrollY;
invalidateParentIfNeeded();
+ onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (clampedY) {
mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b1692d7..12d0c49 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -146,6 +146,13 @@
* view for editing.
*
* <p>
+ * To allow users to copy some or all of the TextView's value and paste it somewhere else, set the
+ * XML attribute {@link android.R.styleable#TextView_textIsSelectable
+ * android:textIsSelectable} to "true" or call
+ * {@link #setTextIsSelectable setTextIsSelectable(true)}. The {@code textIsSelectable} flag
+ * allows users to make selection gestures in the TextView, which in turn triggers the system's
+ * built-in copy/paste controls.
+ * <p>
* <b>XML attributes</b>
* <p>
* See {@link android.R.styleable#TextView TextView Attributes},
@@ -548,7 +555,6 @@
private InputFilter[] mFilters = NO_FILTERS;
private volatile Locale mCurrentSpellCheckerLocaleCache;
- private final ReentrantLock mCurrentTextServicesLocaleLock = new ReentrantLock();
// It is possible to have a selection even when mEditor is null (programmatically set, like when
// a link is pressed). These highlight-related fields do not go in mEditor.
@@ -4862,17 +4868,12 @@
}
/**
- * When a TextView is used to display a useful piece of information to the user (such as a
- * contact's address), it should be made selectable, so that the user can select and copy this
- * content.
*
- * Use {@link #setTextIsSelectable(boolean)} or the
- * {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
- * selectable (text is not selectable by default).
- *
- * Note that this method simply returns the state of this flag. Although this flag has to be set
- * in order to select text in non-editable TextView, the content of an {@link EditText} can
- * always be selected, independently of the value of this flag.
+ * Returns the state of the {@code textIsSelectable} flag (See
+ * {@link #setTextIsSelectable setTextIsSelectable()}). Although you have to set this flag
+ * to allow users to select and copy text in a non-editable TextView, the content of an
+ * {@link EditText} can always be selected, independently of the value of this flag.
+ * <p>
*
* @return True if the text displayed in this TextView can be selected by the user.
*
@@ -4883,16 +4884,28 @@
}
/**
- * Sets whether or not (default) the content of this view is selectable by the user.
+ * Sets whether the content of this view is selectable by the user. The default is
+ * {@code false}, meaning that the content is not selectable.
+ * <p>
+ * When you use a TextView to display a useful piece of information to the user (such as a
+ * contact's address), make it selectable, so that the user can select and copy its
+ * content. You can also use set the XML attribute
+ * {@link android.R.styleable#TextView_textIsSelectable} to "true".
+ * <p>
+ * When you call this method to set the value of {@code textIsSelectable}, it sets
+ * the flags {@code focusable}, {@code focusableInTouchMode}, {@code clickable},
+ * and {@code longClickable} to the same value. These flags correspond to the attributes
+ * {@link android.R.styleable#View_focusable android:focusable},
+ * {@link android.R.styleable#View_focusableInTouchMode android:focusableInTouchMode},
+ * {@link android.R.styleable#View_clickable android:clickable}, and
+ * {@link android.R.styleable#View_longClickable android:longClickable}. To restore any of these
+ * flags to a state you had set previously, call one or more of the following methods:
+ * {@link #setFocusable(boolean) setFocusable()},
+ * {@link #setFocusableInTouchMode(boolean) setFocusableInTouchMode()},
+ * {@link #setClickable(boolean) setClickable()} or
+ * {@link #setLongClickable(boolean) setLongClickable()}.
*
- * Note that this methods affect the {@link #setFocusable(boolean)},
- * {@link #setFocusableInTouchMode(boolean)} {@link #setClickable(boolean)} and
- * {@link #setLongClickable(boolean)} states and you may want to restore these if they were
- * customized.
- *
- * See {@link #isTextSelectable} for details.
- *
- * @param selectable Whether or not the content of this TextView should be selectable.
+ * @param selectable Whether the content of this TextView should be selectable.
*/
public void setTextIsSelectable(boolean selectable) {
if (!selectable && mEditor == null) return; // false is default value with no edit data
@@ -8023,16 +8036,13 @@
}
private void updateTextServicesLocaleAsync() {
+ // AsyncTask.execute() uses a serial executor which means we don't have
+ // to lock around updateTextServicesLocaleLocked() to prevent it from
+ // being executed n times in parallel.
AsyncTask.execute(new Runnable() {
@Override
public void run() {
- if (mCurrentTextServicesLocaleLock.tryLock()) {
- try {
- updateTextServicesLocaleLocked();
- } finally {
- mCurrentTextServicesLocaleLock.unlock();
- }
- }
+ updateTextServicesLocaleLocked();
}
});
}
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index e6796cb..e33c4d4 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -237,6 +237,7 @@
// update controls to initial state
updateHourControl();
+ updateMinuteControl();
updateAmPmControl();
setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
@@ -428,6 +429,7 @@
updateHourControl();
// set value after spinner range is updated
setCurrentHour(currentHour);
+ updateMinuteControl();
updateAmPmControl();
}
@@ -508,6 +510,14 @@
}
}
+ private void updateMinuteControl() {
+ if (is24HourView()) {
+ mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+ } else {
+ mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+ }
+ }
+
private void updateAmPmControl() {
if (is24HourView()) {
if (mAmPmSpinner != null) {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index acbb2b1..e092fff 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -1210,6 +1210,10 @@
mActionView.setIcon(icon);
}
+ public boolean hasIcon() {
+ return mActionView.hasIcon();
+ }
+
@Override
public void setLogo(int resId) {
mActionView.setLogo(resId);
@@ -1220,6 +1224,10 @@
mActionView.setLogo(logo);
}
+ public boolean hasLogo() {
+ return mActionView.hasLogo();
+ }
+
public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
if (!mDisplayHomeAsUpSet) {
setDisplayHomeAsUpEnabled(enable);
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index cf797bb..e300021 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -97,7 +97,7 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
- mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_ACTIVE_SCAN);
+ mRouter.addCallback(mRouteTypes, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index c22cd26..a674776 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.os.AsyncTask;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
@@ -621,9 +622,11 @@
view = mInflater.inflate(
com.android.internal.R.layout.resolve_list_item, parent, false);
+ final ViewHolder holder = new ViewHolder(view);
+ view.setTag(holder);
+
// Fix the icon size even if we have different sized resources
- ImageView icon = (ImageView)view.findViewById(R.id.icon);
- ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
+ ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
lp.width = lp.height = mIconSize;
} else {
view = convertView;
@@ -633,20 +636,30 @@
}
private final void bindView(View view, DisplayResolveInfo info) {
- TextView text = (TextView)view.findViewById(com.android.internal.R.id.text1);
- TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
- ImageView icon = (ImageView)view.findViewById(R.id.icon);
- text.setText(info.displayLabel);
+ final ViewHolder holder = (ViewHolder) view.getTag();
+ holder.text.setText(info.displayLabel);
if (mShowExtended) {
- text2.setVisibility(View.VISIBLE);
- text2.setText(info.extendedInfo);
+ holder.text2.setVisibility(View.VISIBLE);
+ holder.text2.setText(info.extendedInfo);
} else {
- text2.setVisibility(View.GONE);
+ holder.text2.setVisibility(View.GONE);
}
if (info.displayIcon == null) {
- info.displayIcon = loadIconForResolveInfo(info.ri);
+ new LoadIconTask().execute(info);
}
- icon.setImageDrawable(info.displayIcon);
+ holder.icon.setImageDrawable(info.displayIcon);
+ }
+ }
+
+ static class ViewHolder {
+ public TextView text;
+ public TextView text2;
+ public ImageView icon;
+
+ public ViewHolder(View view) {
+ text = (TextView) view.findViewById(com.android.internal.R.id.text1);
+ text2 = (TextView) view.findViewById(com.android.internal.R.id.text2);
+ icon = (ImageView) view.findViewById(R.id.icon);
}
}
@@ -660,5 +673,21 @@
}
}
+
+ class LoadIconTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> {
+ @Override
+ protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) {
+ final DisplayResolveInfo info = params[0];
+ if (info.displayIcon == null) {
+ info.displayIcon = loadIconForResolveInfo(info.ri);
+ }
+ return info;
+ }
+
+ @Override
+ protected void onPostExecute(DisplayResolveInfo info) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 38391df..601d3ac4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1579,9 +1579,7 @@
for (int i = 0; i < size; i++) {
entry = uidStats.getValues(i, entry);
- final Uid u = mUidStats.get(entry.uid);
- if (u == null) continue;
-
+ final Uid u = getUidStatsLocked(entry.uid);
u.mStartedTcpBytesReceived = entry.rxBytes;
u.mStartedTcpBytesSent = entry.txBytes;
u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 95130c8..70e2bfc 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -17,12 +17,13 @@
package com.android.internal.view;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Handler;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -40,6 +41,21 @@
}
/**
+ * Gets whether the device supports rotation. In general such a
+ * device has an accelerometer and has the portrait and landscape
+ * features.
+ *
+ * @param context Context for accessing system resources.
+ * @return Whether the device supports rotation.
+ */
+ public static boolean isRotationSupported(Context context) {
+ PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)
+ && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)
+ && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+ }
+
+ /**
* Returns true if the device supports the rotation-lock toggle feature
* in the system UI or system bar.
*
@@ -48,7 +64,8 @@
* settings.
*/
public static boolean isRotationLockToggleSupported(Context context) {
- return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
+ return isRotationSupported(context)
+ && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
/**
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index dda1a10..f2bd522 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -16,24 +16,12 @@
package com.android.internal.widget;
-import com.android.internal.R;
-import com.android.internal.view.menu.ActionMenuItem;
-import com.android.internal.view.menu.ActionMenuPresenter;
-import com.android.internal.view.menu.ActionMenuView;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuPresenter;
-import com.android.internal.view.menu.MenuView;
-import com.android.internal.view.menu.SubMenuBuilder;
-
import android.animation.LayoutTransition;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
-import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -42,7 +30,6 @@
import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.CollapsibleActionView;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -62,6 +49,15 @@
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
+import com.android.internal.R;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.view.menu.ActionMenuPresenter;
+import com.android.internal.view.menu.ActionMenuView;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
/**
* @hide
@@ -188,34 +184,8 @@
ActionBar.NAVIGATION_MODE_STANDARD);
mTitle = a.getText(R.styleable.ActionBar_title);
mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
-
mLogo = a.getDrawable(R.styleable.ActionBar_logo);
- if (mLogo == null) {
- if (context instanceof Activity) {
- try {
- mLogo = pm.getActivityLogo(((Activity) context).getComponentName());
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Activity component name not found!", e);
- }
- }
- if (mLogo == null) {
- mLogo = appInfo.loadLogo(pm);
- }
- }
-
mIcon = a.getDrawable(R.styleable.ActionBar_icon);
- if (mIcon == null) {
- if (context instanceof Activity) {
- try {
- mIcon = pm.getActivityIcon(((Activity) context).getComponentName());
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Activity component name not found!", e);
- }
- }
- if (mIcon == null) {
- mIcon = appInfo.loadIcon(pm);
- }
- }
final LayoutInflater inflater = LayoutInflater.from(context);
@@ -729,7 +699,11 @@
}
public void setIcon(int resId) {
- setIcon(mContext.getResources().getDrawable(resId));
+ setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+ }
+
+ public boolean hasIcon() {
+ return mIcon != null;
}
public void setLogo(Drawable logo) {
@@ -740,7 +714,11 @@
}
public void setLogo(int resId) {
- setLogo(mContext.getResources().getDrawable(resId));
+ setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+ }
+
+ public boolean hasLogo() {
+ return mLogo != null;
}
public void setNavigationMode(int mode) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index febccb4..188941b 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -17,6 +17,10 @@
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+# When built as part of the system image we can enable certian non-NDK compliant
+# Skia optimizations.
+LOCAL_CFLAGS += -DSK_BUILD_FOR_ANDROID_FRAMEWORK
+
LOCAL_SRC_FILES:= \
AndroidRuntime.cpp \
Time.cpp \
@@ -159,10 +163,6 @@
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
$(TOP)/frameworks/av/include \
- external/skia/include/core \
- external/skia/include/effects \
- external/skia/include/images \
- external/skia/include/ports \
external/skia/src/core \
external/skia/src/images \
external/skia/include/utils \
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 5454c08..380f061 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -58,6 +58,10 @@
static void defaultSettingsForAndroid(SkPaint* paint) {
// GlyphID encoding is required because we are using Harfbuzz shaping
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+ SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
+ paintOpts.setUseFontFallbacks(true);
+ paint->setPaintOptionsAndroid(paintOpts);
}
class SkPaintGlue {
@@ -300,7 +304,10 @@
ScopedUtfChars localeChars(env, locale);
char langTag[ULOC_FULLNAME_CAPACITY];
toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
- obj->setLanguage(SkLanguage(langTag));
+
+ SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
+ paintOpts.setLanguage(langTag);
+ obj->setPaintOptionsAndroid(paintOpts);
}
static jfloat getTextSize(JNIEnv* env, jobject paint) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index cd84fff..73f3639 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -218,7 +218,8 @@
*/
TextLayoutCacheKey::TextLayoutCacheKey(): start(0), count(0), contextCount(0),
dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
- hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language() {
+ hinting(SkPaint::kNo_Hinting) {
+ paintOpts.setUseFontFallbacks(true);
}
TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
@@ -232,8 +233,7 @@
textScaleX = paint->getTextScaleX();
flags = paint->getFlags();
hinting = paint->getHinting();
- variant = paint->getFontVariant();
- language = paint->getLanguage();
+ paintOpts = paint->getPaintOptionsAndroid();
}
TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
@@ -248,8 +248,7 @@
textScaleX(other.textScaleX),
flags(other.flags),
hinting(other.hinting),
- variant(other.variant),
- language(other.language) {
+ paintOpts(other.paintOpts) {
}
int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
@@ -283,11 +282,8 @@
deltaInt = lhs.dirFlags - rhs.dirFlags;
if (deltaInt) return (deltaInt);
- deltaInt = lhs.variant - rhs.variant;
- if (deltaInt) return (deltaInt);
-
- if (lhs.language < rhs.language) return -1;
- if (lhs.language > rhs.language) return +1;
+ if (lhs.paintOpts != rhs.paintOpts)
+ return memcmp(&lhs.paintOpts, &rhs.paintOpts, sizeof(SkPaintOptionsAndroid));
return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
}
@@ -306,7 +302,7 @@
hash = JenkinsHashMix(hash, hash_type(textScaleX));
hash = JenkinsHashMix(hash, flags);
hash = JenkinsHashMix(hash, hinting);
- hash = JenkinsHashMix(hash, variant);
+ hash = JenkinsHashMix(hash, paintOpts.getFontVariant());
// Note: leaving out language is not problematic, as equality comparisons
// are still valid - the only bad thing that could happen is collisions.
hash = JenkinsHashMixShorts(hash, getText(), contextCount);
@@ -698,8 +694,7 @@
mShapingPaint.setTextScaleX(paint->getTextScaleX());
mShapingPaint.setFlags(paint->getFlags());
mShapingPaint.setHinting(paint->getHinting());
- mShapingPaint.setFontVariant(paint->getFontVariant());
- mShapingPaint.setLanguage(paint->getLanguage());
+ mShapingPaint.setPaintOptionsAndroid(paint->getPaintOptionsAndroid());
// Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script
// into the shaperItem
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index ab6ac72..54704ec 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -28,7 +28,6 @@
#include <utils/Singleton.h>
#include <SkAutoKern.h>
-#include <SkLanguage.h>
#include <SkPaint.h>
#include <SkTemplates.h>
#include <SkTypeface.h>
@@ -104,8 +103,7 @@
SkScalar textScaleX;
uint32_t flags;
SkPaint::Hinting hinting;
- SkPaint::FontVariant variant;
- SkLanguage language;
+ SkPaintOptionsAndroid paintOpts;
}; // TextLayoutCacheKey
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 9537ac4..08962e2 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -33,11 +33,11 @@
static jint DBG = false;
-static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
+static int doCommand(const char *ifname, char *cmd, char *replybuf, int replybuflen)
{
size_t reply_len = replybuflen - 1;
- if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
+ if (::wifi_command(ifname, cmd, BUF_SIZE, replybuf, &reply_len) != 0)
return -1;
else {
// Strip off trailing newline
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 5d32328..61eb31b 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -99,6 +99,11 @@
return getpid();
}
+jint android_os_Process_myPpid(JNIEnv* env, jobject clazz)
+{
+ return getppid();
+}
+
jint android_os_Process_myUid(JNIEnv* env, jobject clazz)
{
return getuid();
@@ -990,6 +995,7 @@
static const JNINativeMethod methods[] = {
{"myPid", "()I", (void*)android_os_Process_myPid},
+ {"myPpid", "()I", (void*)android_os_Process_myPpid},
{"myTid", "()I", (void*)android_os_Process_myTid},
{"myUid", "()I", (void*)android_os_Process_myUid},
{"getUidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3443d6e..6918099 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2298,8 +2298,7 @@
<activity android:name="android.accounts.CantAddAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.Dialog"
- android:label="@string/error_message_title"
+ android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"
android:process=":ui">
</activity>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index c3b1ac5..39915f9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
<string name="owner_name" msgid="2716755460376028154">"Eienaar"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Hierdie program werk nie met rekeninge vir beperkte profiele nie"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Geen program gevind om hierdie handeling te hanteer nie"</string>
<string name="revoke" msgid="5404479185228271586">"Herroep"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 12cfbf4..327f1cb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
<string name="owner_name" msgid="2716755460376028154">"ባለቤት"</string>
<string name="error_message_title" msgid="4510373083082500195">"ስህተት"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"ይህ መተግበሪያ የተገደቡ መገለጫዎች መለያዎችን አይደግፍም"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም"</string>
<string name="revoke" msgid="5404479185228271586">"ሻር"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 50c143b..19f2d6a 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -556,7 +556,7 @@
<string name="permlab_useCredentials" msgid="235481396163877642">"استخدام الحسابات على الجهاز"</string>
<string name="permdesc_useCredentials" msgid="7984227147403346422">"للسماح للتطبيق بطلب الرموز المميزة للمصادقة."</string>
<string name="permlab_accessNetworkState" msgid="4951027964348974773">"عرض اتصالات الشبكة"</string>
- <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"للمساح للتطبيق بعرض معلومات حول اتصالات الشبكة كعرض معلومات عن الشبكات المتوفرة والشبكات المتصلة."</string>
+ <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"للسماح للتطبيق بعرض معلومات حول اتصالات الشبكة كعرض معلومات عن الشبكات المتوفرة والشبكات المتصلة."</string>
<string name="permlab_createNetworkSockets" msgid="8018758136404323658">"إمكانية دخول كاملة إلى الشبكة"</string>
<string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"للسماح للتطبيق بإنشاء مقابس شبكات واستخدام بروتوكولات شبكات مخصصة. ويوفر المتصفح وتطبيقات أخرى طرقًا لإرسال البيانات إلى الإنترنت، ولذلك لا يعد هذا الإذن مطلوبًا لإرسال البيانات إلى الإنترنت."</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"تغيير/اعتراض إعدادات الشبكة وحركة المرور"</string>
@@ -572,8 +572,8 @@
<string name="permlab_changeWifiState" msgid="6550641188749128035">"التوصيل والفصل من Wi-Fi"</string>
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"للسماح للتطبيق بالاتصال بنقاط الوصول إلى Wi-Fi وقطع الاتصال بها، وإجراء تغييرات على تهيئة الجهاز لشبكات Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"السماح باستقبال بث Wi-Fi متعدد"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"للمساح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهازك اللوحي فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"للمساح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام جهازك اللوحي فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"للسماح للتطبيق بتلقي الحزم التي يتم إرسالها إلى جميع الأجهزة على شبكة Wi-Fi باستخدام عناوين بث متعدد، وليس باستخدام هاتفك فقط. ويؤدي ذلك إلى استخدام قدر أكبر من الطاقة يفوق وضع البث غير المتعدد."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"الدخول إلى إعدادات بلوتوث"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"المالك"</string>
<string name="error_message_title" msgid="4510373083082500195">"خطأ"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"هذا التطبيق لا يتوافق مع حسابات الملفات الشخصية المقيدة"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"لا يتوافق هذا التطبيق مع حسابات الملفات الشخصية المقيدة"</string>
<string name="app_not_found" msgid="3429141853498927379">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
<string name="revoke" msgid="5404479185228271586">"إلغاء"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 5cb4c43..ab0db23 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Уладальнік"</string>
<string name="error_message_title" msgid="4510373083082500195">"Памылка"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Гэтае прыкладанне не падтрымлівае уліковыя запісы для карыстальнікаў з абмежаваннямi"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Гэта прыкладанне не падтрымлівае ўліковыя запісы для профiляў з абмежаваннямі"</string>
<string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
<string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index afa6c11..4d8a5cc 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Собственик"</string>
<string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Това приложение не поддържа профили за потребителски профили с ограничена функционалност"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Няма намерено приложение за извършване на това действие"</string>
<string name="revoke" msgid="5404479185228271586">"Отмяна"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index aaa911d..4eaf068 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -565,8 +565,8 @@
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permet que l\'aplicació pugui canviar l\'estat de connectivitat de la xarxa."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"Canvia la connectivitat d\'ancoratge a xarxa"</string>
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permet que l\'aplicació canviï l\'estat de la connectivitat de la xarxa d\'ancoratge."</string>
- <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"canviar la configuració d\'ús de dades de referència"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Permet que l\'aplicació canviï la configuració d\'ús de les dades de fons."</string>
+ <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"canviar la configuració d\'ús de dades en segon pla"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Permet que l\'aplicació canviï la configuració d\'ús de les dades en segon pla."</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"veure connexions Wi-Fi"</string>
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permet que l\'aplicació visualitzi informació sobre les xarxes Wi-Fi, com ara si la Wi-Fi està activada i el nom dels dispositius Wi-Fi connectats."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"connectar-se a xarxes Wi-Fi i desconnectar-se"</string>
@@ -1406,7 +1406,7 @@
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"S\'ha superat el límit de dades mòbils"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"S\'ha superat el límit de dades Wi-Fi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> per sobre del límit especif."</string>
- <string name="data_usage_restricted_title" msgid="5965157361036321914">"Dades de referència restringides"</string>
+ <string name="data_usage_restricted_title" msgid="5965157361036321914">"Dades en segon pla restringides"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"Toca per eliminar la restricció."</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Certificat de seguretat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Aquest certificat és vàlid."</string>
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Propietari"</string>
<string name="error_message_title" msgid="4510373083082500195">"Error"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"L\'aplicació no és compatible amb comptes de perfils restringits."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"No s\'ha trobat cap aplicació per processar aquesta acció"</string>
<string name="revoke" msgid="5404479185228271586">"Revoca"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index abe6dad..91498cd 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
<string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Tato aplikace nepodporuje účty pro omezené profily."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Aplikace potřebná k provedení této akce nebyla nalezena"</string>
<string name="revoke" msgid="5404479185228271586">"Zrušit"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e00597a..081fd2a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Ejer"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fejl"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Denne applikation understøtter ikke konti for begrænsede profiler"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Der blev ikke fundet nogen applikation, der kan håndtere denne handling"</string>
<string name="revoke" msgid="5404479185228271586">"Tilbagekald"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 655d5d0..53db449 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -940,7 +940,7 @@
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
<plurals name="num_seconds_ago">
- <item quantity="one" msgid="4869870056547896011">"Vor 1 Sekunde"</item>
+ <item quantity="one" msgid="4869870056547896011">"vor 1 Sekunde"</item>
<item quantity="other" msgid="3903706804349556379">"vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item>
</plurals>
<plurals name="num_minutes_ago">
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Eigentümer"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fehler"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Diese App unterstützt keine Konten für eingeschränkte Profile."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Für diese Aktion wurde keine App gefunden."</string>
<string name="revoke" msgid="5404479185228271586">"Aufheben"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 5135847..78a707f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Κάτοχος"</string>
<string name="error_message_title" msgid="4510373083082500195">"Σφάλμα"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Αυτή η εφαρμογή δεν υποστηρίζει λογαριασμούς για περιορισμένα προφίλ"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Δεν υπάρχει εφαρμογή για τη διαχείριση αυτής της ενέργειας"</string>
<string name="revoke" msgid="5404479185228271586">"Ανάκληση"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 2d5e70c..b8c0d50 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Owner"</string>
<string name="error_message_title" msgid="4510373083082500195">"Error"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"This application does not support accounts for restricted profiles"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"This app doesn\'t support accounts for restricted profiles"</string>
<string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
<string name="revoke" msgid="5404479185228271586">"Revoke"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 501d56f..49f6e1f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
<string name="error_message_title" msgid="4510373083082500195">"Error"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicación no admite cuentas de perfiles restringidos."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"No se encontró una aplicación para manejar esta acción."</string>
<string name="revoke" msgid="5404479185228271586">"Revocar"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0685e66..0a704c3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
<string name="error_message_title" msgid="4510373083082500195">"Error"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicación no admite cuentas de perfiles restringidos"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
<string name="revoke" msgid="5404479185228271586">"Revocar"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b1997d1..8f6911c 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Omanik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Viga"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"See rakendus ei toeta piiratud profiilide kontosid"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
<string name="revoke" msgid="5404479185228271586">"Tühista"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b47bf9f..170e9ae 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"دارنده"</string>
<string name="error_message_title" msgid="4510373083082500195">"خطا"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"این برنامه از حسابهای متعلق به نمایههای محدود پشتیبانی نمیکند"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"این برنامه از حسابهای متعلق به نمایههای محدود پشتیبانی نمیکند"</string>
<string name="app_not_found" msgid="3429141853498927379">"برنامهای برای انجام این عملکرد موجود نیست"</string>
<string name="revoke" msgid="5404479185228271586">"لغو"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index feeed53..15a5f95 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Omistaja"</string>
<string name="error_message_title" msgid="4510373083082500195">"Virhe"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Tämä sovellus ei tue rajoitettujen profiilien tilejä"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Tätä toimintoa käsittelevää sovellusta ei löydy"</string>
<string name="revoke" msgid="5404479185228271586">"Peruuta"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 97e0a82..9afa938 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
<string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Les comptes des profils limités ne sont pas acceptés pour cette application."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
<string name="revoke" msgid="5404479185228271586">"Révoquer"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index b135c2e..4df3a5b 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"स्वामी"</string>
<string name="error_message_title" msgid="4510373083082500195">"त्रुटि"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"यह एप्लिकेशन प्रतिबंधित प्रोफ़ाइल के खातों का समर्थन नहीं करता है"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई एप्लिकेशन नहीं मिला"</string>
<string name="revoke" msgid="5404479185228271586">"निरस्त करें"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f033a16..a7208ee 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Pogreška"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Aplikacija ne podržava račune za ograničene profile"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija za upravljanje ovom radnjom"</string>
<string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 516241f..3060fd1 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
<string name="owner_name" msgid="2716755460376028154">"Tulajdonos"</string>
<string name="error_message_title" msgid="4510373083082500195">"Hiba"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ez az alkalmazás nem támogatja a korlátozott profilokkal rendelkező fiókokat"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
<string name="revoke" msgid="5404479185228271586">"Visszavonás"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 812d016..5504078 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Kesalahan"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Aplikasi ini tidak mendukung akun untuk profil yang dibatasi"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Tidak ada aplikasi yang ditemukan untuk menangani tindakan ini"</string>
<string name="revoke" msgid="5404479185228271586">"Cabut"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 05bed06..a1e8bfc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietario"</string>
<string name="error_message_title" msgid="4510373083082500195">"Errore"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Questa applicazione non supporta account relativi a profili con limitazioni"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nessuna applicazione trovata in grado di gestire questa azione"</string>
<string name="revoke" msgid="5404479185228271586">"Revoca"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1e0e204..d48f846 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"בעלים"</string>
<string name="error_message_title" msgid="4510373083082500195">"שגיאה"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"היישום הזה לא תומך בחשבונות עבור פרופילים מוגבלים"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"לא נמצא יישום שתומך בפעולה זו"</string>
<string name="revoke" msgid="5404479185228271586">"בטל"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3241159..9932924 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
<string name="owner_name" msgid="2716755460376028154">"所有者"</string>
<string name="error_message_title" msgid="4510373083082500195">"エラー"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"このアプリでは制限付きプロフィールのアカウントはサポートしていません"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"この操作を行うアプリが見つかりません"</string>
<string name="revoke" msgid="5404479185228271586">"取り消し"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b6e07c8..f66fb33 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
<string name="owner_name" msgid="2716755460376028154">"소유자"</string>
<string name="error_message_title" msgid="4510373083082500195">"오류"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"이 애플리케이션은 제한된 프로필의 계정을 지원하지 않습니다."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"이 작업을 처리하는 애플리케이션을 찾을 수 없습니다."</string>
<string name="revoke" msgid="5404479185228271586">"취소"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2ad0598..d4019f3 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Savininkas"</string>
<string name="error_message_title" msgid="4510373083082500195">"Klaida"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ši programa nepalaiko apribotų profilių paskyrų"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nerasta programa šiam veiksmui apdoroti"</string>
<string name="revoke" msgid="5404479185228271586">"Anuliuoti"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index de30037..dac8a7b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Īpašnieks"</string>
<string name="error_message_title" msgid="4510373083082500195">"Kļūda"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Šajā lietojumprogrammā netiek atbalstīti ierobežotu profilu konti."</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Netika atrasta neviena lietojumprogramma, kas var veikt šo darbību."</string>
<string name="revoke" msgid="5404479185228271586">"Atsaukt"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index b518ea9..bcc9493 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Ralat"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Apl ini tidak menyokong akaun untuk profil yang disekat"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
<string name="revoke" msgid="5404479185228271586">"Batalkan"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 080a05c..5993cc9 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Eier"</string>
<string name="error_message_title" msgid="4510373083082500195">"Feil"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Denne appen støtter ikke kontoer for begrensede profiler"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Finner ingen apper som kan utføre denne handlingen"</string>
<string name="revoke" msgid="5404479185228271586">"Opphev"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 299658e..b8e5deb 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Deze app biedt geen ondersteuning voor accounts voor beperkte profielen"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
<string name="revoke" msgid="5404479185228271586">"Intrekken"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index babfe61..642237c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -52,9 +52,9 @@
<string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
<string name="imei" msgid="2625429890869005782">"IMEI"</string>
<string name="meid" msgid="4841221237681254195">"MEID"</string>
- <string name="ClipMmi" msgid="6952821216480289285">"Identyfikator rozmówcy przy połączeniach przychodzących"</string>
- <string name="ClirMmi" msgid="7784673673446833091">"Identyfikator rozmówcy przy połączeniach wychodzących"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Przekazywanie połączeń"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"Nazwa rozmówcy przy połączeniach przychodzących"</string>
+ <string name="ClirMmi" msgid="7784673673446833091">"Nazwa rozmówcy przy połączeniach wychodzących"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Przekierowanie połączeń"</string>
<string name="CwMmi" msgid="9129678056795016867">"Połączenia oczekujące"</string>
<string name="BaMmi" msgid="455193067926770581">"Blokada dzwonienia"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Zmiana hasła"</string>
@@ -65,10 +65,10 @@
<string name="RuacMmi" msgid="7827887459138308886">"Odrzucanie niepożądanych, irytujących połączeń"</string>
<string name="CndMmi" msgid="3116446237081575808">"Dostarczanie numeru telefonującego"</string>
<string name="DndMmi" msgid="1265478932418334331">"Nie przeszkadzać"</string>
- <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Identyfikator rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
- <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Identyfikator rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Identyfikator rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Identyfikator rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+ <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+ <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Nazwa rozmówcy ustawiona jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Nazwa rozmówcy ustawiona jest domyślnie na „nie zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Usługa nie jest świadczona."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Nie możesz zmienić ustawienia identyfikatora rozmówcy."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Zmieniono ograniczenie dostępu"</string>
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Właściciel"</string>
<string name="error_message_title" msgid="4510373083082500195">"Błąd"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ta aplikacja nie obsługuje kont w przypadku profili z ograniczeniami"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nie znaleziono aplikacji do obsługi tej akcji"</string>
<string name="revoke" msgid="5404479185228271586">"Cofnij"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 6d76248..ff912b9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
<string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicação não suporta contas de perfis restritos"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Não foram encontradas aplicações para executar esta ação"</string>
<string name="revoke" msgid="5404479185228271586">"Revogar"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 252fc27..9698884 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -205,7 +205,7 @@
<string name="permgrouplab_appInfo" msgid="8028789762634147725">"Informações sobre seus aplicativos"</string>
<string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Capacidade de afetar o comportamento de outros aplicativos no dispositivo."</string>
<string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Plano de fundo"</string>
- <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Alterar as configurações de papel de parede do dispositivo."</string>
+ <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Alterar as configurações de plano de fundo do dispositivo."</string>
<string name="permgrouplab_systemClock" msgid="406535759236612992">"Relógio"</string>
<string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Alterar a hora ou fuso horário no dispositivo."</string>
<string name="permgrouplab_statusBar" msgid="2095862568113945398">"Barra de status"</string>
@@ -533,7 +533,7 @@
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Executa como um teste do fabricante de nível inferior, permitindo o acesso completo ao hardware do tablet. Disponível apenas quando um tablet está em execução no modo de teste do fabricante."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Executa como um teste do fabricante de nível inferior, permitindo o acesso completo ao hardware do telefone. Disponível apenas quando um telefone está em execução no modo de teste do fabricante."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"definir plano de fundo"</string>
- <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permite que o aplicativo defina o papel de parede do sistema."</string>
+ <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permite que o aplicativo defina o plano de fundo do sistema."</string>
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"ajustar tamanho do plano de fundo"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Permite que o aplicativo defina as dicas de tamanho do plano de fundo do sistema."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"redefinir o sistema para os padrões de fábrica"</string>
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
<string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Este aplicativo não suporta contas para perfis restritos"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nenhum aplicativo encontrado para executar a ação"</string>
<string name="revoke" msgid="5404479185228271586">"Revogar"</string>
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 4404d875..b2a0bca 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -2435,7 +2435,7 @@
<skip />
<!-- no translation found for error_message_title (4510373083082500195) -->
<skip />
- <!-- no translation found for app_no_restricted_accounts (4011285085817350390) -->
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
<skip />
<!-- no translation found for app_not_found (3429141853498927379) -->
<skip />
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 4267fe1..b7866f6 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Proprietar"</string>
<string name="error_message_title" msgid="4510373083082500195">"Eroare"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Această aplicație nu acceptă conturi pentru profilurile cu permisiuni limitate"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Nicio aplicație pentru gestionarea acestei acțiuni"</string>
<string name="revoke" msgid="5404479185228271586">"Revocați"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b05bef7..3b8b907 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Владелец"</string>
<string name="error_message_title" msgid="4510373083082500195">"Ошибка"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Это приложение не поддерживается в аккаунтах для профилей с ограниченным доступом"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Невозможно обработать это действие"</string>
<string name="revoke" msgid="5404479185228271586">"Отменить"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 96b44f7..2d62a47 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
<string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Táto aplikácia nepodporuje účty pre profily s obmedzením"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Táto aplikácia nepodporuje účty pre profily s obmedzením"</string>
<string name="app_not_found" msgid="3429141853498927379">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla"</string>
<string name="revoke" msgid="5404479185228271586">"Odvolať"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5280b06..fd0b91f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Lastnik"</string>
<string name="error_message_title" msgid="4510373083082500195">"Napaka"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ta aplikacija ne podpira računov za profile z omejitvami"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Najdena ni bila nobena aplikacija za izvedbo tega dejanja"</string>
<string name="revoke" msgid="5404479185228271586">"Prekliči"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 79a3d87..742375f 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Власник"</string>
<string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ова апликација не подржава налоге за ограничене профиле"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
<string name="revoke" msgid="5404479185228271586">"Опозови"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0775d0a..1a316bd 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Ägare"</string>
<string name="error_message_title" msgid="4510373083082500195">"Fel"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Den här appen stöder inte konton för begränsade profiler"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Ingen app som kan hantera åtgärden hittades"</string>
<string name="revoke" msgid="5404479185228271586">"Återkalla"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 450e6a3..bf03bdc 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Mmiliki"</string>
<string name="error_message_title" msgid="4510373083082500195">"Hitilafu"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Programu hii haiwezi kutumiwa na akaunti za wasifu zilizowekewa vikwazo"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
<string name="revoke" msgid="5404479185228271586">"Batilisha"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index fd3ab94..f917448 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="owner_name" msgid="2716755460376028154">"เจ้าของ"</string>
<string name="error_message_title" msgid="4510373083082500195">"ข้อผิดพลาด"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"แอปพลิเคชันนี้ไม่สนับสนุนบัญชีที่มีโปรไฟล์ที่ถูกจำกัด"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"แอปนี้ไม่สนับสนุนบัญชีที่มีโปรไฟล์ที่ถูกจำกัด"</string>
<string name="app_not_found" msgid="3429141853498927379">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
<string name="revoke" msgid="5404479185228271586">"เพิกถอน"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ce46219..53aaa0e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"May-ari"</string>
<string name="error_message_title" msgid="4510373083082500195">"Error"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Hindi sinusuportahan ng application na ito ang mga account para sa mga pinaghihigpitang profile"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Walang nakitang application na mangangasiwa sa pagkilos na ito"</string>
<string name="revoke" msgid="5404479185228271586">"Bawiin"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c6e8519..1c25ab7 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Sahibi"</string>
<string name="error_message_title" msgid="4510373083082500195">"Hata"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Bu uygulama kısıtlanmış profillerin hesaplarını desteklemez"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
<string name="revoke" msgid="5404479185228271586">"İptal et"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 216a9b1..9070582 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Власник"</string>
<string name="error_message_title" msgid="4510373083082500195">"Помилка"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ця програма не підтримує облікові записи для обмежених профілів"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Не знайдено програму для обробки цієї дії"</string>
<string name="revoke" msgid="5404479185228271586">"Анулювати"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7f076b9..5d4f0a7 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Chủ sở hữu"</string>
<string name="error_message_title" msgid="4510373083082500195">"Lỗi"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ứng dụng này không hỗ trợ tài khoản cho các tiểu sử bị hạn chế"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string>
<string name="revoke" msgid="5404479185228271586">"Thu hồi"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 2e93751..9878860 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -451,17 +451,17 @@
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"允许安装位置信息提供程序"</string>
<string name="permdesc_installLocationProvider" msgid="9066146120470591509">"创建用于测试的模拟位置源或安装新的位置提供程序。此权限可让该应用覆盖由其他位置源(如 GPS)或位置提供程序返回的位置和/或状态信息。"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"精确位置(基于 GPS 和网络)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"允许该应用通过全球定位系统 (GPS) 或网络位置信息源(例如基站和 Wi-Fi)获取您的精确位置信息。您必须在设备上开启这些位置服务,应用才能获得位置信息。应用会使用此类服务确定您的位置,这可能会消耗更多电量。"</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"允许该应用通过全球定位系统 (GPS) 或网络位置信息源(例如基站和 WLAN)获取您的精确位置信息。您必须在设备上开启这些位置服务,应用才能获得位置信息。应用会使用此类服务确定您的位置,这可能会消耗更多电量。"</string>
<string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"大致位置(基于网络)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"允许该应用获取您的大致位置信息。这类位置信息来自于使用网络位置信息源(例如基站和 Wi-Fi)的位置服务。您必须在设备上开启这些位置服务,应用才能获得位置信息。应用会使用此类服务确定您的大概位置。"</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"允许该应用获取您的大致位置信息。这类位置信息来自于使用网络位置信息源(例如基站和 WLAN)的位置服务。您必须在设备上开启这些位置服务,应用才能获得位置信息。应用会使用此类服务确定您的大概位置。"</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"访问 SurfaceFlinger"</string>
<string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允许应用使用 SurfaceFlinger 低级功能。"</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"读取帧缓冲区"</string>
<string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允许应用读取帧缓冲区的内容。"</string>
- <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"配置 Wi-Fi 显示设备"</string>
- <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到 Wi-Fi 显示设备。"</string>
- <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 Wi-Fi 显示设备"</string>
- <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制 Wi-Fi 显示设备的基础功能。"</string>
+ <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"配置 WLAN 显示设备"</string>
+ <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到 WLAN 显示设备。"</string>
+ <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WLAN 显示设备"</string>
+ <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制 WLAN 显示设备的基础功能。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"更改您的音频设置"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允许该应用修改全局音频设置,例如音量和用于输出的扬声器。"</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"录音"</string>
@@ -567,13 +567,13 @@
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"允许应用更改绑定网络连接的状态。"</string>
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"更改后台数据使用设置"</string>
<string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允许应用更改后台数据使用设置。"</string>
- <string name="permlab_accessWifiState" msgid="5202012949247040011">"查看 Wi-Fi 连接"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"允许该应用查看 Wi-Fi 网络的相关信息,例如是否启用了 Wi-Fi 以及连接的 Wi-Fi 设备的名称。"</string>
- <string name="permlab_changeWifiState" msgid="6550641188749128035">"连接 Wi-Fi 和断开连接"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"允许该应用与 Wi-Fi 接入点建立和断开连接,以及更改 Wi-Fi 网络的设备配置。"</string>
- <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"允许接收 Wi-Fi 多播"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"允许该应用使用多播地址接收发送到 Wi-Fi 网络上所有设备(而不仅仅是您的平板电脑)的数据包。该操作的耗电量比非多播模式要大。"</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"允许该应用使用多播地址接收发送到 Wi-Fi 网络上所有设备(而不仅仅是您的手机)的数据包。该操作的耗电量比非多播模式要大。"</string>
+ <string name="permlab_accessWifiState" msgid="5202012949247040011">"查看 WLAN 连接"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"允许该应用查看 WLAN 网络的相关信息,例如是否启用了 WLAN 以及连接的 WLAN 设备的名称。"</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"连接 WLAN 和断开连接"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"允许该应用与 WLAN 接入点建立和断开连接,以及更改 WLAN 网络的设备配置。"</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"允许接收 WLAN 多播"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"允许该应用使用多播地址接收发送到 WLAN 网络上所有设备(而不仅仅是您的平板电脑)的数据包。该操作的耗电量比非多播模式要大。"</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"允许该应用使用多播地址接收发送到 WLAN 网络上所有设备(而不仅仅是您的手机)的数据包。该操作的耗电量比非多播模式要大。"</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"访问蓝牙设置"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允许应用配置本地蓝牙平板电脑,以及发现远程设备并进行配对。"</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"允许应用配置本地蓝牙手机,以及发现远程设备并进行配对。"</string>
@@ -1130,23 +1130,23 @@
<string name="ringtone_picker_title" msgid="3515143939175119094">"铃声"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"未知铃声"</string>
<plurals name="wifi_available">
- <item quantity="one" msgid="6654123987418168693">"有可用的 Wi-Fi 网络"</item>
- <item quantity="other" msgid="4192424489168397386">"有可用的 Wi-Fi 网络"</item>
+ <item quantity="one" msgid="6654123987418168693">"有可用的 WLAN 网络"</item>
+ <item quantity="other" msgid="4192424489168397386">"有可用的 WLAN 网络"</item>
</plurals>
<plurals name="wifi_available_detailed">
- <item quantity="one" msgid="1634101450343277345">"打开可用的 Wi-Fi 网络"</item>
- <item quantity="other" msgid="7915895323644292768">"打开可用的 Wi-Fi 网络"</item>
+ <item quantity="one" msgid="1634101450343277345">"打开可用的 WLAN 网络"</item>
+ <item quantity="other" msgid="7915895323644292768">"打开可用的 WLAN 网络"</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="4029489716605255386">"登录到 Wi-Fi 网络"</string>
+ <string name="wifi_available_sign_in" msgid="4029489716605255386">"登录到 WLAN 网络"</string>
<string name="network_available_sign_in" msgid="8495155593358054676">"登录网络"</string>
<!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
<skip />
- <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到 Wi-Fi"</string>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到 WLAN"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互联网连接状况不佳。"</string>
- <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
- <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动 Wi-Fi Direct。此操作将会关闭 Wi-Fi 客户端/热点。"</string>
- <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动 Wi-Fi Direct。"</string>
- <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用 Wi-Fi Direct"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WLAN Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动 WLAN Direct。此操作将会关闭 WLAN 客户端/热点。"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动 WLAN Direct。"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用 WLAN Direct"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"通过触摸进行设置"</string>
<string name="accept" msgid="1645267259272829559">"接受"</string>
<string name="decline" msgid="2112225451706137894">"拒绝"</string>
@@ -1156,8 +1156,8 @@
<string name="wifi_p2p_to_message" msgid="248968974522044099">"收件人:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"键入所需的 PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"平板电脑连接到“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”时会暂时断开与 Wi-Fi 的连接"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"手机连接到<xliff:g id="DEVICE_NAME">%1$s</xliff:g>时会暂时断开与 Wi-Fi 的连接。"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"平板电脑连接到“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”时会暂时断开与 WLAN 的连接"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"手机连接到<xliff:g id="DEVICE_NAME">%1$s</xliff:g>时会暂时断开与 WLAN 的连接。"</string>
<string name="select_character" msgid="3365550120617701745">"插入字符"</string>
<string name="sms_control_title" msgid="7296612781128917719">"正在发送短信"</string>
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>在发送大量短信。是否允许该应用继续发送短信?"</string>
@@ -1399,12 +1399,12 @@
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G 数据已停用"</string>
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据已停用"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据已停用"</string>
- <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi 数据网络已停用"</string>
+ <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"WLAN 数据网络已停用"</string>
<string name="data_usage_limit_body" msgid="3317964706973601386">"触摸可启用。"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"已超出 2G-3G 数据流量限制"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"已超出 4G 数据使用上限"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"已超出移动数据流量上限"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"超出了 Wi-Fi 数据流量上限"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"超出了 WLAN 数据流量上限"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"超出规定上限 <xliff:g id="SIZE">%s</xliff:g>。"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"后台数据受限制"</string>
<string name="data_usage_restricted_body" msgid="6741521330997452990">"触摸可去除限制。"</string>
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="owner_name" msgid="2716755460376028154">"机主"</string>
<string name="error_message_title" msgid="4510373083082500195">"错误"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"此应用不支持受限个人资料的帐户"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"找不到可处理此操作的应用"</string>
<string name="revoke" msgid="5404479185228271586">"撤消"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5d55678..f175fc1 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1498,7 +1498,8 @@
<string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
<string name="owner_name" msgid="2716755460376028154">"擁有者"</string>
<string name="error_message_title" msgid="4510373083082500195">"錯誤"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"這個應用程式不支援設有限制的個人資料所屬帳戶"</string>
+ <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
+ <skip />
<string name="app_not_found" msgid="3429141853498927379">"找不到支援此操作的應用程式"</string>
<string name="revoke" msgid="5404479185228271586">"撤銷"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index df86b74..eed5e04 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1498,7 +1498,7 @@
<string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="owner_name" msgid="2716755460376028154">"Umnikazi"</string>
<string name="error_message_title" msgid="4510373083082500195">"Iphutha"</string>
- <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Lolu hlelo lokusebenza alusekeli ama-akhawunti wamaphrofayela akhawulelwe"</string>
+ <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Lolu hlelo lokusebenza alusekeli ama-akhawunti wamaphrofayela akhawulelwe"</string>
<string name="app_not_found" msgid="3429141853498927379">"Alukho uhlelo lokusebenza olutholakele lokuphatha lesi senzo"</string>
<string name="revoke" msgid="5404479185228271586">"Chitha"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5d71f75..459a634 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4057,10 +4057,6 @@
<attr name="drawable" />
</declare-styleable>
- <declare-styleable name="MipmapDrawableItem">
- <attr name="drawable" />
- </declare-styleable>
-
<!-- Drawable used to rotate another drawable. -->
<declare-styleable name="RotateDrawable">
<attr name="visible" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f282188..d40eb64 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4123,7 +4123,7 @@
<!-- Error message title [CHAR LIMIT=35] -->
<string name="error_message_title">Error</string>
<!-- Message informing user that app is not permitted to access accounts. [CHAR LIMIT=none] -->
- <string name="app_no_restricted_accounts">This application does not support accounts for restricted profiles</string>
+ <string name="app_no_restricted_accounts">This app doesn\'t support accounts for restricted profiles</string>
<!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] -->
<string name="app_not_found">No application found to handle this action</string>
<string name="revoke">Revoke</string>
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index a63a453..54881d5 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -32,11 +32,7 @@
</intent-filter>
</activity>
</application>
- <!-- default test runner -->
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.connectivitymanagertest"
- android:label="default instrumentation test runner"
- />
+
<!--
This declares that this app uses the instrumentation test runner targeting
the package of connectivitymanagertest. To run the tests use the command:
@@ -68,6 +64,16 @@
android:label="Test runner for Connectivity Manager Stress Tests"
/>
+ <!-- run associate test:
+ "adb shell am instrument -e ssid <ssid> -e password <password>
+ -e ecurity-type [OPEN|WEP64|WEP128|WPA_TKIP|WPA2_AES] -e frequency-band [2.4|5.0|auto]
+ -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
+ -->
+ <instrumentation android:name=".WifiAssociationTestRunner"
+ android:targetPackage="com.android.connectivitymanagertest"
+ android:label="Test runner for Wifi association test"
+ />
+
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
new file mode 100644
index 0000000..722df2e
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2013, 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.connectivitymanagertest;
+
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+
+import com.android.connectivitymanagertest.functional.WifiAssociationTest;
+
+import junit.framework.TestSuite;
+import junit.framework.Assert;
+
+/**
+ * Instrumentation Test Runner for wifi association test.
+ * The instrument will set frequency band if it is necessary
+ *
+ * To run the association tests:
+ *
+ * adb shell am instrument -e ssid <ssid> -e password <password> \
+ * -e security-type [OPEN|WEP64|WEP128|WPA_TKIP|WPA2_AES] -e frequency-band [2.4|5.0|auto]
+ * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
+ */
+public class WifiAssociationTestRunner extends InstrumentationTestRunner {
+ private static final String TAG = "WifiAssociationTestRunner";
+ public int mBand;
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(WifiAssociationTest.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return WifiAssociationTestRunner.class.getClassLoader();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ Bundle arguments = icicle;
+ String mFrequencyBand = arguments.getString("frequency-band");
+ if (mFrequencyBand != null) {
+ setFrequencyBand(mFrequencyBand);
+ }
+ }
+
+ private void setFrequencyBand(String band) {
+ WifiManager mWifiManager = (WifiManager)getContext().getSystemService(Context.WIFI_SERVICE);
+ if (band.equals("2.4")) {
+ Log.v(TAG, "set frequency band to 2.4");
+ mBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ;
+ } else if (band.equals("5.0")) {
+ Log.v(TAG, "set frequency band to 5.0");
+ mBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
+ } else if (band.equals("auto")) {
+ Log.v(TAG, "set frequency band to auto");
+ mBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
+ } else {
+ Assert.fail("invalid frequency band");
+ }
+ int currentFreq = mWifiManager.getFrequencyBand();
+ if (mBand == currentFreq) {
+ Log.v(TAG, "frequency band has been set");
+ return;
+ }
+ mWifiManager.setFrequencyBand(mBand, true);
+ }
+}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index 87a98bf..f12e62e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -17,6 +17,7 @@
package com.android.connectivitymanagertest.functional;
import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.WifiAssociationTestRunner;
import android.content.Context;
import android.os.Bundle;
@@ -27,22 +28,19 @@
import android.net.wifi.WifiConfiguration.GroupCipher;
import android.net.wifi.WifiConfiguration.PairwiseCipher;
import android.net.wifi.WifiConfiguration.Protocol;
-import android.net.wifi.WifiConfiguration.Status;
import android.net.wifi.WifiManager;
import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.ActivityInstrumentationTestCase2;
-import android.test.InstrumentationTestRunner;
import android.util.Log;
/**
* Test Wi-Fi connection with different configuration
* To run this tests:
- * adb shell am instrument -e ssid <ssid> -e password <password>
- * -e security-type <security-type>
- * -w com.android.connectivitymanagertest/android.test.InstrumentationTestRunner
+ * * adb shell am instrument -e ssid <ssid> -e password <password> \
+ * -e security-type [OPEN|WEP64|WEP128|WPA_TKIP|WPA2_AES] -e frequency-band [2.4|5.0|auto]
+ * -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
*/
public class WifiAssociationTest
extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
@@ -51,6 +49,8 @@
private String mSsid = null;
private String mPassword = null;
private String mSecurityType = null;
+ private String mFrequencyBand = null;
+ private int mBand;
private WifiManager mWifiManager = null;
enum SECURITY_TYPE {
@@ -64,15 +64,18 @@
@Override
public void setUp() throws Exception {
super.setUp();
- InstrumentationTestRunner mRunner = (InstrumentationTestRunner)getInstrumentation();
+ WifiAssociationTestRunner mRunner = (WifiAssociationTestRunner)getInstrumentation();
mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE);
mAct = getActivity();
Bundle arguments = mRunner.getArguments();
mSecurityType = arguments.getString("security-type");
mSsid = arguments.getString("ssid");
mPassword = arguments.getString("password");
+ mFrequencyBand = arguments.getString("frequency-band");
+ mBand = mRunner.mBand;
assertNotNull("Security type is empty", mSecurityType);
assertNotNull("Ssid is empty", mSsid);
+ validateFrequencyBand();
// enable Wifi and verify wpa_supplicant is started
assertTrue("enable Wifi failed", mAct.enableWifi());
sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
@@ -88,6 +91,14 @@
super.tearDown();
}
+ private void validateFrequencyBand() {
+ if (mFrequencyBand != null) {
+ int currentFreq = mWifiManager.getFrequencyBand();
+ Log.v(TAG, "read frequency band: " + currentFreq);
+ assertTrue("device frequency band is not set successfully", (mBand == currentFreq));
+ }
+ }
+
/**
* Connect to the provided Wi-Fi network
* @param config is the network configuration
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index a147350..27cedcb 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -219,6 +219,21 @@
- from: /guide/tutorials/...
to: /resources/tutorials/...
+# move ui docs to design
+
+- from: /guide/practices/ui_guidelines/index.html
+ to: /design/index.html
+
+- from: /guide/practices/ui_guidelines/icon_design.*
+ to: /design/style/iconography.html
+
+- from: /guide/practices/ui_guidelines/activity_task_design.html
+ to: /design/patterns/app-structure.html
+
+- from: /guide/practices/ui_guidelines/menu_design.html
+ to: /design/patterns/actionbar.html
+
+
# ------------------- RESOURCES -------------------
- from: /resources/dashboard/...
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 6956634..43eead9 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -57,7 +57,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 14-day period ending on May 1, 2013.
+<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013.
<br/>Any versions with less than 0.1% distribution are not shown.</em>
</p>
@@ -83,7 +83,7 @@
</div>
-<p style="clear:both"><em>Data collected during a 14-day period ending on May 1, 2013
+<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013
<br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
@@ -130,7 +130,7 @@
-<p style="clear:both"><em>Data collected during a 14-day period ending on May 1, 2013</em></p>
+<p style="clear:both"><em>Data collected during a 14-day period ending on June 3, 2013</em></p>
@@ -148,7 +148,7 @@
var VERSION_DATA =
[
{
- "chart": "//chart.googleapis.com/chart?chs=500x250&cht=p&chf=bg%2Cs%2C00000000&chd=t%3A1.8%2C3.7%2C38.5%2C0.1%2C27.5%2C28.4&chco=c4df9b%2C6fad0c&chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean",
+ "chart": "//chart.googleapis.com/chart?chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean&chd=t%3A1.6%2C3.2%2C36.5%2C0.1%2C25.6%2C33.0&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=500x250",
"data": [
{
"api": 4,
@@ -158,12 +158,12 @@
{
"api": 7,
"name": "Eclair",
- "perc": "1.7"
+ "perc": "1.5"
},
{
"api": 8,
"name": "Froyo",
- "perc": "3.7"
+ "perc": "3.2"
},
{
"api": 9,
@@ -173,7 +173,7 @@
{
"api": 10,
"name": "Gingerbread",
- "perc": "38.4"
+ "perc": "36.4"
},
{
"api": 13,
@@ -183,17 +183,17 @@
{
"api": 15,
"name": "Ice Cream Sandwich",
- "perc": "27.5"
+ "perc": "25.6"
},
{
"api": 16,
"name": "Jelly Bean",
- "perc": "26.1"
+ "perc": "29.0"
},
{
"api": 17,
"name": "Jelly Bean",
- "perc": "2.3"
+ "perc": "4.0"
}
]
}
@@ -205,35 +205,34 @@
var SCREEN_DATA =
[
-
{
"data": {
"Large": {
"hdpi": "0.4",
"ldpi": "0.6",
- "mdpi": "2.9",
+ "mdpi": "3.0",
"tvdpi": "1.0",
- "xhdpi": "0.7"
+ "xhdpi": "0.6"
},
"Normal": {
- "hdpi": "37.3",
+ "hdpi": "36.0",
"ldpi": "0.1",
- "mdpi": "16.1",
- "xhdpi": "24.9",
- "xxhdpi": "1.3"
+ "mdpi": "16.0",
+ "xhdpi": "24.5",
+ "xxhdpi": "3.3"
},
"Small": {
- "ldpi": "9.8"
+ "hdpi": "0.1",
+ "ldpi": "9.9"
},
"Xlarge": {
- "hdpi": "0.1",
- "ldpi": "0.2",
- "mdpi": "4.5",
+ "hdpi": "0.2",
+ "mdpi": "4.2",
"xhdpi": "0.1"
}
},
- "densitychart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chf=bg%2Cs%2C00000000&chd=t%3A10.7%2C23.5%2C1.0%2C37.8%2C25.7%2C1.3&chco=c4df9b%2C6fad0c&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
- "layoutchart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chf=bg%2Cs%2C00000000&chd=t%3A4.9%2C5.6%2C79.7%2C9.8&chco=c4df9b%2C6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall"
+ "densitychart": "//chart.googleapis.com/chart?chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A10.6%2C23.2%2C1.0%2C36.7%2C25.2%2C3.3&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250",
+ "layoutchart": "//chart.googleapis.com/chart?chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.5%2C5.6%2C79.9%2C10.0&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c&cht=p&chs=400x250"
}
];
diff --git a/docs/html/about/index.jd b/docs/html/about/index.jd
index 0b72701..1573cc3 100644
--- a/docs/html/about/index.jd
+++ b/docs/html/about/index.jd
@@ -1,4 +1,5 @@
page.title=Android, the world's most popular mobile platform
+excludeFromSuggestions=true
walkthru=0
header.hide=0
diff --git a/docs/html/about/start.jd b/docs/html/about/start.jd
index fbe70e3..727c975 100644
--- a/docs/html/about/start.jd
+++ b/docs/html/about/start.jd
@@ -1,4 +1,5 @@
page.title=Get Started
+excludeFromSuggestions=true
walkthru=0
@jd:body
diff --git a/docs/html/channels/io2013.jd b/docs/html/channels/io2013.jd
new file mode 100644
index 0000000..977eb2f
--- /dev/null
+++ b/docs/html/channels/io2013.jd
@@ -0,0 +1,346 @@
+fullpage=true
+page.title=Google I/O 13
+@jd:body
+
+<style>
+#ioplayer-frame {
+ z-index:10;
+ width:703px;
+ height:396px;
+ margin:0;
+ position:relative;
+}
+
+#noplayer-message {
+ position:absolute;
+ top:50%;left:0;
+ width:100%;
+ z-index:-1;
+ text-align:center;
+ display:none;
+}
+
+h1 {
+ font-weight:100;
+ font-size:40px;
+ line-height:30px;
+ margin:30px 0 10px 0px;
+ color:#000;
+}
+
+h2 {
+ font-weight:100;
+ font-size:30px;
+ line-height:30px;
+ margin:12px 0 10px 0px;
+ color:#000;
+ float:left;
+ display:block;
+}
+
+.col-4 h2 {
+ margin-top:40px;
+}
+
+ul.videos {
+ list-style:none;
+ margin:0;
+ width:auto;
+}
+ul.videos li {
+ display:block;
+ float:left;
+ position:relative;
+ margin:0 2px 2px 0;
+ background-repeat:no-repeat !important;
+ background-size:320px auto;
+ background-position:10% 50%;
+ z-index:1; /* IE: the description is 2 */
+}
+ul.videos li a {
+ color:#fff !important;
+ display:block;
+ margin:0;
+ padding:8px 12px;
+ width:209px;
+ height:134px;
+ box-shadow:inset 500px 500px 999px rgba(000, 000, 000, 0.2);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(0,0,0,0.8)), color-stop(1, transparent));
+ background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.8), transparent);
+ background-image: -moz-linear-gradient(top, rgba(0,0,0,0.8), transparent);
+ background-image: -o-linear-gradient(top, rgba(0,0,0,0.8), transparent);
+ background-image: linear-gradient(to bottom, rgba(0,0,0,0.8), transparent);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc000000', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
+}
+ul.videos.featured li {
+ margin:0 0 2px;
+}
+ul.videos.featured li a {
+ margin:0;
+ height:115px;
+}
+ul.videos li a:hover {
+ box-shadow:inset 500px 500px 999px rgba(255,255,255, 0.6);
+}
+ul.videos li h4 {
+ text-shadow:1px 1px 0 rgba(0,0,0,0.8);
+ font-size:18px;
+ line-height:22px;
+ color:#fff;
+ margin:0;
+ height:100%; /* IE: to fill clickable area */
+}
+
+ul.videos li .description-frame {
+ display:none;
+ z-index:2; /* IE: the li is 1 */
+}
+ul.videos li a:hover .description-frame {
+ display:block;
+ position:absolute;
+ top:80px;
+ left:8px;
+ z-index:99;
+}
+ul.videos .description {
+ background:#fff;
+ width:200px;
+ padding:8px;
+ -webkit-border-radius:1px;
+ -moz-border-radius:1px;
+ border-radius:1px;
+ -moz-box-shadow: 0 2px 3px 2px rgba(000,000,000, 0.4);
+ -webkit-box-shadow: 0 2px 3px 2px rgba(000,000,000, 0.4);
+ box-shadow: 0 2px 3px 2px rgba(000,000,000, 0.4);
+ font-size:11px;
+ line-height:12px;
+ color:#000;
+ overflow:hidden;
+}
+ul.videos .arrow-up {
+ position:absolute;
+ left:15px;
+ top:-11px;
+ width:0;
+ height:0;
+ border-bottom:12px solid #fff;
+ border-left:12px solid transparent;
+ border-right:12px solid transparent;
+}
+ul.videos .arrow-down {
+ position:absolute;
+ left:15px;
+ bottom:-11px;
+ width:0;
+ height:0;
+ border-top:12px solid #fff;
+ border-left:12px solid transparent;
+ border-right:12px solid transparent;
+}
+
+ul.videos span.tag {
+ font-size:.9em;
+ font-weight:normal;
+ display: block;
+ position: absolute;
+ bottom: 0;
+ color: #fff;
+ left: 0;
+ padding: 4px;
+ border-top-right-radius:4px;
+ text-transform:uppercase;
+ text-shadow: none;
+}
+ul.videos span.tag.design {
+ background-color:rgba(51, 181, 229, .7);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc33b5e5', endColorstr='#cc33b5e5',GradientType=0 ); /* IE6-9 */
+}
+ul.videos span.tag.develop {
+ background-color:rgba(255, 136, 0, .7);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ccff8800', endColorstr='#ccff8800',GradientType=0 ); /* IE6-9 */
+}
+ul.videos span.tag.distribute {
+ background-color:rgba(153, 204, 0, .7);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc99cc00', endColorstr='#cc99cc00',GradientType=0 ); /* IE6-9 */
+}
+
+</style>
+
+
+
+
+
+
+
+<div class="wrap">
+
+ <div class="col-12" style="width:704px;margin:0">
+ <h1>Android @ Google I/O 13</h1>
+ <div id="ioplayer-frame">
+ <div id="noplayer-message">
+ <!-- busted flash player message -->
+ Your video is supposed to appear here.<br/>
+ Make sure you have the <a href="//get.adobe.com/flashplayer/" target="_blank">Flash® Player</a>.
+ </div>
+ <div id="player"><!-- Youtube embeds here... actually replaces this div --></div>
+ </div>
+ </div>
+
+ <div class="col-4" style="margin:0;width:234px;padding:0 0 0 2px">
+ <h2 class="norule">Most Popular</h2>
+ <ul class="videos featured" id="playlist2">
+ </ul>
+ </div>
+</div>
+
+<div class="wrap">
+
+ <div style="position:absolute;width:940px;text-align:right">
+ <a href="//www.youtube.com/AndroidDevelopers" target="_blank">
+ More on YouTube
+ <img src="//www.youtube.com/favicon.ico" style="border:0;width:16px;height:16px;vertical-align:middle;margin:0 2px 3px 2px">
+ </a>
+ </div>
+ <div style="width:944px;overflow:hidden;padding:0 0 20px">
+ <h2 class="norule">All Videos</h2>
+ <ul class="videos" id="playlist1" style="clear:left">
+ <span id="videos-design"></span>
+ <span id="videos-develop"></span>
+ <span id="videos-distribute"></span>
+ </ul>
+ </div>
+
+</div>
+
+<br class="clearfix"/>
+
+
+
+
+
+
+
+
+
+
+
+<script src="//swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
+<script type="text/javascript">
+
+/* Load a video into the player box.
+ * @param id The YouTube video ID
+ * @param title The video title to display in the player box (character escaped)
+ * @param autoplay Whether to automatically play the video
+ */
+function loadVideo(id, title, autoplay) {
+ var url = '//www.youtube.com/v/' + id + '&rel=1&border=0&fs=1' + (autoplay?'&autoplay=1':'');
+ swfobject.embedSWF(url, 'player', '704', '397', '9.0.0', false, false, {allowfullscreen: 'true'});
+ $('body,html').animate({ scrollTop: 0 }, "slow");
+ setTimeout(function(){$('#noplayer-message').show()}, 2000);
+}
+
+
+function buildPlaylistDesign(data) {
+ buildPlaylist(data, $('ul#playlist1 #videos-design'), "design");
+}
+
+function buildPlaylistDevelop(data) {
+ buildPlaylist(data, $('ul#playlist1 #videos-develop'), "develop");
+}
+
+function buildPlaylistDistribute(data) {
+ buildPlaylist(data, $('ul#playlist1 #videos-distribute'), "distribute");
+}
+
+function buildPlaylist2(data) {
+ buildPlaylist(data, $('ul#playlist2'));
+}
+
+function buildPlaylist(data, ul, tag) {
+
+ var MAX_DESC_LENGTH = 200; // the length at which we will trim the description
+ var feed = data.feed;
+ var entries = feed.entry || [];
+ var playlistId = feed.yt$playlistId.$t;
+
+ // Loop through each entry (each video) and add it to the '#DevelopersLive' list
+ for (var i = 0; i < entries.length; i++) {
+ var entry = entries[i];
+ var title = entry.title.$t;
+ var id = entry.media$group.yt$videoid.$t;
+ // get 180x320 thumbnail
+ var thumbs = entry.media$group.media$thumbnail;
+ var thumbUrl;
+ for (var j = 0; j < thumbs.length; j++) {
+ if (thumbs[j].yt$name == "hqdefault") {
+ thumbUrl = thumbs[j].url;
+ }
+ }
+
+ // chop out the google io title
+ title = title.substr(title.indexOf("-") + 1, title.length);
+
+ var fullDescription = entry.media$group.media$description.$t;
+ var playerUrl = entry.media$group.media$content[0].url;
+ var shortDescription = fullDescription.substr(0, MAX_DESC_LENGTH);
+ // further shorten description if there's a url (remove it)
+ var httpindex = shortDescription.indexOf("http://");
+ if (httpindex != -1) {
+ shortDescription = shortDescription.substring(0,httpindex);
+ }
+ shortDescription += shortDescription.length == MAX_DESC_LENGTH ? "..." : ""; // add ellipsis if we've chopped the description
+
+ var a = $('<a href="#" id="' + id + '" '
+ + 'onclick="loadVideo(\'' + id + '\',\'' + escape(title) + '\',true); return false;" />');
+ var pShortDescription = $('<div class="description-frame"><div class="arrow-up"></div>'
+ + '<div class="description">' + shortDescription + '</div></div>');
+ var h4Title = "<h4>" + title + "</h4>";
+ var li = $('<li style="background-image:url(\'' + thumbUrl +'\')" />');
+
+ li.append(a);
+ a.append(h4Title).append(pShortDescription);
+
+ if (tag !== undefined) {
+ var $tag = $('<span class="tag ' + tag + '">' + tag + '</span>');
+ a.append($tag);
+ }
+
+ ul.append(li);
+
+
+ // put the first video in the player
+ if ((tag == "design") && (i == 0)) {
+ loadVideo(id, escape(title), false);
+ }
+ }
+}
+
+
+/* Request the playlist feeds from YouTube */
+function showDevelopersLivePlaylist() {
+ var playlistId = "PLWz5rJ2EKKc-qVhMuAprIFYFbCotdgJKq"; /* IO 13 - Design */
+ $.getScript("//gdata.youtube.com/feeds/api/playlists/"
+ + playlistId +
+ "?v=2&alt=json-in-script&max-results=50&callback=buildPlaylistDesign&orderby=position");
+
+ playlistId = "PLWz5rJ2EKKc9rkwO9yBosRvkQBJd5utmR"; /* IO 13 - Develop */
+ $.getScript("//gdata.youtube.com/feeds/api/playlists/"
+ + playlistId +
+ "?v=2&alt=json-in-script&max-results=50&callback=buildPlaylistDevelop&orderby=position");
+
+ playlistId = "PLWz5rJ2EKKc-1WjgQqL0B4OQtbLfhMlB2"; /* IO 13 - Distribute */
+ $.getScript("//gdata.youtube.com/feeds/api/playlists/"
+ + playlistId +
+ "?v=2&alt=json-in-script&max-results=50&callback=buildPlaylistDistribute&orderby=position");
+
+
+ playlistId = "PLWz5rJ2EKKc9WGUwq2gQ-coU3fSyexgOx"; /* IO 13 - The Android Sessions */
+ $.getScript("//gdata.youtube.com/feeds/api/playlists/"
+ + playlistId +
+ "?v=2&alt=json-in-script&max-results=3&callback=buildPlaylist2&orderby=viewCount");
+}
+
+showDevelopersLivePlaylist();
+
+
+</script>
\ No newline at end of file
diff --git a/docs/html/design/media/devices_displays_density.png b/docs/html/design/media/devices_displays_density.png
index 7ddad31..4e3cbf6 100644
--- a/docs/html/design/media/devices_displays_density.png
+++ b/docs/html/design/media/devices_displays_density.png
Binary files differ
diff --git a/docs/html/design/media/devices_displays_density@2x.png b/docs/html/design/media/devices_displays_density@2x.png
new file mode 100644
index 0000000..79a46b0
--- /dev/null
+++ b/docs/html/design/media/devices_displays_density@2x.png
Binary files differ
diff --git a/docs/html/design/style/devices-displays.jd b/docs/html/design/style/devices-displays.jd
index 18550d9..a8f9d6f 100644
--- a/docs/html/design/style/devices-displays.jd
+++ b/docs/html/design/style/devices-displays.jd
@@ -32,7 +32,7 @@
</div>
</div>
- <img src="{@docRoot}design/media/devices_displays_density.png">
+ <img src="{@docRoot}design/media/devices_displays_density@2x.png" alt="" height="160" />
<h4>Strategies</h4>
<p>So where do you begin when designing for multiple screens? One approach is to work in the base
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 1475e5c..0d2cdbb 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -4,9 +4,37 @@
<img src="{@docRoot}design/media/iconography_overview.png">
+
<p>An icon is a graphic that takes up a small portion of screen real estate and provides a quick,
intuitive representation of an action, a status, or an app.</p>
+<p>When you design icons for your app, it's important to keep in mind that your
+app may be installed on a variety of devices that offer a range of
+pixel densities, as mentioned in
+<a href="{@docRoot}design/style/devices-displays.html">Devices
+and Displays</a>. But you can make your icons look great on all devices
+by providing each icon in multiple sizes. When your app runs, Android checks the characteristics of
+the device screen and loads the appropriate density-specific assets for your app. </p>
+
+<p>Because you will deliver each icon in multiple sizes to support different densities,
+the design guidelines below
+refer to the icon dimensions in <acronym title="density-independent pixels">dp</acronym>
+units, which are based on the pixel dimensions of a medium-density (MDPI) screen.</p>
+
+<img src="{@docRoot}design/media/devices_displays_density@2x.png" alt="" height="160" />
+
+<p>So, to create an icon for different densities, you should follow the <strong>2:3:4:6 scaling
+ratio</strong> between the four primary densities (medium, high, x-high, and xx-high,
+respectively). For example, consider that the size for a launcher icon is specified to be
+48x48 dp. This means the baseline (MDPI) asset is 48x48 px, and the
+high density (HDPI) asset should be 1.5x the baseline at 72x72 px, and the x-high
+density (XHDPI) asset should be 2x the baseline at 96x96 px, and so on.</p>
+
+<p class="note"><strong>Note:</strong> Android also supports low-density (LDPI) screens,
+but you normally don't need to create custom assets at this size because Android
+effectively down-scales your HDPI assets by 1/2 to match the expected size.</p>
+
+
<h2 id="launcher">Launcher</h2>
@@ -338,3 +366,165 @@
</div>
<!-- 2 free columns -->
</div>
+
+
+
+
+
+
+
+
+
+
+<h2 id="DesignTips">Design Tips</h2>
+
+<p>Here are some tips you might find useful as you create icons or other
+drawable assets for your application. These tips assume you are using
+Adobe® Photoshop® or a similar raster and vector image-editing program.</p>
+
+
+
+
+<h3>Use vector shapes where possible</h3>
+
+<p>Many image-editing programs such as Adobe® Photoshop® allow you to use a
+combination of vector shapes and raster layers and effects. When possible,
+use vector shapes so that if the need arises, assets can be scaled up without
+loss of detail and edge crispness.</p>
+
+<p>Using vectors also makes it easy to align edges and corners to pixel
+boundaries at smaller resolutions.</li>
+
+
+
+<h3>Start with large artboards</h3>
+
+<p>Because you will need to create assets for different screen densities,
+it is best to start your icon
+designs on large artboards with dimensions that are multiples of the target icon
+sizes. For example, launcher icons are 48, 72, 96, or 144 pixels wide,
+depending on screen density (mdpi, hdpi, xhdpi, and xxhdpi, respectively). If you
+initially draw launcher icons on an 864x864 artboard, it will be easier and
+cleaner to adjust the icons when you scale the artboard down to the target
+sizes for final asset creation.</p>
+
+
+
+<h3>When scaling, redraw bitmap layers as needed</h3>
+
+<p>If you scaled an image up from a bitmap layer, rather than from a vector
+layer, those layers will need to be redrawn manually to appear crisp at higher
+densities. For example if a 60x60 circle was painted as a bitmap for
+mdpi it will need to be repainted as a 90x90 circle for hdpi.</p>
+
+
+
+<h3>Use common naming conventions for icon assets</h3>
+
+<p>Try to name files so that related assets will group together inside a
+directory when they are sorted alphabetically. In particular, it helps to use a
+common prefix for each icon type. For example:</p>
+
+<table>
+<tr>
+<th>Asset Type</th>
+<th>Prefix</th>
+<th>Example</th>
+</tr>
+<tr>
+<td>Icons</td>
+<td><code>ic_</code></td>
+<td><code>ic_star.png</code></td>
+</tr>
+<tr>
+<td>Launcher icons</td>
+<td><code>ic_launcher</code></td>
+<td><code>ic_launcher_calendar.png</code></td>
+</tr>
+<tr>
+<td>Menu icons and Action Bar icons</td>
+<td><code>ic_menu</code></td>
+<td><code>ic_menu_archive.png</code></td>
+</tr>
+<tr>
+<td>Status bar icons</td>
+<td><code>ic_stat_notify</code></td>
+<td><code>ic_stat_notify_msg.png</code></td>
+</tr>
+<tr>
+<td>Tab icons</td>
+<td><code>ic_tab</code></td>
+<td><code>ic_tab_recent.png</code></td>
+</tr>
+<tr>
+<td>Dialog icons</td>
+<td><code>ic_dialog</code></td>
+<td><code>ic_dialog_info.png</code></td>
+</tr>
+</table>
+
+<p>Note that you are not required to use a shared prefix of any
+type—doing so is for your convenience only.</p>
+
+
+<h3>Set up a working space that organizes files by density</h3>
+
+<p>Supporting multiple screen densities means you must create multiple versions
+of the same icon. To help keep the multiple copies of files safe and easier to
+find, we recommend creating a directory structure in your working space that
+organizes asset files based on the target density. For example:</p>
+
+<pre>
+art/...
+ mdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png
+ hdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png
+ xhdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png</pre>
+ xxhdpi/...
+ _pre_production/...
+ <em>working_file</em>.psd
+ <em>finished_asset</em>.png</pre>
+
+<p>Because the structure in your working space is similar to that of the application, you
+can quickly determine which assets should be copied to each
+resources directory. Separating assets by density also helps you detect any
+variances in filenames across densities, which is important because
+corresponding assets for different densities must share the same filename.</p>
+
+<p>For comparison, here's the resources directory structure of a typical
+application: </p>
+
+<pre>res/...
+ drawable-ldpi/...
+ <em>finished_asset</em>.png
+ drawable-mdpi/...
+ <em>finished_asset</em>.png
+ drawable-hdpi/...
+ <em>finished_asset</em>.png
+ drawable-xhdpi/...
+ <em>finished_asset</em>.png
+</pre>
+
+<p>For more information about how to save resources in the application project,
+see <a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.
+</p>
+
+
+<h3>Remove unnecessary metadata from final assets</h3>
+
+<p>Although the Android SDK tools will automatically compress PNGs when packaging
+application resources into the application binary, a good practice is to remove
+unnecessary headers and metadata from your PNG assets. Tools such as <a
+href="http://optipng.sourceforge.net/">OptiPNG</a> or <a
+href="http://pmt.sourceforge.net/pngcrush/">Pngcrush</a> can ensure that this
+metadata is removed and that your image asset file sizes are optimized.</p>
+
+
diff --git a/docs/html/design/style/metrics-grids.jd b/docs/html/design/style/metrics-grids.jd
index 3116ff6d..0a99a2f 100644
--- a/docs/html/design/style/metrics-grids.jd
+++ b/docs/html/design/style/metrics-grids.jd
@@ -4,15 +4,28 @@
<p>Devices vary not only in physical size, but also in screen density (<acronym title="Dots per
inch">DPI</acronym>). To simplify the way you design for multiple screens, think of each device as
-falling into a particular size bucket and density bucket. The size buckets are <em>handset</em> (smaller than
-600<acronym title="Density-independent pixels. One dp is one pixel on a 160 dpi
-screen.">dp</acronym>) and <em>tablet</em> (larger than or equal 600dp). The density buckets are <acronym
+falling into a particular size bucket and density bucket:</p>
+<ul>
+ <li>The size buckets are <em>handset</em> (smaller than
+600<acronym title="Density-independent pixels: One dp is one pixel on a 160 dpi (mdpi)
+screen.">dp</acronym>) and <em>tablet</em> (larger than or equal 600dp).</li>
+ <li>The density buckets are <acronym
title="Low density (120 dpi)">LDPI</acronym>, <acronym title="Medium density (160
-dpi)">MDPI</acronym>, <acronym title="High density (240 dpi)">HDPI</acronym>, and <acronym title
-="Extra-high density (320 dpi)">XHDPI</acronym>. Optimize your application's UI by designing
+dpi)">MDPI</acronym>, <acronym title="High density (240 dpi)">HDPI</acronym>, <acronym title
+="Extra-high density (320 dpi)">XHDPI</acronym>, and <acronym title
+="Extra-extra!-high density (480 dpi)">XXHDPI</acronym>.</li>
+</ul>
+
+<p>Optimize your application's UI by designing
alternative layouts for some of the different size buckets, and provide alternative bitmap images
for different density buckets.</p>
+<p>Because it's important that you design and implement your layouts for multiple densities,
+the guidelines below and throught the documentation
+refer to layout dimensions with <acronym title="Density-independent pixels: One dp is one pixel
+on a 160 dpi (mdpi) screen.">dp</acronym> measurements instead of pixels.</p>
+
+
<div class="layout-content-row">
<div class="layout-content-col span-8">
@@ -30,6 +43,7 @@
</div>
</div>
+
<h2 id="48dp-rhythm">48dp Rhythm</h2>
<p>Touchable UI components are generally laid out along 48dp units.</p>
diff --git a/docs/html/distribute/googleplay/spotlight/index.jd b/docs/html/distribute/googleplay/spotlight/index.jd
index a248dea..b83080e 100644
--- a/docs/html/distribute/googleplay/spotlight/index.jd
+++ b/docs/html/distribute/googleplay/spotlight/index.jd
@@ -13,7 +13,36 @@
overflow: auto;
clear:both;
margin-bottom:40px;
- margin-top:30px;"">
+ margin-top:30px;">
+ <div style="padding:0 0 0 29px;">
+ <h4>Developer Story: redBus.in</h4>
+ <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px height:78px;
+ width: 78px;
+ float: left;
+ margin: 17px 20px 9px 0;" src=
+ "//lh4.ggpht.com/kvI2XfzBPGBDASvxvP18MCCj7YPEmLcG4nh1BlYW4XzaW12gg3iXtcM2ZqDnAfLLB9ed=w124">
+ <div style="width:700px;">
+ <p style="margin-top:26px;
+ margin-bottom:12px;">
+ Bangalore-based developers <a href="//play-next-dogfood.corp.google.com/store/apps/details?id=in.redbus.android">redBus.in</a> are bringing the sophistication and convenience of air-travel booking to bus transit. Hear how Android is helping them deliver a superior travel experience to millions of daily bus riders in India.</p>
+ </div>
+ <iframe style="float:left;
+ margin-right:24px;
+ margin-top:14px;" width="700" height="394" src=
+ "http://www.youtube.com/embed/O8i4HUw7JYA?HD=1;rel=0;origin=developer.android.com;" frameborder="0" allowfullscreen>
+ </iframe>
+ </div>
+</div>
+
+<div style="background: #F0F0F0;
+ border-top: 1px solid #DDD;
+ padding: 0px 0 24px 0;
+ overflow: auto;
+ clear:both;
+ margin-bottom:40px;
+ margin-top:30px;">
<div style="padding:0 0 0 29px;">
<h4>Developer Story: Smule</h4>
<img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
@@ -42,7 +71,7 @@
overflow: auto;
clear:both;
margin-bottom:-10px;
- margin-top:30px;"">
+ margin-top:30px;">
<div style="padding:0 0 0 29px;">
<h4>Developer Story: Robot Invader</h4>
<img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index ffe15c5..0cadbd2 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -23,7 +23,7 @@
<li><a href="#msg_examples">Message Examples</a></li>
</ol>
</li>
- <li><a href="#flow">Control Flow</a> </li>
+ <li><a href="#flow">Flow Control</a> </li>
</ol>
<h2>See Also</h2>
@@ -48,6 +48,8 @@
<p>The upstream messaging (device-to-cloud) feature of CCS is part of the Google Play services platform. Upstream messaging is available through the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. To use upstream messaging and the new streamlined registration process, you must <a href="{@docRoot}google/play-services/setup.html">set up</a> the Google Play services SDK.</p>
+<p class="note"><strong>Note:</strong> For an example of an XMPP server, see <a href="server.html#xmpp">GCM Server</a>.
+
<h2 id="gcm">CCS vs. GCM HTTP</h2>
<p>CCS messaging differs from GCM HTTP messaging in the following ways:</p>
@@ -229,69 +231,13 @@
</gcm>
</message></pre>
-<h4 id="python">Python Example</h4>
-<p>This example illustrates how to connect,
-send, and receive GCM messages using XMPP. It shouldn't be used as-is
-on a production deployment.</p>
-<pre>
-import sys, json, xmpp
-SERVER = ('gcm.googleapis.com', 5235)
-#USERNAME = '<your_numeric_project_id>'
-#PASSWORD = '<your_gcm_api_key>'
+<h2 id="flow">Flow Control</h2>
-# Unique message id for downstream messages
-sent_message_id = 0
+<p>Every message sent to CCS receives either an ACK or a NACK response. Messages that haven't received one of these responses are considered pending. If the pending message count reaches 1000, the 3rd-party server should stop sending new messages and wait for CCS to acknowledge some of the existing pending messages.</p>
-def message_callback(session, message):
- global sent_message_id
- gcm = message.getTags('gcm')
+<p>Conversely, to avoid overloading the 3rd-party server, CCS will stop sending if there are too many unacknowledged messages. Therefore, the 3rd-party server should "ACK" received messages as soon as possible to maintain a constant flow of incoming messages. The aforementioned pending message limit doesn't apply to these ACKs. Even if the pending message count reaches 1000, the 3rd-party server should continue sending ACKs to avoid blocking delivery of new messages.</p>
- if gcm:
- gcm_json = gcm[0].getData()
- msg = json.loads(gcm_json)
- msg_id = msg['message_id']
- device_reg_id = msg['from']
-
- # Ignore non-standard messages (e.g. acks/nacks).
- if not msg.has_key('message_type'):
- # Acknowledge the incoming message.
- send({'to': device_reg_id,
- 'message_type': 'ack',
- 'message_id': msg_id})
-
- # Send a response back to the server.
- send({'to': device_reg_id,
- 'message_id' : str(sent_message_id),
- 'data': {'pong': 1}})
- sent_message_id = sent_message_id + 1
-
-def send(json_dict):
- template = ("<message from='{0}' to='gcm@google.com'>"
- "<gcm xmlns='google:mobile:data'>{1}</gcm></message>")
- client.send(xmpp.protocol.Message(
- node=template.format(client.Bind.bound[0],
- json.dumps(json_dict))))
-
-client = xmpp.Client(SERVER[0], debug=['socket'])
-client.connect(server=SERVER, secure=1, use_srv=False)
-auth = client.auth(USERNAME, PASSWORD, 'test')
-if not auth:
- print 'Authentication failed!'
- sys.exit(1)
-
-client.RegisterHandler('message', message_callback)
-
-while True:
- client.Process(1)</pre>
-
-<h2 id="flow">Control Flow</h2>
-
-<p>Every message sent by a 3rd-party server to CCS receives either an ACK or a NACK response. A single connection can have at most 1000 messages that were sent without having yet received a response.</p>
-
-<p>To enforce this policy, the app can maintain a counter of sent messages that increments on each send and decrements on each ACK or NACK. If the counter exceeds 1000, the app should stop sending messages until an ACK or NACK is received.</p>
-
-<p>Conversely, when CCS sends messages to a 3rd-party server, it expects ACKs for each message it sends, and it will not send more than 1000 unacknowledged messages.</p>
-
-<p>The ACKs and messages must match on each connection. You can only send an ACK for a message on the connection on which it was received.</p>
+<p>ACKs are only valid within the context of one connection. If the connection is closed before a message can be ACKed, the 3rd-party server should wait for CCS to resend the message before ACKing it again.
+</p>
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
new file mode 100644
index 0000000..7604932
--- /dev/null
+++ b/docs/html/google/gcm/client.jd
@@ -0,0 +1,24 @@
+page.title=GCM Client
+page.tags="cloud","push","messaging"
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>See Also</h2>
+
+<ol class="toc">
+<li><a href="gs.html">Getting Started</a></li>
+<li><a href="server.html">GCM Server</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>A GCM client is a GCM-enabled app that runs on an Android device. To write your client code, we recommend that you use the new <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. The client helper library that was offered in previous versions of GCM still works, but it has been superseded by the more efficient <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs.</p>
+
+<p>A full GCM implementation requires both a client implementation and a server-side implementation. For a step-by-step guide to creating a complete sample implementation that includes both client and server, see <a href="gs.html">Getting Started</a>. </p>
+
+<p>
+
+
diff --git a/docs/html/google/gcm/demo.jd b/docs/html/google/gcm/demo.jd
index 6da9e98..012eb9a 100644
--- a/docs/html/google/gcm/demo.jd
+++ b/docs/html/google/gcm/demo.jd
@@ -1,6 +1,22 @@
page.title=GCM Demo Application
@jd:body
+<div id="deprecatedSticker">
+ <a href="#"
+ onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+ <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>The information in this document has been superseded by <a href="server.html">GCM Server</a> and <a href="client.html">GCM Client</a></strong>. Please use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> API instead of the GCM client helper library. The GCM server helper library is still valid.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+ value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
+
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/google/gcm/gcm.jd b/docs/html/google/gcm/gcm.jd
index 886677a..ceb82b0 100644
--- a/docs/html/google/gcm/gcm.jd
+++ b/docs/html/google/gcm/gcm.jd
@@ -1,4 +1,4 @@
-page.title=Google Cloud Messaging for Android
+page.title=GCM Architectural Overview
@jd:body
<div id="qv-wrapper">
@@ -28,20 +28,6 @@
<li><a href="#user">What Does the User See?</a></li>
</ol>
</li>
- <li><a href="#writing_apps">Writing Android Applications that use GCM</a>
- <ol>
- <li><a href="#manifest">Creating the Manifest</a></li>
- <li><a href="#registering">Registering for GCM</a></li>
-
- <li><a href="#handling_intents">Handling Intents Sent by GCM</a>
- <ol>
- <li><a href="#handling_reg">Handling Registration Results</a></li>
- <li><a href="#received_data">Handling Received Data</a></li>
- </ol>
- </li>
- <li><a href="#testing">Developing and Testing Your Android Applications</a></li>
- </ol>
- </li>
<li><a href="#server">Role of the 3rd-party Application Server</a>
<ol class="toc">
<li><a href="#send-msg">Sending Messages</a>
@@ -53,7 +39,6 @@
</ol>
<li><a href="#stats">Viewing Statistics</a>
</li>
- <li><a href="#example">Examples</a></li>
</ol>
@@ -306,336 +291,6 @@
includes GCM. They must approve the use of this feature to install the
Android application. </p>
-<h2 id="writing_apps">Writing Android Applications that Use GCM</h2>
-
-<p>To write Android applications that use GCM, you must have an application
-server that can perform the tasks described in <a href="#server">Role of the
-3rd-party Application Server</a>. This section describes the steps you take to
-create a client application that uses GCM.</p>
-
-<p>Remember that there is no user interface associated with GCM.
-However you choose to process messages in your Android application is up to you.</p>
-
-<p>There are two primary steps involved in writing a client Android application:</p>
-
-<ul>
- <li>Creating a manifest that contains the permissions the Android application needs to
-use GCM.</li>
- <li>Implementing your code. To use GCM, this implementation must
-include:
- <ul>
- <li>Code to start and stop the registration service.</li>
- <li>Receivers for the <code>com.google.android.c2dm.intent.RECEIVE</code> and <code>com.google.android.c2dm.intent.REGISTRATION</code> intents.</li>
- </ul>
- </li>
-</ul>
-
-<p class="note"><strong>Note:</strong> This section describes how to
-write an app without using the
-<a href="{@docRoot}reference/com/google/android/gcm/package-summary.html">helper libraries</a>.
-For details on writing
-an app that uses the helper libraries (which is the recommended and
-simpler approach), see <a href="gs.html">GCM: Getting Started</a>.
-
-<h3 id="manifest">Creating the Manifest</h3>
-
-<p>To use the GCM feature, the
-<code>AndroidManifest.xml</code> file must include the following:</p>
-
-<ul>
- <li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so the Android application can register and receive messages.</li>
- <li>The <code>android.permission.INTERNET</code> permission so the Android application can send the registration ID to the 3rd-party server.</li>
- <li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires a Google account (necessary only if if the device is running a version lower than Android 4.0.4)</li>
- <li>The <code>android.permission.WAKE_LOCK</code> permission so the application can keep the processor from sleeping when a message is received. Optional—use only if the app wants to keep the device from sleeping.</li>
- <li>An <code>applicationPackage + ".permission.C2D_MESSAGE</code> permission to prevent other Android applications from registering and receiving the Android application's
-messages. The permission name must exactly match this pattern—otherwise the Android application will not receive the messages.</li>
- <li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code> and <code>com.google.android.c2dm.intent.REGISTRATION</code>, with the category set
-as <code>applicationPackage</code>. The receiver should require the <code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
-Framework can send a message to it. Note that both registration and the receiving
-of messages are implemented as <a href="{@docRoot}guide/components/intents-filters.html">Intents</a>.</li>
- <li>An intent service to handle the intents received by the broadcast receiver. Optional.</li>
- <li>If the GCM feature is critical to the Android application's function, be sure to
-set <code>android:minSdkVersion="8"</code> in the manifest. This
-ensures that the Android application cannot be installed in an environment in which it
-could not run properly. </li>
-</ul>
-
-<p>Here are excerpts from a manifest that supports GCM:</p>
-
-<pre class="prettyprint pretty-xml">
-<manifest package="com.example.gcm" ...>
-
- <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16"/>
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.GET_ACCOUNTS" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
-
- <permission android:name="com.example.gcm.permission.C2D_MESSAGE"
- android:protectionLevel="signature" />
- <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
-
- <application ...>
- <receiver
- android:name=".MyBroadcastReceiver"
- android:permission="com.google.android.c2dm.permission.SEND" >
- <intent-filter>
- <action android:name="com.google.android.c2dm.intent.RECEIVE" />
- <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
- <category android:name="com.example.gcm" />
- </intent-filter>
- </receiver>
- <service android:name=".MyIntentService" />
- </application>
-
-</manifest>
-</pre>
-
-<h3 id="registering">Registering for GCM</h3>
-
-<div class="sidebox-wrapper">
-<div class="sidebox">
- <h2>Streamlined Registration</h2>
- <p>There is now a simpler alternative to registering and unregistering. Simply call the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> method
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#register">{@code register(senderID...)}</a>.
-This method registers the application for GCM and returns the registration ID. To unregister, call the
-<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#unregister">{@code unregister()}</a> method (though you should rarely if ever need to unregister).</p>
-</div>
-</div>
-
-<p>An Android application needs to register with GCM servers before it can receive messages. To register, the application sends an Intent
-(<code>com.google.android.c2dm.intent.REGISTER</code>), with 2 extra parameters:
-</p>
-
-<ul>
- <li><code>sender</code> is the project number of the account authorized to send messages
-to the Android application. </li>
- <li><code>app</code> is the Android application's ID, set with a <code>PendingIntent</code> to
-allow the registration service to extract Android application information. </li>
-</ul>
-
-<p>For example:</p>
-
-<pre style="clear:right">Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
-// sets the app name in the intent
-registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
-registrationIntent.putExtra("sender", senderID);
-startService(registrationIntent);</pre>
-
-<p>This intent will be asynchronously sent to the GCM server, and the response will be delivered to
-the application as a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent containing
-the registration ID assigned to the Android application running on that particular device.</p>
-
-<p>Registration is not complete until the Android application sends the registration ID
-to the 3rd-party application server, which in turn will use the registration ID to send
-messages to the application.</p>
-
-<h3 id="unregistering">Unregistering from GCM</h3>
-
-<p>To unregister from GCM, do the following:</p>
-
-<pre class="prettyprint pretty-java">Intent unregIntent = new Intent("com.google.android.c2dm.intent.UNREGISTER");
-unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
-startService(unregIntent);
-</pre>
-
-<p>Similar to the registration request, this intent is sent asynchronously, and the response comes as a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent.
-
-
-<h3 id="handling_intents">Handling Intents sent by GCM</h3>
-
-<p>As discussed in <a href="#manifest">Creating the Manifest</a>, the manifest
-defines a broadcast receiver for the <code>com.google.android.c2dm.intent.REGISTRATION</code> and <code>com.google.android.c2dm.intent.RECEIVE</code> intents.
-These <a href="{@docRoot}guide/components/intents-filters.html">intents</a> are sent by GCM to indicate that a device was registered (or unregistered), or to deliver messages, respectively.</p>
-
-<p>Handling these intents might require I/O operations (such as network calls to the 3rd-party server), and
-such operations should not be done in the receiver's <code>onReceive()</code> method.
-You may be tempted to spawn a new thread directly, but there are no guarantees that the process will run long enough for the thread to finish the work.
-Thus the recommended way to handle the intents is to delegate them to a service, such as an {@link android.app.IntentService}.
-For example:</p>
-
-
-<pre class="prettyprint pretty-java">
-public class MyBroadcastReceiver extends BroadcastReceiver {
-
- @Override
- public final void onReceive(Context context, Intent intent) {
- MyIntentService.runIntentInService(context, intent);
- setResult(Activity.RESULT_OK, null, null);
- }
-}
-</pre>
-
-<p>Then in <code>MyIntentService</code>:</p>
-<pre class="prettyprint pretty-java">
-public class MyIntentService extends IntentService {
-
- private static PowerManager.WakeLock sWakeLock;
- private static final Object LOCK = MyIntentService.class;
-
- static void runIntentInService(Context context, Intent intent) {
- synchronized(LOCK) {
- if (sWakeLock == null) {
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "my_wakelock");
- }
- }
- sWakeLock.acquire();
- intent.setClassName(context, MyIntentService.class.getName());
- context.startService(intent);
- }
-
- @Override
- public final void onHandleIntent(Intent intent) {
- try {
- String action = intent.getAction();
- if (action.equals("com.google.android.c2dm.intent.REGISTRATION")) {
- handleRegistration(intent);
- } else if (action.equals("com.google.android.c2dm.intent.RECEIVE")) {
- handleMessage(intent);
- }
- } finally {
- synchronized(LOCK) {
- sWakeLock.release();
- }
- }
- }
-}
-</pre>
-
-<p class="note"><strong>Note:</strong> your application must acquire a wake lock before starting the service—otherwise the device could be put to sleep before the service is started.</p>
-
-<h4 id="handling_reg">Handling Registration Results</h4>
-
-<p>When a <code>com.google.android.c2dm.intent.REGISTRATION</code> intent is received, it could potentially contain 3 extras: <code>registration_id</code>, <code>error</code>, and <code>unregistered</code>.
-
-<p>When a registration succeeds, <code>registration_id</code> contains the registration ID and the other extras are not set.
-The application must ensure that the 3rd-party server receives the registration ID. It may do so by saving the registration ID and sending it to the server.
-If the network is down or there are errors, the application should retry sending the registration ID when the network is up again or the next time it starts.</p>
-
-<p class="note"><strong>Note:</strong> Although the <code>com.google.android.c2dm.intent.REGISTRATION</code> intent is typically received after a request was made by the application,
-Google may periodically refresh the registration ID. So the application must be prepared to handle it at any time.</p>
-
-<p>When an unregistration succeeds, only the <code>unregistered</code> extra is set, and similar to the registration workflow,
-the application must contact the 3rd-party server to remove the registration ID (note that the registration ID is not available in the intent,
-but the application should have saved the registration ID when it got it).<p>
-
-<p>If the application request (be it register or unregister) fails, the <code>error</code> will be set with an error code, and the other extras will not be set.
-
-Here are the possible error codes:</p>
-
-<table>
- <tr>
- <th>Error Code</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>SERVICE_NOT_AVAILABLE</code></td>
- <td>The device can't read the response, or there was a 500/503 from the
-server that can be retried later. The Android application should use exponential back-off and retry. See <a href="adv.html#retry">Advanced Topics</a> for more information. </td>
- </tr>
- <tr>
- <td><code>ACCOUNT_MISSING</code></td>
- <td>There is no Google account on the phone. The Android application should ask the
-user to open the account manager and add a Google account. Fix on the device
-side.</td>
- </tr>
- <tr>
- <td><code>AUTHENTICATION_FAILED</code></td>
- <td>Bad Google Account password. The Android application should ask the user to enter his/her Google Account
-password, and let the user retry manually later. Fix on the device side.</td>
- </tr>
- <tr>
- <td><code>INVALID_SENDER</code></td>
- <td>The sender account is not recognized. This must be fixed on the Android application side. The developer must fix the application to provide the right <code>sender</code> extra in the <code>com.google.android.c2dm.intent.REGISTER</code> intent.</td>
- </tr>
- <tr>
- <td><code>PHONE_REGISTRATION_ERROR</code></td>
- <td> Incorrect phone registration with Google. This
-phone doesn't currently support GCM.</td>
- </tr>
- <tr>
- <td><code>INVALID_PARAMETERS</code></td>
- <td>The request sent by the phone does not contain the expected parameters. This phone doesn't currently support GCM.</td>
- </tr>
-</table>
-
-
-
-
-<p>Here's an example on how to handle the registration in the <code>MyIntentService</code> example:</p>
-
-<pre class="prettyprint pretty-java">
-private void handleRegistration(Intent intent) {
- String registrationId = intent.getStringExtra("registration_id");
- String error = intent.getStringExtra("error");
- String unregistered = intent.getStringExtra("unregistered");
- // registration succeeded
- if (registrationId != null) {
- // store registration ID on shared preferences
- // notify 3rd-party server about the registered ID
- }
-
- // unregistration succeeded
- if (unregistered != null) {
- // get old registration ID from shared preferences
- // notify 3rd-party server about the unregistered ID
- }
-
- // last operation (registration or unregistration) returned an error;
- if (error != null) {
- if ("SERVICE_NOT_AVAILABLE".equals(error)) {
- // optionally retry using exponential back-off
- // (see <a href="adv.html#retry">Advanced Topics</a>)
- } else {
- // Unrecoverable error, log it
- Log.i(TAG, "Received error: " + error);
- }
- }
-}</pre>
-
-
-
-<h4 id="received_data">Handling Received Data</h4>
-
-<p>The <code>com.google.android.c2dm.intent.RECEIVE</code> intent is used by GCM to
-deliver the messages sent by the 3rd-party server to the application running in the device.
-If the server included key-pair values in the <code>data</code> parameter, they are available as
-extras in this intent, with the keys being the extra names. GCM also includes an extra called
-<code>from</code> which contains the sender ID as an string, and another called <code>collapse_key</code> containing the collapse key (when in use).
-
-<p>Here is an example, again using the <code>MyIntentReceiver</code> class:</p>
-
-<pre class="prettyprint pretty-java">
-private void handleMessage(Intent intent) {
- // server sent 2 key-value pairs, score and time
- String score = intent.getExtra("score");
- String time = intent.getExtra("time");
- // generates a system notification to display the score and time
-}</pre>
-
-<h3 id="testing">Developing and Testing Your Android Applications</h3>
-
-<p>Here are some guidelines for developing and testing an Android application
-that uses the GCM feature:</p>
-
-<ul>
- <li>To develop and test your Android applications, you need to run and debug the
-applications on an Android 2.2 system image that includes the necessary
-underlying Google services. </li>
- <li>To develop and debug on an actual device, you need a device running an
-Android 2.2 system image that includes the Google Play Store application. </li>
- <li>To develop and test on the Android Emulator, you need to download the
-Android 2.2 version of the Google APIs Add-On into your SDK using the <em>Android
-SDK and AVD Manager</em>. Specifically, you need to download the component named
-"Google APIs by Google Inc, Android API 8". Then, you need to set up
-an AVD that uses that system image. </li>
- <li>If the GCM feature is critical to the Android application's function, be sure to
-set <code>android:minSdkVersion="8"</code> in the manifest. This
-ensures that the Android application cannot be installed in an environment in which it
-could not run properly. </li>
-</ul>
-
<h2 id="server">Role of the 3rd-party Application Server</h2>
@@ -1105,6 +760,4 @@
</ol>
<p class="note"><strong>Note:</strong> Stats on the Google API Console are not enabled for GCM. You must use the <a href="http://play.google.com/apps/publish">Developer Console</a>.</p>
-<h2 id="example">Examples</h2>
-<p>See the <a href="demo.html">GCM Demo Application</a> document.</p>
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
index d938bd6..8ceea0cc 100644
--- a/docs/html/google/gcm/gs.jd
+++ b/docs/html/google/gcm/gs.jd
@@ -12,14 +12,14 @@
<li><a href="#create-proj">Creating a Google API Project</a></li>
<li><a href="#gcm-service">Enabling the GCM Service</a></li>
<li><a href="#access-key">Obtaining an API Key</a></li>
-<li><a href="#android-app">Writing the Android Application</a>
+<li><a href="#client">Writing a Client App</a></li>
+<li><a href="#server">Writing the Server Code</a></li>
</ol>
<h2>See Also</h2>
<ol class="toc">
<li><a href="https://code.google.com/apis/console">Google APIs Console page</a></li>
-<li><a href="{@docRoot}google/gcm/helper.html">Using the GCM Helper Libraries</a></li>
<li><a href="https://services.google.com/fb/forms/gcm/" class="external-link" target="_android">CCS and User Notifications Signup Form</a></li>
</ol>
@@ -29,20 +29,9 @@
<p>The sections below guide you through the process of setting up a GCM
implementation.
Before you start, make sure to <a href="/google/play-services/setup.html">set up
-the Google Play Services SDK</a>. You need this SDK to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> methods. Strictly speaking, the only thing you absolutely need this API for is upstream (device-to-cloud) messaging, but it also offers a streamlined registration API that is recommended.</p>
+the Google Play Services SDK</a>. You need this SDK to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> methods.</p>
-
-<!--the basic steps are:
-
-<ul>
-<li>Creating a Google APIs Project</li>
-<li>Setting up GCM in your apps</li>
-<li>Integrating </li>
-
-<p>Note that a full GCM implementation requires a server-side implementation, in addition to the client implementation in your app. For complete information, make sure to read the <a href="/google/gcm/index.html">Google Cloud Messaging documentation</a>.
--->
-
-
+<p>Note that a full GCM implementation requires a server-side implementation, in addition to the client implementation in your app. This document offers a complete example that includes both the client and server.</p>
<h2 id="create-proj">Creating a Google API project</h2>
@@ -95,17 +84,21 @@
<p> Take note of the <strong>API key</strong> value (<code>YourKeyWillBeShownHere</code>) in this example, as it will be used later on.</p>
<p class="note"><strong>Note:</strong> If you need to rotate the key, click <strong>Generate new key</strong>. A new key will be created while the old one will still be active for up to 24 hours. If you want to get rid of the old key immediately (for example, if you feel it was compromised), click <strong>Delete key</strong>.</p>
+<p>The following sections walk you through the steps of creating client and server-side code.</p>
-<h2 id="android-app">Writing the Android Application</h2>
-<p>This section describes the steps involved in writing an Android application that uses GCM.</p>
+<h2 id="client">Writing a Client App</h2>
-<h4 id="manifest">Step 1: Make the following changes in the application's Android manifest</h4>
+<p>This section walks you through the steps involved in writing a client-side application—that is, the GCM-enabled application that runs on an Android device. This client sample is designed to work in conjunction with the server code shown in <a href="#server">Writing the Server Code</a>, below.</p>
+
+
+
+<h3 id="manifest">Step 1: Edit Your App's Manifest</h3>
<ul>
<li>The <code>com.google.android.c2dm.permission.RECEIVE</code> permission so the Android application can register and receive messages.</li>
<li>The <code>android.permission.INTERNET</code> permission so the Android application can send the registration ID to the 3rd party server.</li>
<li>The <code>android.permission.GET_ACCOUNTS</code> permission as GCM requires a Google account (necessary only if if the device is running a version lower than Android 4.0.4)</li>
<li>The <code>android.permission.WAKE_LOCK</code> permission so the application can keep the processor from sleeping when a message is received. Optional—use only if the app wants to keep the device from sleeping.</li>
- <li>An <code>applicationPackage + ".permission.C2D_MESSAGE</code> permission to prevent other Android applications from registering and receiving the Android application's
+ <li>An <code>applicationPackage + ".permission.C2D_MESSAGE"</code> permission to prevent other Android applications from registering and receiving the Android application's
messages. The permission name must exactly match this pattern—otherwise the Android application will not receive the messages.</li>
<li>A receiver for <code>com.google.android.c2dm.intent.RECEIVE</code>, with the category set
as <code>applicationPackage</code>. The receiver should require the <code>com.google.android.c2dm.SEND</code> permission, so that only the GCM
@@ -149,106 +142,199 @@
</pre>
-<h4>Step 2: Register for GCM</h4>
+<h3 id="register">Step 2: Register for GCM</h3>
<p>An Android application running on a mobile device registers to receive messages by calling
the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> method
<a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#register">{@code register(senderID...)}</a>.
This method registers the application for GCM and returns the registration ID. This streamlined approach replaces the previous
-GCM registration process.</p>
+GCM registration process. See the example below for details.</p>
-<h4> Step 3: Write your application</h4>
+<h3 id="app"> Step 3: Write Your Application</h3>
<p>Finally, write your application. GCM offers a variety of ways to get the job done:</p>
<ul>
- <li>For your messaging server, you can either use the new <a href="ccs.html">GCM Cloud Connection Server</a> (CCS), the older <a href="gcm.html">GCM HTTP server</a>, or both in tandem.</li>
- <li>To write your client application, you can use any of the following:
- <ul>
- <li>The helper libraries, which are described in the <a href="{@docRoot}google/gcm/demo.html">Demo App Tutorial</a> and <a href="{@docRoot}google/gcm/helper.html">Using the GCM Helper Libraries</a>.</li>
- <li>The approach described in the <a href="{@docRoot}google/gcm/gcm.html#writing_apps">GCM Architectural Overview</a>.</li>
- <li>Regardless, you must use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs if you are doing upstream (device-to-cloud) messaging. Even if you are not doing upstream messaging, we recommend that you use this API to take advantage of the streamlined registration process—described above and shown in the following sample.</li>
+ <li>For your messaging server, you can either use the new <a href="ccs.html">GCM Cloud Connection Server</a> (CCS), the older <a href="gcm.html">GCM HTTP server</a>, or both in tandem. For more discussion, see see <a href="server.html">GCM Server</a>.</li>
+ <li>To write your client application (that is, the GCM-enabled app that runs on an Android device), use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs as shown below. Don't forget to set up your project to use the Google Play services SDK as described in <a href="/google/play-services/setup.html">Setup Google Play Services SDK</a>.</li>
</ul>
</li>
</ul>
-<h5 id="gs_example">Example</h5>
+<h4 id="example">Example</h4>
-<p>Here is a sample application that illustrates how to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. In this example, the sender is a <a href="{@docRoot}google/gcm/ccs.html">CCS</a> echo server. The sample consists of a main Activity ({@code DemoActivity}) and a broadcast receiver ({@code GcmBroadcastReceiver}).</p>
+<p>Here is a sample client application that illustrates how to use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. The sample consists of a main activity ({@code DemoActivity}) and a broadcast receiver ({@code GcmBroadcastReceiver}). You can use this client sample code in conjunction with the server code shown in <a href="#server">Writing the Server Code</a>.</p>
+<p>Note the following:</p>
+
+<ul>
+ <li>The sample primarily illustrates two things: registration, and upstream messaging. Upstream messaging only applies to apps that are running against a <a href="ccs.html">CCS</a> server; HTTP-based servers don't support upstream messaging.</li>
+ <li>The <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> registration APIs replace the old registration process, which was based on the now-obsolete client helper library. While the old registration process still works, we encourage you to use the newer <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> registration APIs, regardless of your underlying server.</li>
+</ul>
+
+<h5>Registering</h5>
<p>An Android application needs to register with GCM servers before it can receive messages. So in its {@code onCreate()} method, {@code DemoActivity} checks to see whether the app is registered with GCM and with the server:</p>
-<pre>public class DemoActivity extends Activity {
+<pre>/**
+ * Main UI for the demo app.
+ */
+public class DemoActivity extends Activity {
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
+ private static final String PROPERTY_APP_VERSION = "appVersion";
+ private static final String PROPERTY_ON_SERVER_EXPIRATION_TIME =
+ "onServerExpirationTimeMs";
/**
- * You can use your own project ID instead. This sender is a test CCS
- * echo server.
+ * Default lifespan (7 days) of a reservation until it is considered expired.
*/
- String GCM_SENDER_ID = "Your-Sender-ID";
+ public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 7;
- // Tag for log messages.
+ /**
+ * Substitute you own sender ID here.
+ */
+ String SENDER_ID = "Your-Sender-ID";
+
+ /**
+ * Tag used on log messages.
+ */
static final String TAG = "GCMDemo";
TextView mDisplay;
GoogleCloudMessaging gcm;
AtomicInteger msgId = new AtomicInteger();
SharedPreferences prefs;
+ Context context;
+
String regid;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // Make sure the app is registered with GCM and with the server
- prefs = getSharedPreferences(DemoActivity.class.getSimpleName(),
- Context.MODE_PRIVATE);
setContentView(R.layout.main);
-
mDisplay = (TextView) findViewById(R.id.display);
- regid = prefs.getString(PROPERTY_REG_ID, null);
-
- // If there is no registration ID, the app isn't registered.
- // Call registerBackground() to register it.
- if (regid == null) {
+ context = getApplicationContext();
+ regid = getRegistrationId(context);
+
+ if (regid.length() == 0) {
registerBackground();
}
-
gcm = GoogleCloudMessaging.getInstance(this);
- }</pre>
+ }
+...
+}</pre>
-<p>If the app isn't registered, {@code DemoActivity} calls the following {@code registerBackground()} method to register it. Note that because GCM methods are blocking, this has to take place on a background thread. This sample uses {@link android.os.AsyncTask} to accomplish this:</p>
+<p>The app calls {@code getRegistrationId()} to see whether there is an existing registration ID stored in shared preferences:</p>
-<pre>private void registerBackground() {
+<pre>/**
+ * Gets the current registration id for application on GCM service.
+ * <p>
+ * If result is empty, the registration has failed.
+ *
+ * @return registration id, or empty string if the registration is not
+ * complete.
+ */
+private String getRegistrationId(Context context) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ String registrationId = prefs.getString(PROPERTY_REG_ID, "");
+ if (registrationId.length() == 0) {
+ Log.v(TAG, "Registration not found.");
+ return "";
+ }
+ // check if app was updated; if so, it must clear registration id to
+ // avoid a race condition if GCM sends a message
+ int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
+ int currentVersion = getAppVersion(context);
+ if (registeredVersion != currentVersion || isRegistrationExpired()) {
+ Log.v(TAG, "App version changed or registration expired.");
+ return "";
+ }
+ return registrationId;
+}
+
+...
+
+/**
+ * @return Application's {@code SharedPreferences}.
+ */
+private SharedPreferences getGCMPreferences(Context context) {
+ return getSharedPreferences(DemoActivity.class.getSimpleName(),
+ Context.MODE_PRIVATE);
+}</pre>
+
+<p>If the registration ID doesn't exist, or the app was updated, or the registration ID has expired, {@code getRegistrationId()} returns an empty string to indicate that the app needs to get a new regID. {@code getRegistrationId()} calls the following methods to check the app version and whether the regID has expired:</p>
+
+<pre>/**
+ * @return Application's version code from the {@code PackageManager}.
+ */
+private static int getAppVersion(Context context) {
+ try {
+ PackageInfo packageInfo = context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0);
+ return packageInfo.versionCode;
+ } catch (NameNotFoundException e) {
+ // should never happen
+ throw new RuntimeException("Could not get package name: " + e);
+ }
+}
+
+/**
+ * Checks if the registration has expired.
+ *
+ * <p>To avoid the scenario where the device sends the registration to the
+ * server but the server loses it, the app developer may choose to re-register
+ * after REGISTRATION_EXPIRY_TIME_MS.
+ *
+ * @return true if the registration has expired.
+ */
+private boolean isRegistrationExpired() {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ // checks if the information is not stale
+ long expirationTime =
+ prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
+ return System.currentTimeMillis() > expirationTime;
+}</pre>
+
+
+<p>If there isn't a valid existing registration ID, {@code DemoActivity} calls the following {@code registerBackground()} method to register. Note that because GCM methods are blocking, this has to take place on a background thread. This sample uses {@link android.os.AsyncTask} to accomplish this:</p>
+
+<pre>
+/**
+ * Registers the application with GCM servers asynchronously.
+ * <p>
+ * Stores the registration id, app versionCode, and expiration time in the
+ * application's shared preferences.
+ */
+private void registerBackground() {
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
- regid = gcm.register(GCM_SENDER_ID);
+ if (gcm == null) {
+ gcm = GoogleCloudMessaging.getInstance(context);
+ }
+ regid = gcm.register(SENDER_ID);
msg = "Device registered, registration id=" + regid;
- // You should send the registration ID to your server over HTTP,
+ // You should send the registration ID to your server over HTTP,
// so it can use GCM/HTTP or CCS to send messages to your app.
- // For this demo: we don't need to send it because the device
- // will send upstream messages to a server that will echo back
- // the message using the 'from' address in the message.
-
- // Save the regid for future use - no need to register again.
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(PROPERTY_REG_ID, regid);
- editor.commit();
+ // For this demo: we don't need to send it because the device
+ // will send upstream messages to a server that echo back the message
+ // using the 'from' address in the message.
+
+ // Save the regid - no need to register again.
+ setRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
- // Once registration is done, display the registration status
- // string in the Activity's UI.
+
@Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
@@ -256,7 +342,33 @@
}.execute(null, null, null);
}</pre>
-<p>When the user clicks the app's <strong>Echo</strong> button, the app generates the necessary XMPP stanza for the message, which it sends to the echo server:</p>
+<p>After registering, the app calls {@code setRegistrationId()} to store the registration ID in shared preferences for future use:</p>
+
+<pre>/**
+ * Stores the registration id, app versionCode, and expiration time in the
+ * application's {@code SharedPreferences}.
+ *
+ * @param context application's context.
+ * @param regId registration id
+ */
+private void setRegistrationId(Context context, String regId) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ int appVersion = getAppVersion(context);
+ Log.v(TAG, "Saving regId on app version " + appVersion);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(PROPERTY_REG_ID, regId);
+ editor.putInt(PROPERTY_APP_VERSION, appVersion);
+ long expirationTime = System.currentTimeMillis() + REGISTRATION_EXPIRY_TIME_MS;
+
+ Log.v(TAG, "Setting registration expiry time to " +
+ new Timestamp(expirationTime));
+ editor.putLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, expirationTime);
+ editor.commit();
+}</pre>
+
+<h5>Sending a message</h5>
+<p>When the user clicks the app's <strong>Send</strong> button, the app sends an upstream message using the new <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> APIs. In order to receive the upstream message, your server should be connected to CCS. You can use the code shown in <a href="#server">Writing the Server Code</a> as a sample XMPP client to connect to CCS.</p>
+
<pre>public void onClick(final View view) {
if (view == findViewById(R.id.send)) {
new AsyncTask<Void, Void, String>() {
@@ -265,11 +377,10 @@
String msg = "";
try {
Bundle data = new Bundle();
- // data is a key-value pair.
- data.putString("hello", "world");
+ data.putString("hello", "World");
String id = Integer.toString(msgId.incrementAndGet());
- gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, data);
- msg = "Sending message";
+ gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
+ msg = "Sent message";
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
@@ -278,23 +389,25 @@
@Override
protected void onPostExecute(String msg) {
- // Displays the text "Sending message"
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
- }
+ } else if (view == findViewById(R.id.clear)) {
+ mDisplay.setText("");
+ }
}</pre>
<p>As described above in <a href="#manifest">Step 1</a>, the app includes a broadcast receiver for the <code>com.google.android.c2dm.intent.RECEIVE</code> intent. This is the mechanism GCM uses to deliver messages. When {@code onClick()} calls {@code gcm.send()}, it triggers the broadcast receiver's {@code onReceive()} method, which has the responsibility of handling the GCM message. In this sample the receiver's {@code onReceive()} method calls {@code sendNotification()} to put the message into a notification:</p>
-<pre>public class GcmBroadcastReceiver extends BroadcastReceiver {
+<pre>/**
+ * Handling of GCM messages.
+ */
+public class GcmBroadcastReceiver extends BroadcastReceiver {
static final String TAG = "GCMDemo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context ctx;
-
-
@Override
public void onReceive(Context context, Intent intent) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
@@ -303,7 +416,7 @@
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + intent.getExtras().toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
- sendNotification("Deleted messages on server: " +
+ sendNotification("Deleted messages on server: " +
intent.getExtras().toString());
} else {
sendNotification("Received: " + intent.getExtras().toString());
@@ -313,21 +426,98 @@
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
- mNotificationManager = (NotificationManager)
- ctx.getSystemService(Context.NOTIFICATION_SERVICE);
-
- PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
- new Intent(ctx, DemoActivity.class), 0);
-
- NotificationCompat.Builder mBuilder =
- new NotificationCompat.Builder(ctx)
- .setSmallIcon(R.drawable.ic_stat_notification)
- .setContentTitle("GCM Notification")
- .setStyle(new NotificationCompat.BigTextStyle()
- .bigText(msg))
- .setContentText(msg);
-
- mBuilder.setContentIntent(contentIntent);
- mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
+ mNotificationManager = (NotificationManager)
+ ctx.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
+ new Intent(ctx, DemoActivity.class), 0);
+
+ NotificationCompat.Builder mBuilder =
+ new NotificationCompat.Builder(ctx)
+ .setSmallIcon(R.drawable.ic_stat_gcm)
+ .setContentTitle("GCM Notification")
+ .setStyle(new NotificationCompat.BigTextStyle()
+ .bigText(msg))
+ .setContentText(msg);
+
+ mBuilder.setContentIntent(contentIntent);
+ mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}</pre>
+
+<h2 id="server">Writing the Server Code</h2>
+
+<p>Here is an example of a CCS server written in Python. You can use this in conjunction with the sample client code shown above. This sample echo server sends an initial message, and for every upstream message received, it sends a dummy response back to the application that sent the upstream message. This example illustrates how to connect,
+send, and receive GCM messages using XMPP. It shouldn't be used as-is
+on a production deployment. For examples of HTTP-based servers, see <a href="server.html">GCM Server</a>.</p>
+
+<pre>
+#!/usr/bin/python
+import sys, json, xmpp, random, string
+
+SERVER = 'gcm.googleapis.com'
+PORT = 5235
+USERNAME = ''
+PASSWORD = ''
+REGISTRATION_ID = ''
+
+unacked_messages_quota = 1000
+send_queue = []
+
+# Return a random alphanumerical id
+def random_id():
+ rid = ''
+ for x in range(8): rid += random.choice(string.ascii_letters + string.digits)
+ return rid
+
+def message_callback(session, message):
+ global unacked_messages_quota
+ gcm = message.getTags('gcm')
+ if gcm:
+ gcm_json = gcm[0].getData()
+ msg = json.loads(gcm_json)
+ if not msg.has_key('message_type'):
+ # Acknowledge the incoming message immediately.
+ send({'to': msg['from'],
+ 'message_type': 'ack',
+ 'message_id': msg['message_id']})
+ # Queue a response back to the server.
+ if msg.has_key('from'):
+ # Send a dummy echo response back to the app that sent the upstream message.
+ send_queue.append({'to': msg['from'],
+ 'message_id': random_id(),
+ 'data': {'pong': 1}})
+ elif msg['message_type'] == 'ack' or msg['message_type'] == 'nack':
+ unacked_messages_quota += 1
+
+def send(json_dict):
+ template = ("<message><gcm xmlns='google:mobile:data'>{1}</gcm></message>")
+ client.send(xmpp.protocol.Message(
+ node=template.format(client.Bind.bound[0], json.dumps(json_dict))))
+
+def flush_queued_messages():
+ global unacked_messages_quota
+ while len(send_queue) and unacked_messages_quota > 0:
+ send(send_queue.pop(0))
+ unacked_messages_quota -= 1
+
+client = xmpp.Client('gcm.googleapis.com', debug=['socket'])
+client.connect(server=(SERVER,PORT), secure=1, use_srv=False)
+auth = client.auth(USERNAME, PASSWORD)
+if not auth:
+ print 'Authentication failed!'
+ sys.exit(1)
+
+client.RegisterHandler('message', message_callback)
+
+send_queue.append({'to': REGISTRATION_ID,
+ 'message_id': 'reg_id',
+ 'data': {'message_destination': 'RegId',
+ 'message_id': random_id()}})
+
+while True:
+ client.Process(1)
+ flush_queued_messages()</pre>
+
+
+
diff --git a/docs/html/google/gcm/helper.jd b/docs/html/google/gcm/helper.jd
index bde2df0..e7f2f73 100644
--- a/docs/html/google/gcm/helper.jd
+++ b/docs/html/google/gcm/helper.jd
@@ -2,6 +2,23 @@
page.tags="cloud","push","messaging"
@jd:body
+<div id="deprecatedSticker">
+ <a href="#"
+ onclick="$('#naMessage').show();$('#deprecatedSticker').hide();return false">
+ <strong>This doc is deprecated</strong></a>
+</div>
+
+
+<div id="naMessage" style="display:block">
+<div><p><strong>The information in this document has been superseded by <a href="server.html">GCM Server</a> and <a href="client.html">GCM Client</a></strong>. Please use the <a href="{@docRoot}reference/com/google/android/gms/gcm/GoogleCloudMessaging.html">{@code GoogleCloudMessaging}</a> API instead of the GCM client helper library. The GCM server helper library is still valid.</p>
+
+ <input style="margin-top:1em;padding:5px" type="button"
+ value="That's nice, but I still want to read this document"
+onclick="$('#naMessage').hide();$('#deprecatedSticker').show()" />
+</div>
+</div>
+
+
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/google/gcm/index.jd b/docs/html/google/gcm/index.jd
index aeba86f..8f325b8 100644
--- a/docs/html/google/gcm/index.jd
+++ b/docs/html/google/gcm/index.jd
@@ -49,6 +49,9 @@
<h4>Seamless multi-device messaging</h4>
<p>Maps a single user to a notification key, which you can then use to send a single message to multiple devices owned by the user. Use <a href="https://services.google.com/fb/forms/gcm/">this form</a> to sign up for User Notifications. <a href="{@docRoot}google/gcm/notifications.html">Learn more »</a></p>
+
+ <h4>Get Started</h4>
+ <p>Get started using the new features with a tutorial that walks you through creating a GCM app. <a href="{@docRoot}google/gcm/gs.html">Learn more »</a></p>
</div>
</div>
diff --git a/docs/html/google/gcm/notifications.jd b/docs/html/google/gcm/notifications.jd
index 6a4b34a..df171cf 100644
--- a/docs/html/google/gcm/notifications.jd
+++ b/docs/html/google/gcm/notifications.jd
@@ -52,6 +52,9 @@
<p>The way this works is that during registration, the 3rd-party server requests a {@code notification_key}. The {@code notification_key} maps a particular user to all of the user's associated registration IDs (a regID represents a particular Android application running on a particular device). Then instead of sending one message to one regID at a time, the 3rd-party server can send a message to to the {@code notification_key}, which then sends the message to all of the user's regIDs.</p>
+<p class="note"><strong>Note:</strong> A notification dismissal message is like any other upstream message, meaning that it will be delivered to the other devices that belong to the specified {@code notification_key}. You should design your app to handle cases where the app receives a dismissal message, but has not yet displayed the notification that is being dismissed. You can solve this by caching the dismissal and then reconciling it with the corresponding notification.
+</p>
+
<p>You can use this feature with either the new <a href="ccs.html">GCM Cloud Connection Server</a> (CCS), or the older <a href="gcm.html">GCM HTTP server</a>.</p>
diff --git a/docs/html/google/gcm/server.jd b/docs/html/google/gcm/server.jd
new file mode 100644
index 0000000..92a1531
--- /dev/null
+++ b/docs/html/google/gcm/server.jd
@@ -0,0 +1,160 @@
+page.title=GCM Server
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Quickview</h2>
+
+<ul>
+<li>Understand how to set up the server side of a GCM app.</li>
+<li>Become familiar with the <a href="{@docRoot}reference/com/google/android/gcm/server/package-summary.html">GCM server helper library</a>.</li>
+</ul>
+
+
+<h2>In this document</h2>
+
+<ol>
+ <li><a href="#requirements">Requirements</a> </li>
+ <li><a href="#gcm-setup">Setting Up GCM</a></li>
+ <li><a href="#server-setup">Setting Up an HTTP Server</a>
+ <ol>
+ <li><a href="#webserver-setup">Using a standard web server</a></li>
+ <li><a href="#appengine-setup">Using App Engine for Java</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>See Also</h2>
+
+<ol class="toc">
+<li><a href="gs.html">Getting Started</a></li>
+<li><a href="client.html">GCM Client</a></li>
+<li><a href="ccs.html">Cloud Connection Server</a></li>
+
+
+</ol>
+
+</div>
+</div>
+
+
+
+
+<p>This document gives examples of GCM server-side code for HTTP. For an example of an XMPP server (<a href="ccs.html">Cloud Connection Server</a>), see <a href="gs.html#server">Getting Started</a>. Note that a full GCM implementation requires a client-side implementation, in addition to the server. For a complete working example that includes client and server-side code, see <a href="gs.html">Getting Started</a>.</a>
+
+<h2 id="requirements">Requirements</h2>
+<p>For the web server:</p>
+<ul>
+ <li> <a href="http://ant.apache.org/">Ant 1.8</a> (it might work with earlier versions, but it's not guaranteed).</li>
+ <li>One of the following:
+ <ul>
+ <li>A running web server compatible with Servlets API version 2.5, such as <a href="http://tomcat.apache.org/">Tomcat 6</a> or <a href="http://jetty.codehaus.org/">Jetty</a>, or</li>
+ <li><a href="http://code.google.com/appengine/">Java App Engine SDK</a> version 1.6 or later.</li>
+ </ul>
+ </li>
+ <li>A Google account registered to use GCM.</li>
+ <li>The API key for that account.</li>
+</ul>
+<p>For the Android application:</p>
+<ul>
+ <li>Emulator (or device) running Android 2.2 with Google APIs.</li>
+ <li>The Google API project number of the account registered to use GCM.</li>
+</ul>
+<h2 id="gcm-setup">Setting Up GCM</h2>
+<p>Before proceeding with the server and client setup, it's necessary to register a Google account with the Google API Console, enable Google Cloud Messaging in GCM, and obtain an API key from the <a href="https://code.google.com/apis/console">Google API Console</a>.</p>
+<p>For instructions on how to set up GCM, see <a href="gs.html">Getting Started</a>.</p>
+
+
+<h2 id="server-setup">Setting Up an HTTP Server</h2>
+<p>This section describes the different options for setting up an HTTP server.</p>
+<h3 id="webserver-setup">Using a standard web server</h3>
+<p>To set up the server using a standard, servlet-compliant web server:</p>
+<ol>
+ <li>From the <a href="http://code.google.com/p/gcm">open source site</a>, download the following directories: <code>gcm-server</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
+
+
+ <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
+ <li>In a shell window, go to the <code>samples/gcm-demo-server</code> directory.</li>
+ <li>Generate the server's WAR file by running <code>ant war</code>:</li>
+
+ <pre class="prettyprint">$ ant war
+
+Buildfile:build.xml
+
+init:
+ [mkdir] Created dir: build/classes
+ [mkdir] Created dir: dist
+
+compile:
+ [javac] Compiling 6 source files to build/classes
+
+war:
+ [war] Building war: <strong>dist/gcm-demo.war</strong>
+
+BUILD SUCCESSFUL
+Total time: 0 seconds
+</pre>
+
+ <li>Deploy the <code>dist/gcm-demo.war</code> to your running server. For instance, if you're using Jetty, copy <code>gcm-demo.war</code> to the <code>webapps</code> directory of the Jetty installation.</li>
+ <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/gcm-demo/home</code>, where <code>gcm-demo</code> is the application context and <code>/home</code> is the path of the main servlet.
+
+ </li>
+</ol>
+<p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows. </p>
+
+<p> You server is now ready.</p>
+
+<h3 id="appengine-setup">Using App Engine for Java</h3>
+
+<p>To set up the server using a standard App Engine for Java:</p>
+<ol>
+ <li>Get the files from the <a href="http://code.google.com/p/gcm">open source site</a>, as described above.</p>
+ </li>
+ <li>In a text editor, edit <code>samples/gcm-demo-appengine/src/com/google/android/gcm/demo/server/ApiKeyInitializer.java</code> and replace the existing text with the API key obtained above.
+
+ <p class="note"><strong>Note:</strong> The API key value set in that class will be used just once to create a persistent entity on App Engine. If you deploy the application, you can use App Engine's <code>Datastore Viewer</code> to change it later.</p>
+
+ </li>
+ <li>In a shell window, go to the <code>samples/gcm-demo-appengine</code> directory.</li>
+ <li>Start the development App Engine server by <code>ant runserver</code>, using the <code>-Dsdk.dir</code> to indicate the location of the App Engine SDK and <code>-Dserver.host</code> to set your server's hostname or IP address:</li>
+
+<pre class="prettyprint">
+$ ant -Dsdk.dir=/opt/google/appengine-java-sdk runserver -Dserver.host=192.168.1.10
+Buildfile: gcm-demo-appengine/build.xml
+
+init:
+ [mkdir] Created dir: gcm-demo-appengine/dist
+
+copyjars:
+
+compile:
+
+datanucleusenhance:
+ [enhance] DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
+ [enhance] DataNucleus Enhancer completed with success for 0 classes. Timings : input=28 ms, enhance=0 ms, total=28 ms. Consult the log for full details
+ [enhance] DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details
+
+runserver:
+ [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.jetty.JettyLogger info
+ [java] INFO: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
+ [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AppEngineWebXmlReader readAppEngineWebXml
+ [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/appengine-web.xml
+ [java] Jun 15, 2012 8:46:06 PM com.google.apphosting.utils.config.AbstractConfigXmlReader readConfigXml
+ [java] INFO: Successfully processed gcm-demo-appengine/WebContent/WEB-INF/web.xml
+ [java] Jun 15, 2012 8:46:09 PM com.google.android.gcm.demo.server.ApiKeyInitializer contextInitialized
+ [java] SEVERE: Created fake key. Please go to App Engine admin console, change its value to your API Key (the entity type is 'Settings' and its field to be changed is 'ApiKey'), then restart the server!
+ [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
+ [java] INFO: The server is running at http://192.168.1.10:8080/
+ [java] Jun 15, 2012 8:46:09 PM com.google.appengine.tools.development.DevAppServerImpl start
+ [java] INFO: The admin console is running at http://192.168.1.10:8080/_ah/admin
+</pre>
+
+ <li>Open the server's main page in a browser. The URL depends on the server you're using and your machine's IP address, but it will be something like <code>http://192.168.1.10:8080/home</code>, where <code>/home</code> is the path of the main servlet.</li>
+
+ <p class="note"><strong>Note:</strong> You can get the IP by running <code>ifconfig</code> on Linux or MacOS, or <code>ipconfig</code> on Windows.</p>
+
+</ol>
+<p> You server is now ready.</p>
+
+
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index 13d3eb3..891819b 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -132,11 +132,11 @@
<li><a href="<?cs var:toroot?>google/gcm/notifications.html">
<span class="en">User Notifications</span></a>
</li>
- <li><a href="<?cs var:toroot?>google/gcm/demo.html">
- <span class="en">Demo App Tutorial</span></a>
+ <li><a href="<?cs var:toroot?>google/gcm/client.html">
+ <span class="en">GCM Client</span></a>
</li>
- <li><a href="<?cs var:toroot?>google/gcm/helper.html">
- <span class="en">Using the Helper Libraries</span></a>
+ <li><a href="<?cs var:toroot?>google/gcm/server.html">
+ <span class="en">GCM Server</span></a>
</li>
<li><a href="<?cs var:toroot?>google/gcm/adv.html">
<span class="en">Advanced Topics</span></a>
diff --git a/docs/html/google/play-services/gcm.jd b/docs/html/google/play-services/gcm.jd
index 67b55ea..a9da73f 100644
--- a/docs/html/google/play-services/gcm.jd
+++ b/docs/html/google/play-services/gcm.jd
@@ -1,4 +1,4 @@
-page.title=GCM Extensions for Android
+page.title=GCM Extensions
page.tags="cloud","push","messaging"
header.hide=1
@jd:body
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index 2342087..069a603 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -1,4 +1,4 @@
-page.title=Android Supported Media Formats
+page.title=Supported Media Formats
page.tags="video","audio","mpeg","mp4","m4a","mp3","3gp","3gpp","flac","wave","wav"
@jd:body
diff --git a/docs/html/guide/faq/commontasks.jd b/docs/html/guide/faq/commontasks.jd
index 7b90de2..086721f 100644
--- a/docs/html/guide/faq/commontasks.jd
+++ b/docs/html/guide/faq/commontasks.jd
@@ -1,6 +1,5 @@
page.title=Common Tasks and How to Do Them in Android
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
+excludeFromSuggestions=true
@jd:body
<ul>
diff --git a/docs/html/guide/faq/framework.jd b/docs/html/guide/faq/framework.jd
index 4a7a3fc..c851e72 100644
--- a/docs/html/guide/faq/framework.jd
+++ b/docs/html/guide/faq/framework.jd
@@ -1,6 +1,5 @@
page.title=Android Application Framework FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
+excludeFromSuggestions=true
@jd:body
<ul>
diff --git a/docs/html/guide/faq/index.jd b/docs/html/guide/faq/index.jd
index 9a2614b..0c5fb0e 100644
--- a/docs/html/guide/faq/index.jd
+++ b/docs/html/guide/faq/index.jd
@@ -1,4 +1,5 @@
page.title=Android FAQs
+excludeFromSuggestions=true
@jd:body
<dl>
diff --git a/docs/html/guide/faq/licensingandoss.jd b/docs/html/guide/faq/licensingandoss.jd
index c267fe81..d1dd9a7 100644
--- a/docs/html/guide/faq/licensingandoss.jd
+++ b/docs/html/guide/faq/licensingandoss.jd
@@ -1,6 +1,5 @@
page.title=Android Open Source Licensing FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
+excludeFromSuggestions=true
@jd:body
<ul>
diff --git a/docs/html/guide/faq/security.jd b/docs/html/guide/faq/security.jd
index a6e07c8..96fc7f5 100644
--- a/docs/html/guide/faq/security.jd
+++ b/docs/html/guide/faq/security.jd
@@ -1,6 +1,5 @@
page.title=Android Security FAQ
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
+excludeFromSuggestions=true
@jd:body
<ul>
diff --git a/docs/html/guide/faq/troubleshooting.jd b/docs/html/guide/faq/troubleshooting.jd
index f19f5ec..8bb7eeb 100644
--- a/docs/html/guide/faq/troubleshooting.jd
+++ b/docs/html/guide/faq/troubleshooting.jd
@@ -1,6 +1,5 @@
page.title=Troubleshooting
-parent.title=FAQs, Tips, and How-to
-parent.link=index.html
+excludeFromSuggestions=true
@jd:body
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ff35d2e..16dca9d 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -76,9 +76,16 @@
<span class="en">Permissions</span>
</a>
</li>
- <li><a href="<?cs var:toroot ?>guide/topics/appwidgets/index.html">
+ <li class="nav-section">
+ <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/appwidgets/index.html">
<span class="en">App Widgets</span>
- </a></li>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/appwidgets/host.html">
+ <span class="en">App Widget Host</span>
+ </a></li>
+ </ul>
+ </li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/manifest/manifest-intro.html">
<span class="en">Android Manifest</span>
@@ -319,11 +326,11 @@
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html">
- <span class="en">Renderscript</span></a>
+ <span class="en">RenderScript</span></a>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/advanced.html">
- <span class="en">Advanced Renderscript</span></a>
+ <span class="en">Advanced RenderScript</span></a>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/renderscript/reference.html">
<span class="en">Runtime API Reference</span></a>
diff --git a/docs/html/guide/topics/appwidgets/host.jd b/docs/html/guide/topics/appwidgets/host.jd
new file mode 100644
index 0000000..da7408f
--- /dev/null
+++ b/docs/html/guide/topics/appwidgets/host.jd
@@ -0,0 +1,392 @@
+page.title=App Widget Host
+page.tags="AppWidgetHost","home screen","launcher"
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#host-binding">Binding App Widgets</a>
+ <ol>
+ <li><a href="#binding-pre">Binding app widgets on Android 4.0 and lower</a></li>
+ <li><a href="#binding-41">Binding app widgets on Android 4.1 and higher</a></li>
+ </ol>
+ </li>
+ <li><a href="#host-state">Host Responsibilities</a>
+ <ol>
+ <li><a href="#30">Android 3.0</a></li>
+ <li><a href="#31">Android 3.1</a></li>
+ <li><a href="#40">Android 4.0</a></li>
+ <li><a href="#41">Android 4.1</li>
+ <li><a href="#42">Android 4.2</a></li>
+ </ol>
+ </li>
+ </ol>
+ </div>
+</div>
+
+
+<p>The Android Home screen available on most Android devices allows the user
+to embed <a href="{@docRoot}guide/topics/appwidgets/index.html">app widgets</a> for quick
+access to content. If you're building a Home replacement or a similar app,
+you can also allow the user to embed app widgets by implementing an
+{@link android.appwidget.AppWidgetHost}.
+This is not something that most apps will ever need to do, but if you are
+creating your own host, it's important to understand the contractual obligations
+a host implicitly agrees to.</p>
+
+<p>This document focuses on the responsibilities involved in implementing a custom
+{@link android.appwidget.AppWidgetHost}. For an example of how to implement an
+{@link android.appwidget.AppWidgetHost}, see the source code for the
+Android Home screen
+<a href="https://android.googlesource.com/platform/packages/apps/Launcher2/+/master/src/com/android/launcher2/Launcher.java">
+Launcher</a>.
+
+
+<p>Here is an overview of key classes and concepts involved in implementing a custom
+{@link android.appwidget.AppWidgetHost}:</p>
+<ul>
+ <li><strong>App Widget Host</strong>—
+ The {@link android.appwidget.AppWidgetHost} provides the interaction
+with the AppWidget service for apps, like the home screen, that want to embed
+app widgets in their UI. An {@link android.appwidget.AppWidgetHost} must have
+an ID that is unique within the host's own package. This ID remains persistent
+across all uses of the host. The ID is typically a hard-coded value that you assign
+in your application.</li>
+
+ <li><strong>App Widget ID</strong>—
+ Each app widget instance is assigned a unique ID at the time of binding
+(see {@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed bindAppWidgetIdIfAllowed()},
+discussed in more detail in <a href="#binding">Binding app widgets</a>).
+The unique ID is obtained by the host using {@link android.appwidget.AppWidgetHost#allocateAppWidgetId() allocateAppWidgetId()}. This ID is persistent across the lifetime of the widget,
+that is, until it is deleted from the host. Any host-specific state (such as the
+size and location of the widget) should be persisted by the hosting package and
+associated with the app widget ID.
+</li>
+
+ <li><strong>App Widget Host View</strong>—
+ {@link android.appwidget.AppWidgetHostView} can be thought of as a frame
+that the widget is wrapped in whenever it needs to be displayed. An app widget
+is assigned to an {@link android.appwidget.AppWidgetHostView} every time the
+widget is inflated by the host. </li>
+ <li><strong>Options Bundle</strong>—
+The {@link android.appwidget.AppWidgetHost} uses the options bundle to communicate
+information to the {@link android.appwidget.AppWidgetProvider} about how the
+widget is being displayed (for example, size range, and whether the widget is on
+a lockscreen or the home screen). This information allows the
+{@link android.appwidget.AppWidgetProvider} to tailor the widget's contents
+and appearance based on how and where it is displayed.
+You use
+{@link android.appwidget.AppWidgetHostView#updateAppWidgetOptions(android.os.Bundle) updateAppWidgetOptions()}
+and
+{@link android.appwidget.AppWidgetHostView#updateAppWidgetSize updateAppWidgetSize()}
+
+to modify an app widget's
+bundle. Both of these methods trigger a callback to the
+{@link android.appwidget.AppWidgetProvider}.</p></li>
+</ul>
+
+<h2 id="host-binding">Binding App Widgets</h2>
+
+<p>When a user adds an app widget to a host, a process called
+<em>binding</em> occurs. <em>Binding</em> refers to associating
+a particular app widget ID to a specific host and to a specific
+{@link android.appwidget.AppWidgetProvider}. There are different
+ways of achieving this, depending on what version of Android your
+app is running on.</p>
+
+<h3 id="binding-pre">Binding app widgets on Android 4.0 and lower</h3>
+
+<p>On devices running Android version 4.0 and lower, users add app widgets
+via a system activity that allows users to select a widget. This implicitly
+does a permission check—that is, by adding the app widget, the user is
+implicitly granting permission to your app to add app widgets to the host.
+Here is an example that illustrates
+this approach, taken from the original
+<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">Launcher</a>. In this snippet, an event handler invokes
+{@link android.app.Activity#startActivityForResult(android.content.Intent,int) startActivityForResult()}
+with the request code {@code REQUEST_PICK_APPWIDGET} in response to a
+user action:</p>
+
+<pre>
+private static final int REQUEST_CREATE_APPWIDGET = 5;
+private static final int REQUEST_PICK_APPWIDGET = 9;
+...
+public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ ...
+ case AddAdapter.ITEM_APPWIDGET: {
+ ...
+ int appWidgetId =
+ Launcher.this.mAppWidgetHost.allocateAppWidgetId();
+ Intent pickIntent =
+ new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
+ pickIntent.putExtra
+ (AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+ ...
+ startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
+ break;
+ }
+ ...
+}</pre>
+
+<p>When the system activity finishes, it returns a result with the user's chosen
+app widget to your activity. In the following example, the activity responds
+by calling {@code addAppWidget()} to add the app widget:</p>
+
+<pre>public final class Launcher extends Activity
+ implements View.OnClickListener, OnLongClickListener {
+ ...
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ mWaitingForResult = false;
+
+ if (resultCode == RESULT_OK && mAddItemCellInfo != null) {
+ switch (requestCode) {
+ ...
+ case REQUEST_PICK_APPWIDGET:
+ addAppWidget(data);
+ break;
+ case REQUEST_CREATE_APPWIDGET:
+ completeAddAppWidget(data, mAddItemCellInfo, !mDesktopLocked);
+ break;
+ }
+ }
+ ...
+ }
+}</pre>
+
+<p>The method {@code addAppWidget()} checks to see if the app widget
+needs to be configured before it's added:</p>
+
+<pre>void addAppWidget(Intent data) {
+ int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+
+ String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
+ AppWidgetProviderInfo appWidget =
+ mAppWidgetManager.getAppWidgetInfo(appWidgetId);
+
+ if (appWidget.configure != null) {
+ // Launch over to configure widget, if needed.
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
+ intent.setComponent(appWidget.configure);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+ startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
+ } else {
+ // Otherwise, finish adding the widget.
+ }
+}</pre>
+
+<p>For more discussion of configuration,
+see <a href="{@docRoot}guide/topics/appwidgets/index.html#Configuring">Creating an
+App Widget Configuration Activity</a>.</p>
+
+<p>Once the app widget is ready, the next step is to do the
+actual work of adding it to the workspace. The
+<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">original Launcher</a> uses a method called {@code completeAddAppWidget()}
+to do this.</p>
+
+<h3 id="binding-41">Binding app widgets on Android 4.1 and higher</h3>
+
+<p>Android 4.1 adds APIs for a more streamlined binding process.
+These APIs also make it possible for a host to provide a custom UI for
+binding. To use this improved process, your app must declare the
+{@link android.Manifest.permission#BIND_APPWIDGET} permission in its manifest:</p>
+
+<pre><uses-permission android:name="android.permission.BIND_APPWIDGET" />
+</pre>
+
+
+<p>But this is just the first step. At runtime the user must
+explicitly grant permission to your app to allow it to add app widgets
+to the host. To test whether your app has permission to add the widget,
+you use the
+{@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed bindAppWidgetIdIfAllowed()}
+method.
+If {@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed bindAppWidgetIdIfAllowed()}
+returns {@code false}, your app must display a dialog prompting the
+user to grant permission
+("allow" or "always allow," to cover all future app widget additions).
+This snippet gives an example of how to display the dialog:</p>
+
+<pre>Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
+intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
+// This is the options bundle discussed above
+intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
+startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+</pre>
+
+<p>The host also has to check whether the user added
+an app widget that needs configuration. For more discussion of this topic,
+see
+<a href="{@docRoot}guide/topics/appwidgets/index.html#Configuring">Creating
+an App Widget Configuration Activity</a>.</p>
+
+<h2 id="host-state">Host Responsibilities</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h2>What Version are You Targeting?</h2>
+ <p>The approach you use in implementing your host should depend on what Android version
+you're targeting. Many of the features described in this section were introduced
+in 3.0 or later. For example:</p>
+<ul>
+<li>Android 3.0 (API Level 11) introduces auto-advance behavior for widgets.</li>
+<li>Android 3.1 (API Level 12) introduces the ability to resize widgets.</li>
+<li>Android 4.0 (API Level 15) introduces a change in padding policy that
+puts the responsibility on the
+host to manage padding.</li>
+<li>Android 4.1 (API Level 16) adds an API that allows the widget provider
+to get more detailed information about the environment in which its
+widget instances are being hosted.</li>
+<li>Android 4.2 (API Level 17) introduces the options bundle and the
+{@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed(int,android.content.ComponentName,android.os.Bundle) bindAppWidgetIdIfAllowed()}
+method. It also introduces lockscreen widgets.</li>
+</ul>
+<p>If you are targeting earlier devices, refer to the original
+<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">Launcher</a> as an example.
+</div>
+</div>
+
+<p>Widget developers can specify a number of configuration settings
+for widgets using the <a href="{@docRoot}guide/topics/appwidgets/index.html#MetaData">
+AppWidgetProviderInfo metadata</a>.
+These configuration options, discussed in more detail below, can be
+retrieved by the host from the {@link android.appwidget.AppWidgetProviderInfo}
+object associated with a widget provider.</p>
+
+<p>Regardless of the version of Android you are targeting, all hosts
+have the following responsibilities:</p>
+
+<ul>
+<li>When adding a widget, you must allocate the widget ID as described above.
+You must also make sure that when a widget is removed from the host, you call {@link android.appwidget.AppWidgetHost#deleteAppWidgetId deleteAppWidgetId()}
+to deallocate the widget ID.</li>
+
+<li>When adding a widget, be sure to launch its configuration activity
+if it exists, as described in
+<a href="{@docRoot}guide/topics/appwidgets/index.html#UpdatingFromTheConfiguration">
+Updating the App Widget
+from the Configuration Activity</a>. This is a necessary step for many app widgets before
+they can be properly displayed.</li>
+
+<li>Every app widget specifies a minimum width and height in dps, as defined in the {@link android.appwidget.AppWidgetProviderInfo} metadata
+(using {@link android.appwidget.AppWidgetProviderInfo#minWidth android:minWidth} and
+{@link android.appwidget.AppWidgetProviderInfo#minHeight android:minHeight}).
+Make sure that the widget is laid out with at least this many dps.
+For example, many hosts align icons and widgets in a grid. In this scenario,
+by default the host should add the app widget using the minimum number of
+cells that satisfy the {@code minWidth} and {@code minHeight} constraints.</li>
+
+</ul>
+
+<p>In addition to the requirements listed above, specific platform
+versions introduce features that place new responsibilities on the
+host. These are described in the following sections.</p>
+
+<h3 id="30">Android 3.0</h3>
+
+<p>Android 3.0 (API Level 11) introduces the ability for a widget to specify {@link android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId autoAdvanceViewId()}.
+This view ID should point to an instance of an
+{@link android.widget.Advanceable}, such as {@link android.widget.StackView}
+or {@link android.widget.AdapterViewFlipper}. This indicates that the host
+should call {@link android.widget.Advanceable#advance advance()} on this
+view at an interval deemed appropriate by the host (taking into account whether
+it makes sense to advance the widget—for example, the host probably
+wouldn't want to advance a widget if it were on another page, or
+if the screen were turned off).</p>
+
+<h3 id="31">Android 3.1</h3>
+
+<p>Android 3.1 (API Level 12) introduces the ability to resize widgets.
+A widget can specify that it is resizable using the
+{@link android.appwidget.AppWidgetProviderInfo#resizeMode android:resizeMode}
+attribute in the {@link android.appwidget.AppWidgetProviderInfo}
+metadata, and indicate whether it supports horizontal and/or
+vertical resizing. Introduced in Android 4.0 (API Level 14), the widget can also specify a
+{@link android.appwidget.AppWidgetProviderInfo#minResizeWidth android:minResizeWidth}
+and/or {@link android.appwidget.AppWidgetProviderInfo#minResizeHeight android:minResizeHeight}.</p>
+
+<p>It is the host’s responsibility to make it possible for the
+widget to be resized horizontally and/or vertically, as specified
+by the widget. A widget that specifies that it is resizable can be
+resized arbitrarily large, but should not be resized smaller than
+the values specified by {@link
+android.appwidget.AppWidgetProviderInfo#minResizeWidth android:minResizeWidth}
+and {@link
+android.appwidget.AppWidgetProviderInfo#minResizeHeight android:minResizeHeight}.
+For a sample implementation, see <a href="https://android.googlesource.com/platform/packages/apps/Launcher2/+/master/src/com/android/launcher2/AppWidgetResizeFrame.java">
+{@code AppWidgetResizeFrame}</a> in {@code Launcher2}.</p>
+
+
+<h3 id="40">Android 4.0</h3>
+
+<p>Android 4.0 (API Level 15) introduces a change in padding policy that
+puts the responsibility on the host to manage padding. As of 4.0, app
+widgets no longer include their own padding. Instead, the system adds
+padding for each widget, based the characteristics of the current screen.
+This leads to a more uniform, consistent presentation of widgets in a grid.
+To assist applications that host app widgets, the platform provides
+the method
+{@link android.appwidget.AppWidgetHostView#getDefaultPaddingForWidget getDefaultPaddingForWidget()}.
+Applications can call this method to get the system-defined padding
+and account for it when computing the number of cells to allocate to the widget.</p>
+
+<h3 id="41">Android 4.1</h3>
+
+<p>Android 4.1 (API Level 16) adds an API that allows the widget provider
+to get more detailed information about the environment in which its
+widget instances are being hosted. Specifically, the host hints to the
+widget provider about the size at which the widget is being displayed.
+It is the host’s responsibility to provide this size information.</p>
+
+<p>The host provides this information via
+{@link android.appwidget.AppWidgetHostView#updateAppWidgetSize updateAppWidgetSize()}.
+The size is specified as a minimum and maximum width/height in dps.
+The reason that a range is specified (as opposed to a fixed size)
+is because the width and height of a widget may change with orientation.
+You don’t want the host to have to update all of its widgets on rotation,
+as this could cause serious system slowdown. These values should be
+updated once upon the widget being placed, any time the widget is resized,
+and any time the launcher inflates the widget for the first time in a
+given boot (as the values aren’t persisted across boot).</p>
+
+
+<h3 id="42">Android 4.2</h3>
+
+<p>Android 4.2 (API Level 17) adds the ability for the options bundle
+to be specified at bind time. This is the ideal way to specify app
+widget options, including size, as it gives the {@link
+android.appwidget.AppWidgetProvider} immediate access to the options
+data on the first update. This can be achieved by using the method {@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed(int,android.content.ComponentName,android.os.Bundle) bindAppWidgetIdIfAllowed()}. For more discussion of this topic,
+see <a href="#host-binding">Binding app widgets</a>.</p>
+
+<p>Android 4.2 also introduces lockscreen widgets. When hosting widgets
+on the lockscreen, the host must specify this information within the app
+widget options bundle (the {@link
+android.appwidget.AppWidgetProvider} can use this information to style
+the widget appropriately). To designate a widget as a lockscreen widget, use {@link android.appwidget.AppWidgetHostView#updateAppWidgetOptions updateAppWidgetOptions()}
+and include the field
+{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_HOST_CATEGORY}
+with the value {@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}.
+This option defaults to
+{@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN},
+so it is not explicitly required to set this for a home screen host.</p>
+
+<p>Make sure that your host adds only app widgets that are appropriate
+for your app—for example, if your host is a home screen, ensure
+that the
+{@link android.appwidget.AppWidgetProviderInfo#widgetCategory android:widgetCategory}
+attribute in the
+{@link android.appwidget.AppWidgetProviderInfo} metadata includes
+the flag {@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN}.
+Similarly, for the lockscreen, ensure that field includes the flag {@link android.appwidget.AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}. For more
+discussion of this topic, see
+<a href="{@docRoot}guide/topics/appwidgets/index.html#lockscreen">
+Enabling App Widgets on the Lockscreen</a>.</p>
+
+
+
+
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 774c66a..d8ad844 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -22,15 +22,16 @@
<ol>
<li><a href="#UpdatingFromTheConfiguration">Updating the App Widget
from
- the configuration Activity</a></li>
+ the Configuration Activity</a></li>
</ol>
</li>
<li><a href="#preview">Setting a Preview Image</a></li>
- <li><a href="#lockscreen">Enabling App Widgets on the Lockscreen
+ <li><a href="#lockscreen">Enabling App Widgets on the Lockscreen</a>
<ol>
- <li><a href="#lockscreen-sizing">Sizing guidelines</li>
+ <li><a href="#lockscreen-sizing">Sizing guidelines</a></li>
</ol>
</li>
+
<li><a href="#collections">Using App Widgets with Collections</a>
<ol>
<li><a href="#collection_sample">Sample application</a></li>
@@ -66,7 +67,9 @@
<img src="{@docRoot}images/appwidgets/appwidget.png" alt="" />
<p>This document describes how to publish an App Widget using an App Widget
-provider.</p>
+provider. For a discussion of creating your own {@link android.appwidget.AppWidgetHost}
+to host app widgets, see <a href="{@docRoot}guide/topics/appwidgets/host.html">
+App Widget Host</a>.</p>
<div class="note design">
<p><strong>Widget Design</strong></p>
@@ -100,7 +103,7 @@
and allows him or her
to modify App Widget settings at create-time.</p>
-<p>The following sections describe how to setup each of these components.</p>
+<p>The following sections describe how to set up each of these components.</p>
<h2 id="Manifest">Declaring an App Widget in the Manifest</h2>
@@ -165,8 +168,8 @@
<pre>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="294dp"
- android:minHeight="72dp"
+ android:minWidth="40dp"
+ android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/preview"
android:initialLayout="@layout/example_appwidget"
@@ -270,6 +273,14 @@
To declare a widget as resizeable horizontally and vertically, supply the value
"horizontal|vertical". Introduced in Android 3.1.</li>
+<li>The <code>minResizeHeight</code> attribute specifies the minimum height (in dps) to which
+the widget can be resized. This field has no effect if it is greater than {@code minHeight} or if
+vertical resizing isn't enabled (see <code>resizeMode</code>). Introduced in Android 4.0.</li>
+
+<li>The <code> minResizeWidth </code> attribute specifies the minimum width (in dps) to which
+the widget can be resized. This field has no effect if it is greater than {@code minWidth} or if
+horizontal resizing isn't enabled (see <code>resizeMode</code>). Introduced in Android 4.0.</li>
+
<li>The <code>widgetCategory</code> attribute declares whether your App Widget can be displayed on the home screen,
the lock screen (keyguard), or both. Values for this attribute include "home_screen" and "keyguard". A widget that
is displayed on both needs to ensure that it follows the design guidelines for both widget classes. For more
@@ -788,12 +799,12 @@
<h2 id="collections">Using App Widgets with Collections</h2>
-<p>Android 3.0 introduces App Widgets with collections. These kinds of App
+<p>Android 3.0 introduces app widgets with collections. These kinds of App
Widgets use the {@link android.widget.RemoteViewsService} to display collections
that are backed by remote data, such as from a <a
href="{@docRoot}guide/topics/providers/content-providers.html">content
provider</a>. The data provided by the {@link android.widget.RemoteViewsService}
-is presented in the App Widget using one of the following view types, which
+is presented in the app widget using one of the following view types, which
we’ll refer to as “collection views:”</p>
<dl>
@@ -900,15 +911,15 @@
</ul>
<h3 id="implementing_collections">Implementing app widgets with collections</h3>
-<p>To implement an App Widget with collections, you follow the same basic steps
+<p>To implement an app widget with collections, you follow the same basic steps
you would use to implement any app widget. The following sections describe the
-additional steps you need to perform to implement an App Widget with
+additional steps you need to perform to implement an app widget with
collections.</p>
<h4>Manifest for app widgets with collections</h4>
<p> In addition to the requirements listed in <a href="#Manifest">Declaring an
-App Widget in the Manifest</a>, to make it possible for App Widgets with
+app widget in the Manifest</a>, to make it possible for app widgets with
collections to bind to your {@link android.widget.RemoteViewsService}, you must
declare the service in your manifest file with the permission {@link
android.Manifest.permission#BIND_REMOTEVIEWS}. This prevents other applications
@@ -987,7 +998,7 @@
android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}, and
the widget can serve up the appropriate data. When you call this method, you
must pass an intent that points to your implementation of {@link
-android.widget.RemoteViewsService} and the App Widget ID that specifies the app
+android.widget.RemoteViewsService} and the app widget ID that specifies the app
widget to update.</p>
@@ -1009,7 +1020,7 @@
// Add the app widget ID to the intent extras.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
- // Instantiate the RemoteViews object for the App Widget layout.
+ // Instantiate the RemoteViews object for the app widget layout.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
// Set up the RemoteViews object to use a RemoteViews adapter.
// This adapter connects
@@ -1367,15 +1378,15 @@
<h3 id="fresh">Keeping Collection Data Fresh</h3>
-<p>The following figure illustrates the flow that occurs in an App Widget that
+<p>The following figure illustrates the flow that occurs in an app widget that
uses
-collections when updates occur. It shows how the App Widget code interacts with
+collections when updates occur. It shows how the app widget code interacts with
the {@link android.widget.RemoteViewsService.RemoteViewsFactory
RemoteViewsFactory}, and how you can trigger updates:</p>
<img src="{@docRoot}images/appwidgets/appwidget_collections.png" alt="" />
-<p>One feature of App Widgets that use collections is the ability to provide
+<p>One feature of app widgets that use collections is the ability to provide
users with up-to-date content. For example, consider the Android 3.0 Gmail
app widget, which provides users with a snapshot of their inbox. To make this
possible, you need to be able to trigger your {@link
diff --git a/docs/html/guide/topics/renderscript/advanced.jd b/docs/html/guide/topics/renderscript/advanced.jd
index 58f5e1f..6a72b97 100644
--- a/docs/html/guide/topics/renderscript/advanced.jd
+++ b/docs/html/guide/topics/renderscript/advanced.jd
@@ -1,4 +1,4 @@
-page.title=Advanced Renderscript
+page.title=Advanced RenderScript
parent.title=Computation
parent.link=index.html
@@ -9,7 +9,7 @@
<h2>In this document</h2>
<ol>
- <li><a href="#native">Renderscript Runtime Layer</a></li>
+ <li><a href="#native">RenderScript Runtime Layer</a></li>
<li><a href="#reflected">Reflected Layer</a>
<ol>
<li><a href="#func">Functions</a></li>
@@ -25,7 +25,7 @@
<li>
<a href="#memory">Working with Memory</a>
<ol>
- <li><a href="#allocating-mem">Allocating and binding memory to the Renderscript</a></li>
+ <li><a href="#allocating-mem">Allocating and binding memory to the RenderScript</a></li>
<li><a href="#read-write">Reading and writing to memory</a></li>
@@ -37,36 +37,36 @@
<p></p>
- <p>Because applications that utilize Renderscript still run inside of the Android VM,
+ <p>Because applications that utilize RenderScript still run inside of the Android VM,
you have access to all of the framework APIs that you are familiar with, but can
- utilize Renderscript when appropriate. To facilitate this interaction between
- the framework and the Renderscript runtime, an intermediate layer of code is also
+ utilize RenderScript when appropriate. To facilitate this interaction between
+ the framework and the RenderScript runtime, an intermediate layer of code is also
present to facilitate communication and memory management between the two levels of code.
This document goes into more detail about these
different layers of code as well as how memory is shared between the Android VM and
- Renderscript runtime.</p>
+ RenderScript runtime.</p>
- <h2 id="native">Renderscript Runtime Layer</h2>
+ <h2 id="native">RenderScript Runtime Layer</h2>
- <p>Your Renderscript code is compiled and
- executed in a compact and well-defined runtime layer. The Renderscript runtime APIs offer support for
+ <p>Your RenderScript code is compiled and
+ executed in a compact and well-defined runtime layer. The RenderScript runtime APIs offer support for
intensive computation that is portable and automatically scalable to the
amount of cores available on a processor.
</p>
<p class="note"><strong>Note:</strong> The standard C functions in the NDK must be
- guaranteed to run on a CPU, so Renderscript cannot access these libraries,
- because Renderscript is designed to run on different types of processors.</p>
+ guaranteed to run on a CPU, so RenderScript cannot access these libraries,
+ because RenderScript is designed to run on different types of processors.</p>
-<p>You define your Renderscript code in <code>.rs</code>
+<p>You define your RenderScript code in <code>.rs</code>
and <code>.rsh</code> files in the <code>src/</code> directory of your Android project. The code
is compiled to intermediate bytecode by the
<code>llvm</code> compiler that runs as part of an Android build. When your application
runs on a device, the bytecode is then compiled (just-in-time) to machine code by another
<code>llvm</code> compiler that resides on the device. The machine code is optimized for the
- device and also cached, so subsequent uses of the Renderscript enabled application does not
+ device and also cached, so subsequent uses of the RenderScript enabled application does not
recompile the bytecode.</p>
- <p>Some key features of the Renderscript runtime libraries include:</p>
+ <p>Some key features of the RenderScript runtime libraries include:</p>
<ul>
@@ -79,20 +79,20 @@
<li>Conversion routines for primitive data types and vectors, matrix routines, and date and time
routines</li>
- <li>Data types and structures to support the Renderscript system such as Vector types for
+ <li>Data types and structures to support the RenderScript system such as Vector types for
defining two-, three-, or four-vectors.</li>
<li>Logging functions</li>
</ul>
- <p>See the Renderscript runtime API reference for more information on the available functions.
+ <p>See the RenderScript runtime API reference for more information on the available functions.
<h2 id="reflected">Reflected Layer</h2>
<p>The reflected layer is a set of classes that the Android build tools generate to allow access
- to the Renderscript runtime from the Android framework. This layer also provides methods
+ to the RenderScript runtime from the Android framework. This layer also provides methods
and constructors that allow you to allocate and work with memory for pointers that are defined in
-your Renderscript code. The following list describes the major
+your RenderScript code. The following list describes the major
components that are reflected:</p>
<ul>
@@ -105,9 +105,9 @@
<ul>
<li>Non-static functions</li>
- <li>Non-static, global Renderscript variables. Accessor methods are generated for each
- variable, so you can read and write the Renderscript variables from the Android
- framework. If a global variable is initialized at the Renderscript runtime layer, those
+ <li>Non-static, global RenderScript variables. Accessor methods are generated for each
+ variable, so you can read and write the RenderScript variables from the Android
+ framework. If a global variable is initialized at the RenderScript runtime layer, those
values are used to initialize the corresponding values in the Android framework layer. If global
variables are marked as <code>const</code>, then a <code>set</code> method is not
generated.</p></li>
@@ -128,7 +128,7 @@
<h3 id="func">Functions</h3>
<p>Functions are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. For
-example, if you declare the following function in your Renderscript code:</p>
+example, if you declare the following function in your RenderScript code:</p>
<pre>
void touch(float x, float y, float pressure, int id) {
@@ -155,14 +155,14 @@
}
</pre>
<p>
-Functions cannot have a return value, because the Renderscript system is designed to be
-asynchronous. When your Android framework code calls into Renderscript, the call is queued and is
-executed when possible. This restriction allows the Renderscript system to function without constant
+Functions cannot have a return value, because the RenderScript system is designed to be
+asynchronous. When your Android framework code calls into RenderScript, the call is queued and is
+executed when possible. This restriction allows the RenderScript system to function without constant
interruption and increases efficiency. If functions were allowed to have return values, the call
would block until the value was returned.</p>
<p>
-If you want the Renderscript code to send a value back to the Android framework, use the
+If you want the RenderScript code to send a value back to the Android framework, use the
<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a>
function.
</p>
@@ -172,7 +172,7 @@
<p>Variables of supported types are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. A set of accessor
methods are generated for each variable. For example, if you declare the following variable in
-your Renderscript code:</p>
+your RenderScript code:</p>
<pre>uint32_t unsignedInteger = 1;</pre>
<p>then the following code is generated:</p>
@@ -329,7 +329,7 @@
</pre>
<p>The generated code is provided to you as a convenience to allocate memory for structs requested
-by the Renderscript runtime and to interact with <code>struct</code>s
+by the RenderScript runtime and to interact with <code>struct</code>s
in memory. Each <code>struct</code>'s class defines the following methods and constructors:</p>
<ul>
@@ -356,11 +356,11 @@
</ul>
<p>You can specify multiple memory spaces by using the bitwise <code>OR</code> operator. Doing so
- notifies the Renderscript runtime that you intend on accessing the data in the
+ notifies the RenderScript runtime that you intend on accessing the data in the
specified memory spaces. The following example allocates memory for a custom data type
in both the script and vertex memory spaces:</p>
<pre>
- ScriptField_Point touchPoints = new ScriptField_Point(myRenderscript, 2,
+ ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2,
Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);
</pre>
</li>
@@ -370,13 +370,13 @@
with the <code>struct</code> in your Android code. When you are done manipulating the object,
you can push the object to the allocated memory by calling <code>set(Item i, int index,
boolean copyNow)</code> and setting the <code>Item</code> to the desired position in
-the array. The Renderscript runtime automatically has access to the newly written memory.
+the array. The RenderScript runtime automatically has access to the newly written memory.
<li>Accessor methods to get and set the values of each field in a struct. Each of these
accessor methods have an <code>index</code> parameter to specify the <code>struct</code> in
the array that you want to read or write to. Each setter method also has a
<code>copyNow</code> parameter that specifies whether or not to immediately sync this memory
-to the Renderscript runtime. To sync any memory that has not been synced, call
+to the RenderScript runtime. To sync any memory that has not been synced, call
<code>copyAll()</code>.</li>
<li>The <code>createElement()</code> method creates a description of the struct in memory. This
@@ -387,7 +387,7 @@
created.</li>
<li><code>copyAll()</code> synchronizes memory that was set on the framework level to the
-Renderscript runtime. When you call a set accessor method on a member, there is an optional
+RenderScript runtime. When you call a set accessor method on a member, there is an optional
<code>copyNow</code> boolean parameter that you can specify. Specifying
<code>true</code> synchronizes the memory when you call the method. If you specify false,
you can call <code>copyAll()</code> once, and it synchronizes memory for all the
@@ -397,7 +397,7 @@
<h3 id="pointer">Pointers</h3>
<p>Pointers are reflected into the script class itself, located in
<code>project_root/gen/package/name/ScriptC_renderscript_filename</code>. You
-can declare pointers to a <code>struct</code> or any of the supported Renderscript types, but a
+can declare pointers to a <code>struct</code> or any of the supported RenderScript types, but a
<code>struct</code> cannot contain pointers or nested arrays. For example, if you declare the
following pointers to a <code>struct</code> and <code>int32_t</code></p>
@@ -438,7 +438,7 @@
<p>A <code>get</code> method and a special method named <code>bind_<em>pointer_name</em></code>
(instead of a <code>set()</code> method) is generated. This method allows you to bind the memory
-that is allocated in the Android VM to the Renderscript runtime (you cannot allocate
+that is allocated in the Android VM to the RenderScript runtime (you cannot allocate
memory in your <code>.rs</code> file). For more information, see <a href="#memory">Working
with Allocated Memory</a>.
</p>
@@ -446,14 +446,14 @@
<h2 id="mem-allocation">Memory Allocation APIs</h2>
- <p>Applications that use Renderscript still run in the Android VM. The actual Renderscript code, however, runs natively and
+ <p>Applications that use RenderScript still run in the Android VM. The actual RenderScript code, however, runs natively and
needs access to the memory allocated in the Android VM. To accomplish this, you must
- attach the memory that is allocated in the VM to the Renderscript runtime. This
-process, called binding, allows the Renderscript runtime to seamlessly work with memory that it
+ attach the memory that is allocated in the VM to the RenderScript runtime. This
+process, called binding, allows the RenderScript runtime to seamlessly work with memory that it
requests but cannot explicitly allocate. The end result is essentially the same as if you had
called <code>malloc</code> in C. The added benefit is that the Android VM can carry out garbage collection as well as
-share memory with the Renderscript runtime layer. Binding is only necessary for dynamically allocated memory. Statically
-allocated memory is automatically created for your Renderscript code at compile time. See <a href="#figure1">Figure 1</a>
+share memory with the RenderScript runtime layer. Binding is only necessary for dynamically allocated memory. Statically
+allocated memory is automatically created for your RenderScript code at compile time. See <a href="#figure1">Figure 1</a>
for more information on how memory allocation occurs.
</p>
@@ -479,11 +479,11 @@
<p>In most situations, you do not need to call these memory allocation APIs directly. The reflected layer
classes generate code to use these APIs automatically and all you need to do to allocate memory is call a
constructor that is declared in one of the reflected layer classes and then bind
- the resulting memory {@link android.renderscript.Allocation} to the Renderscript.
+ the resulting memory {@link android.renderscript.Allocation} to the RenderScript.
There are some situations where you would want to use these classes directly to allocate memory on your
own, such as loading a bitmap from a resource or when you want to allocate memory for pointers to
primitive types. You can see how to do this in the
- <a href="#allocating-mem">Allocating and binding memory to the Renderscript</a> section.
+ <a href="#allocating-mem">Allocating and binding memory to the RenderScript</a> section.
The following table describes the three memory management classes in more detail:</p>
<table id="mem-mgmt-table">
@@ -500,12 +500,12 @@
<p>An element describes one cell of a memory allocation and can have two forms: basic or
complex.</p>
- <p>A basic element contains a single component of data of any valid Renderscript data type.
+ <p>A basic element contains a single component of data of any valid RenderScript data type.
Examples of basic element data types include a single <code>float</code> value, a <code>float4</code> vector, or a
single RGB-565 color.</p>
<p>Complex elements contain a list of basic elements and are created from
- <code>struct</code>s that you declare in your Renderscript code. For instance an allocation
+ <code>struct</code>s that you declare in your RenderScript code. For instance an allocation
can contain multiple <code>struct</code>s arranged in order in memory. Each struct is considered as its
own element, rather than each data type within that struct.</p>
</td>
@@ -552,64 +552,64 @@
<h2 id="memory">Working with Memory</h2>
-<p>Non-static, global variables that you declare in your Renderscript are allocated memory at compile time.
-You can work with these variables directly in your Renderscript code without having to allocate
+<p>Non-static, global variables that you declare in your RenderScript are allocated memory at compile time.
+You can work with these variables directly in your RenderScript code without having to allocate
memory for them at the Android framework level. The Android framework layer also has access to these variables
with the provided accessor methods that are generated in the reflected layer classes. If these variables are
-initialized at the Renderscript runtime layer, those values are used to initialize the corresponding
+initialized at the RenderScript runtime layer, those values are used to initialize the corresponding
values in the Android framework layer. If global variables are marked as const, then a <code>set</code> method is
not generated.</p>
-<p class="note"><strong>Note:</strong> If you are using certain Renderscript structures that contain pointers, such as
+<p class="note"><strong>Note:</strong> If you are using certain RenderScript structures that contain pointers, such as
<code>rs_program_fragment</code> and <code>rs_allocation</code>, you have to obtain an object of the
corresponding Android framework class first and then call the <code>set</code> method for that
-structure to bind the memory to the Renderscript runtime. You cannot directly manipulate these structures
-at the Renderscript runtime layer. This restriction is not applicable to user-defined structures
+structure to bind the memory to the RenderScript runtime. You cannot directly manipulate these structures
+at the RenderScript runtime layer. This restriction is not applicable to user-defined structures
that contain pointers, because they cannot be exported to a reflected layer class
in the first place. A compiler error is generated if you try to declare a non-static, global
struct that contains a pointer.
</p>
-<p>Renderscript also has support for pointers, but you must explicitly allocate the memory in your
+<p>RenderScript also has support for pointers, but you must explicitly allocate the memory in your
Android framework code. When you declare a global pointer in your <code>.rs</code> file, you
allocate memory through the appropriate reflected layer class and bind that memory to the native
-Renderscript layer. You can interact with this memory from the Android framework layer as well as
-the Renderscript layer, which offers you the flexibility to modify variables in the most
+RenderScript layer. You can interact with this memory from the Android framework layer as well as
+the RenderScript layer, which offers you the flexibility to modify variables in the most
appropriate layer.</p>
- <h3 id="allocating-mem">Allocating and binding dynamic memory to the Renderscript</h3>
+ <h3 id="allocating-mem">Allocating and binding dynamic memory to the RenderScript</h3>
<p>To allocate dynamic memory, you need to call the constructor of a
{@link android.renderscript.Script.FieldBase} class, which is the most common way. An alternative is to create an
{@link android.renderscript.Allocation} manually, which is required for things such as primitive type pointers. You should
use a {@link android.renderscript.Script.FieldBase} class constructor whenever available for simplicity.
After obtaining a memory allocation, call the reflected <code>bind</code> method of the pointer to bind the allocated memory to the
- Renderscript runtime.</p>
+ RenderScript runtime.</p>
<p>The example below allocates memory for both a primitive type pointer,
<code>intPointer</code>, and a pointer to a struct, <code>touchPoints</code>. It also binds the memory to the
- Renderscript:</p>
+ RenderScript:</p>
<pre>
-private RenderScript myRenderscript;
+private RenderScript myRenderScript;
private ScriptC_example script;
private Resources resources;
public void init(RenderScript rs, Resources res) {
- myRenderscript = rs;
+ myRenderScript = rs;
resources = res;
//allocate memory for the struct pointer, calling the constructor
- ScriptField_Point touchPoints = new ScriptField_Point(myRenderscript, 2);
+ ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2);
//Create an element manually and allocate memory for the int pointer
- intPointer = Allocation.createSized(myRenderscript, Element.I32(myRenderscript), 2);
+ intPointer = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2);
- //create an instance of the Renderscript, pointing it to the bytecode resource
- mScript = new ScriptC_example(myRenderscript, resources, R.raw.example);
+ //create an instance of the RenderScript, pointing it to the bytecode resource
+ mScript = new ScriptC_example(myRenderScript, resources, R.raw.example);
- //bind the struct and int pointers to the Renderscript
+ //bind the struct and int pointers to the RenderScript
mScript.bind_touchPoints(touchPoints);
script.bind_intPointer(intPointer);
@@ -618,29 +618,29 @@
</pre>
<h3>Reading and writing to memory</h3>
- <p>You can read and write to statically and dynamically allocated memory both at the Renderscript runtime
+ <p>You can read and write to statically and dynamically allocated memory both at the RenderScript runtime
and Android framework layer.</p>
<p>Statically allocated memory comes with a one-way communication restriction
-at the Renderscript runtime level. When Renderscript code changes the value of a variable, it is not
+at the RenderScript runtime level. When RenderScript code changes the value of a variable, it is not
communicated back to the Android framework layer for efficiency purposes. The last value
that is set from the Android framework is always returned during a call to a <code>get</code>
method. However, when Android framework code modifies a variable, that change can be communicated to
-the Renderscript runtime automatically or synchronized at a later time. If you need to send data
-from the Renderscript runtime to the Android framework layer, you can use the
+the RenderScript runtime automatically or synchronized at a later time. If you need to send data
+from the RenderScript runtime to the Android framework layer, you can use the
<a href="{@docRoot}reference/renderscript/rs__core_8rsh.html"><code>rsSendToClient()</code></a> function
to overcome this limitation.
</p>
-<p>When working with dynamically allocated memory, any changes at the Renderscript runtime layer are propagated
+<p>When working with dynamically allocated memory, any changes at the RenderScript runtime layer are propagated
back to the Android framework layer if you modified the memory allocation using its associated pointer.
-Modifying an object at the Android framework layer immediately propagates that change back to the Renderscript
+Modifying an object at the Android framework layer immediately propagates that change back to the RenderScript
runtime layer.</p>
<h4>Reading and writing to global variables</h4>
<p>Reading and writing to global variables is a straightforward process. You can use the accessor methods
- at the Android framework level or set them directly in the Renderscript code. Keep in mind that any
- changes that you make in your Renderscript code are not propagated back to the Android framework layer.</p>
+ at the Android framework level or set them directly in the RenderScript code. Keep in mind that any
+ changes that you make in your RenderScript code are not propagated back to the Android framework layer.</p>
<p>For example, given the following struct declared in a file named <code>rsfile.rs</code>:</p>
<pre>
@@ -659,8 +659,8 @@
point.y = 1;
</pre>
-<p>You can assign values to the struct at the Android framework layer like this. These values are
-propagated back to the Renderscript runtime level:</p>
+<p>You can assign values to the struct at the Android framework layer like this. These values are
+propagated back to the RenderScript runtime level:</p>
<pre>
ScriptC_rsfile mScript;
@@ -672,7 +672,7 @@
mScript.set_point(i);
</pre>
-<p>You can read the values in your Renderscript code like this:</p>
+<p>You can read the values in your RenderScript code like this:</p>
<pre>
rsDebug("Printing out a Point", point.x, point.y);
@@ -680,7 +680,7 @@
<p>You can read the values in the Android framework layer with the following code. Keep in mind that this
code only returns a value if one was set at the Android framework level. You will get a null pointer
-exception if you only set the value at the Renderscript runtime level:</p>
+exception if you only set the value at the RenderScript runtime level:</p>
<pre>
Log.i("TAGNAME", "Printing out a Point: " + mScript.get_point().x + " " + mScript.get_point().y);
@@ -689,9 +689,9 @@
<h4>Reading and writing global pointers</h4>
-<p>Assuming that memory has been allocated in the Android framework level and bound to the Renderscript runtime,
+<p>Assuming that memory has been allocated in the Android framework level and bound to the RenderScript runtime,
you can read and write memory from the Android framework level by using the <code>get</code> and <code>set</code> methods for that pointer.
-In the Renderscript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated
+In the RenderScript runtime layer, you can read and write to memory with pointers as normal and the changes are propagated
back to the Android framework layer, unlike with statically allocated memory.</p>
<p>For example, given the following pointer to a <code>struct</code> in a file named <code>rsfile.rs</code>:</p>
@@ -726,5 +726,5 @@
points.get_x(0);
</pre>
-<p>Once memory is already bound, you do not have to rebind the memory to the Renderscript
+<p>Once memory is already bound, you do not have to rebind the memory to the RenderScript
runtime every time you make a change to a value.</p>
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index 5f466ce..607d16e 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -1,4 +1,4 @@
-page.title=Renderscript Computation
+page.title=RenderScript
parent.title=Computation
parent.link=index.html
@@ -9,15 +9,8 @@
<h2>In this document</h2>
<ol>
- <li><a href="#overview">Renderscript System Overview</a></li>
- <li><a href="#filterscript">Filterscript</a></li>
- <li>
- <a href="#creating-renderscript">Creating a Computation Renderscript</a>
- <ol>
- <li><a href="#creating-rs-file">Creating the Renderscript file</a></li>
- <li><a href="#calling">Calling the Renderscript code</a></li>
- </ol>
- </li>
+ <li><a href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a></li>
+ <li><a href="#using-rs-from-java">Using RenderScript from Java Code</a></li>
</ol>
<h2>Related Samples</h2>
@@ -29,371 +22,204 @@
</div>
</div>
- <p>Renderscript offers a high performance computation API at the native
-level that you write in C (C99 standard). Renderscript gives your apps the ability to run
-operations with automatic parallelization across all available processor cores.
-It also supports different types of processors such as the CPU, GPU or DSP. Renderscript
-is useful for apps that do image processing, mathematical modeling, or any operations
-that require lots of mathematical computation.</p>
+<p>RenderScript is a framework for running computationally intensive tasks at high performance on
+Android. RenderScript is primarily oriented for use with data-parallel computation, although serial
+computationally intensive workloads can benefit as well. The RenderScript runtime will parallelize
+work across all processors available on a device, such as multi-core CPUs, GPUs, or DSPs, allowing
+you to focus on expressing algorithms rather than scheduling work or load balancing. RenderScript is
+especially useful for applications performing image processing, computational photography, or
+computer vision.</p>
-<p>In addition, you have access to all of these features without having to write code to
-support different architectures or a different amount of processing cores. You also
-do not need to recompile your application for different processor types, because Renderscript
-code is compiled on the device at runtime.</p>
-
-<p class="note"><strong>Deprecation Notice</strong>: Earlier versions of Renderscript included
- an experimental graphics engine component. This component
-is now deprecated as of Android 4.1 (most of the APIs in <code>rs_graphics.rsh</code>
-and the corresponding APIs in {@link android.renderscript}).
-If you have apps that render graphics with Renderscript, we highly
-recommend you convert your code to another Android graphics rendering option.</p>
-
- <h2 id="overview">Renderscript System Overview</h2>
- <p>The Renderscript runtime operates at the native level and still needs to communicate
-with the Android VM, so the way a Renderscript application is set up is different from a pure VM
-application. An application that uses Renderscript is still a traditional Android application that
-runs in the VM, but you write Renderscript code for the parts of your program that require
-it. No matter what you use it for, Renderscript remains platform
-independent, so you do not have to target multiple architectures (for example,
-ARM v5, ARM v7, x86).</p>
-
-<p>The Renderscript system adopts a control and slave architecture where the low-level Renderscript runtime
-code is controlled by the higher level Android system that runs in a virtual machine (VM). The
-Android VM still retains all control of memory management and binds memory that it allocates to
-the Renderscript runtime, so the Renderscript code can access it. The Android framework makes
-asynchronous calls to Renderscript, and the calls are placed in a message queue and processed
-as soon as possible. Figure 1 shows how the Renderscript system is structured.</p>
-
- <img id="figure1" src="{@docRoot}images/rs_overview.png" />
- <p class="img-caption"><strong>Figure 1.</strong> Renderscript system overview</p>
-
- <p>When using Renderscript, there are three layers of APIs that enable communication between the
- Renderscript runtime and Android framework code:</p>
-
- <ul>
- <li>The Renderscript runtime APIs allow you to do the computation
- that is required by your application.</li>
-
- <li>The reflected layer APIs are a set of classes that are reflected from your Renderscript
-runtime code. It is basically a wrapper around the Renderscript code that allows the Android
-framework to interact with the Renderscript runtime. The Android build tools automatically generate the
-classes for this layer during the build process. These classes eliminate the need to write JNI glue
-code, like with the NDK.</li>
-
- <li>The Android framework layer calls the reflected layer to access the Renderscript
- runtime.</li>
- </ul>
-
-<p>Because of the way Renderscript is structured, the main advantages are:</p>
- <ul>
- <li>Portability: Renderscript is designed to run on many types of devices with different
- processor (CPU, GPU, and DSP for instance) architectures. It supports all of these architectures without
- having to target each device, because the code is compiled and cached on the device
- at runtime.</li>
-
- <li>Performance: Renderscript provides a high performance computation API with seamless parallelization
- across the amount of cores on the device.</li>
-
- <li>Usability: Renderscript simplifies development when possible, such as eliminating JNI glue code.</li>
- </ul>
-
- <p>The main disadvantages are:</p>
-
- <ul>
- <li>Development complexity: Renderscript introduces a new set of APIs that you have to learn.</li>
-
- <li>Debugging visibility: Renderscript can potentially execute (planned feature for later releases)
- on processors other than the main CPU (such as the GPU), so if this occurs, debugging becomes more difficult.
- </li>
- </ul>
-
-<p>For a more detailed explanation of how all of these layers work together, see
- <a href="{@docRoot}guide/topics/renderscript/advanced.html">Advanced Renderscript</a>.<p>
-
-<h2 id="filterscript">Filterscript</h2>
-
-<p>Introduced in Android 4.2 (API Level 17), Filterscript defines a subset of Renderscript
-that focuses on image processing operations, such as those
-that you would typically write with an OpenGL ES fragment shader. You still write your scripts
-using the standard Renderscript runtime APIs, but within stricter
-constraints that ensure wider compatibility and improved optimization across
-CPUs, GPUs, and DSPs. At compile time, the precompiler evaluates Filterscript files and
-applies a more stringent set of warnings and errors than
-it does for standard Renderscript files. The following list describes the major constraints
-of Filterscript when compared to Renderscript:</p>
-
+<p>To begin with RenderScript, there are two main concepts you should understand:</p>
<ul>
-<li>Inputs and return values of root functions cannot contain pointers. The default root function
-signature contains pointers, so you must use the <code>__attribute__((kernel))</code> attribute to declare a custom
-root function when using Filterscript.</li>
-<li>Built-in types cannot exceed 32-bits.</li>
-<li>Filterscript must always use relaxed floating point precision by using the
-<code>rs_fp_relaxed</code> pragma.</li>
-<li>Filterscript files must end with an <code>.fs</code> extension, instead of an <code>.rs</code> extension.</li>
+
+<li>High-performance compute kernels are written in a C99-derived language.</li>
+
+<li>A Java API is used for managing the lifetime of RenderScript resources and controlling kernel
+execution.</li>
</ul>
-<h2 id="creating-renderscript">Creating a Renderscript</h2>
+<h2 id="writing-an-rs-kernel">Writing a RenderScript Kernel</h2>
-<p>Renderscript scales to the amount of
-processing cores available on the device. This is enabled through a function named
-<code>rsForEach()</code> (or the <code>forEach_root()</code> method at the Android framework level).
-that automatically partitions work across available processing cores on the device.</p>
-
-<p>Implementing a Renderscript involves creating a <code>.rs</code> file that contains
-your Renderscript code and calling it at the Android framework level with the
-<code>forEach_root()</code> or at the Renderscript runtime level with the
-<code>rsForEach()</code> function. The following diagram describes how a typical
-Renderscript is set up:</p><img src="{@docRoot}images/rs_compute.png">
-
-<p class="img-caption"><strong>Figure 1.</strong> Renderscript overview</p>
-
-<p>The following sections describe how to create a simple Renderscript and use it in an
-Android application. This example uses the <a href=
-"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute Renderscript
-sample</a> that is provided in the SDK as a guide (some code has been modified from its original
-form for simplicity).</p>
-
-<h3 id="creating-rs-file">Creating the Renderscript file</h3>
-
-<p>Your Renderscript code resides in <code>.rs</code> and <code>.rsh</code> files in the
-<code><project_root>/src/</code> directory. This code contains the computation logic
-and declares all necessary variables and pointers.
-Every <code>.rs</code> file generally contains the following items:</p>
+<p>A RenderScript kernel typically resides in a <code>.rs</code> file in the
+<code><project_root>/src/</code> directory; each <code>.rs</code> file is called a
+script. Every script contains its own set of kernels, functions, and variables. A script can
+contain:</p>
<ul>
- <li>A pragma declaration (<code>#pragma rs java_package_name(<em>package.name</em>)</code>)
- that declares the package name of the <code>.java</code> reflection of this Renderscript.</li>
+<li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of the
+RenderScript kernel language used in this script. Currently, 1 is the only valid value.</li>
- <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of
- Renderscript that you are using (1 is the only value for now).</li>
-
- <li><p>A root function (or kernel) that is the main entry point to your Renderscript.
- The default <code>root()</code> function must return
- <code>void</code> and accept the following arguments:</p>
+<li>A pragma declaration (<code>#pragma rs java_package_name(com.example.app)</code>) that
+declares the package name of the Java classes reflected from this script.</li>
- <ul>
- <li>Pointers to memory allocations that are used for the input and output of the
- Renderscript. Both of these pointers are required for Android 3.2 (API level 13) platform
- versions or older. Android 4.0 (API level 14) and later requires one or both of these
- allocations.</li>
- </ul>
+<li>Some number of invokable functions. An invokable function is a single-threaded RenderScript
+function that you can call from your Java code with arbitrary arguments. These are often useful for
+initial setup or serial computations within a larger processing pipeline.</li>
- <p>The following arguments are optional, but both must be supplied if you choose to use
- them:</p>
+<li>Some number of script globals. A script global is equivalent to a global variable in C. You can
+access script globals from Java code, and these are often used for parameter passing to RenderScript
+kernels.</li>
- <ul>
- <li>A pointer for user-defined data that the Renderscript might need to carry out
- computations in addition to the necessary allocations. This can be a pointer to a simple
- primitive or a more complex struct.</li>
+<li>Some number of compute kernels. A kernel is a parallel function that executes across every
+{@link android.renderscript.Element} within an {@link android.renderscript.Allocation}.
- <li>The size of the user-defined data.</li>
- </ul>
+<p>A simple kernel may look like the following:</p>
- <p>Starting in Android 4.1 (API Level 16), you can choose to define your own root function arguments
- without adhering to the default root function signature described previously. In addition,
- you can declare multiple root functions in the same Renderscript. To do this, use the <code>__attribute__((kernel))</code>
- attribute to define a custom root function. For example, here's a root function
- that returns a <code>uchar4</code> and accepts two <code>uint32_t</code> types: </p>
+<pre>uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {
+ uchar4 out = in;
+ out.r = 255 - in.r;
+ out.g = 255 - in.g;
+ out.b = 255 - in.b;
+ return out;
+}</pre>
- <pre>
- uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
- ...
- }
- </pre>
- </li>
+<p>In most respects, this is identical to a standard C function. The first notable feature is the
+<code>__attribute__((kernel))</code> applied to the function prototype. This denotes that the
+function is a RenderScript kernel instead of an invokable function. The next feature is the
+<code>in</code> argument and its type. In a RenderScript kernel, this is a special argument that is
+automatically filled in based on the input {@link android.renderscript.Allocation} passed to the
+kernel launch. By default, the kernel is run across an entire {@link
+android.renderscript.Allocation}, with one execution of the kernel body per {@link
+android.renderscript.Element} in the {@link android.renderscript.Allocation}. The third notable
+feature is the return type of the kernel. The value returned from the kernel is automatically
+written to the appropriate location in the output {@link android.renderscript.Allocation}. The
+RenderScript runtime checks to ensure that the {@link android.renderscript.Element} types of the
+input and output Allocations match the kernel's prototype; if they do not match, an exception is
+thrown.</p>
- <li>An optional <code>init()</code> function. This allows you to do any initialization
- before the root function runs, such as initializing variables. This
- function runs once and is called automatically when the Renderscript starts, before anything
- else in your Renderscript.</li>
+<p>A kernel may have an input {@link android.renderscript.Allocation}, an output {@link
+android.renderscript.Allocation}, or both. A kernel may not have more than one input or one output
+{@link android.renderscript.Allocation}. If more than one input or output is required, those objects
+should be bound to <code>rs_allocation</code> script globals and accessed from a kernel or invokable
+function via <code>rsGetElementAt_<em>type</em>()</code> or
+<code>rsSetElementAt_<em>type</em>()</code>.</p>
- <li>Any variables, pointers, and structures that you wish to use in your Renderscript code (can
- be declared in <code>.rsh</code> files if desired)</li>
-</ul>
+<p>A kernel may access the coordinates of the current execution using the <code>x</code>,
+<code>y</code>, and <code>z</code> arguments. These arguments are optional, but the type of the
+coordinate arguments must be <code>uint32_t</code>.</p></li>
-<p>The following code shows how the <a href=
-"{@docRoot}resources/samples/RenderScript/HelloCompute/src/com/example/android/rs/hellocompute/mono.html">
-mono.rs</a> file is implemented:</p>
-<pre>
-#pragma version(1)
-#pragma rs java_package_name(com.example.android.rs.hellocompute)
+<li>An optional <code>init()</code> function. An <code>init()</code> function is a special type of
+invokable function that is run when the script is first instantiated. This allows for some
+computation to occur automatically at script creation.</li>
-//multipliers to convert a RGB colors to black and white
-const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
-
-void root(const uchar4 *v_in, uchar4 *v_out) {
- //unpack a color to a float4
- float4 f4 = rsUnpackColor8888(*v_in);
- //take the dot product of the color and the multiplier
- float3 mono = dot(f4.rgb, gMonoMult);
- //repack the float to a color
- *v_out = rsPackColorTo8888(mono);
-}
-</pre>
+<li>Some number of static script globals and functions. A static script global is equivalent to a
+script global except that it cannot be set from Java code. A static function is a standard C
+function that can be called from any kernel or invokable function in the script but is not exposed
+to the Java API. If a script global or function does not need to be called from Java code, it is
+highly recommended that those be declared <code>static</code>.</li> </ul>
<h4>Setting floating point precision</h4>
-<p>You can define the floating point precision required by your compute algorithms. This is useful if you
- require less precision than the IEEE 754-2008 standard (used by default). You can define
-the floating-point precision level of your script with the following pragmas:</p>
+
+<p>You can control the required level of floating point precision in a script. This is useful if
+full IEEE 754-2008 standard (used by default) is not required. The following pragmas can set a
+different level of floating point precision:</p>
<ul>
- <li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that
- require floating point precision as outlined by the IEEE 754-2008 standard.
+
+<li><code>#pragma rs_fp_full</code> (default if nothing is specified): For apps that require
+ floating point precision as outlined by the IEEE 754-2008 standard.
+
</li>
- <li><code>#pragma rs_fp_relaxed</code> - For apps that don’t require
- strict IEEE 754-2008 compliance and can tolerate less precision. This mode enables
- flush-to-zero for denorms and round-towards-zero.
+
+ <li><code>#pragma rs_fp_relaxed</code> - For apps that don’t require strict IEEE 754-2008
+ compliance and can tolerate less precision. This mode enables flush-to-zero for denorms and
+ round-towards-zero.
+
</li>
- <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision requirements. This mode enables
- everything in <code>rs_fp_relaxed</code> along with the following:
+
+ <li><code>#pragma rs_fp_imprecise</code> - For apps that don’t have stringent precision
+ requirements. This mode enables everything in <code>rs_fp_relaxed</code> along with the
+ following:
+
<ul>
+
<li>Operations resulting in -0.0 can return +0.0 instead.</li>
<li>Operations on INF and NAN are undefined.</li>
</ul>
</li>
</ul>
-<h4>Script intrinsics</h4>
-<p>Renderscript adds support for a set of script intrinsics, which are pre-implemented
-filtering primitives that reduce the amount of
-code that you need to write. They also are implemented to ensure that your app gets the
-maximum performance gain possible.</p>
+<p>Most applications can use <code>rs_fp_relaxed</code> without any side effects. This may be very
+beneficial on some architectures due to additional optimizations only available with relaxed
+precision (such as SIMD CPU instructions).</p>
-<p>
-Intrinsics are available for the following:
+<h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
+
+<p>Using RenderScript from Java code relies on the {@link android.renderscript} APIs. Most
+applications follow the same basic usage patterns:</p>
+
+<ol>
+
+<li><strong>Initialize a RenderScript context.</strong> The {@link
+android.renderscript.RenderScript} context, created with {@link
+android.renderscript.RenderScript#create}, ensures that RenderScript can be used and provides an
+object to control the lifetime of all subsequent RenderScript objects. You should consider context
+creation to be a potentially long-running operation, since it may create resources on different
+pieces of hardware; it should not be in an application's critical path if at all
+possible. Typically, an application will have only a single RenderScript context at a time.</li>
+
+<li><strong>Create at least one {@link android.renderscript.Allocation} to be passed to a
+script.</strong> An {@link android.renderscript.Allocation} is a RenderScript object that provides
+storage for a fixed amount of data. Kernels in scripts take {@link android.renderscript.Allocation}
+objects as their input and output, and {@link android.renderscript.Allocation} objects can be
+accessed in kernels using <code>rsGetElementAt_<em>type</em>()</code> and
+<code>rsSetElementAt_<em>type</em>()</code> when bound as script globals. {@link
+android.renderscript.Allocation} objects allow arrays to be passed from Java code to RenderScript
+code and vice-versa. {@link android.renderscript.Allocation} objects are typically created using
+{@link android.renderscript.Allocation#createTyped} or {@link
+android.renderscript.Allocation#createFromBitmap}.</li>
+
+<li><strong>Create whatever scripts are necessary.</strong> There are two types of scripts available
+to you when using RenderScript:
+
<ul>
- <li>{@link android.renderscript.ScriptIntrinsicBlend Blends}</li>
- <li>{@link android.renderscript.ScriptIntrinsicBlur Blur}</li>
- <li>{@link android.renderscript.ScriptIntrinsicColorMatrix Color matrix}</li>
- <li>{@link android.renderscript.ScriptIntrinsicConvolve3x3 3x3 convolve}</li>
- <li>{@link android.renderscript.ScriptIntrinsicConvolve5x5 5x5 convolve}</li>
- <li>{@link android.renderscript.ScriptIntrinsicLUT Per-channel lookup table}</li>
- <li>{@link android.renderscript.ScriptIntrinsicYuvToRGB Converting an Android YUV buffer to RGB}</li>
-</ul>
-<h3 id="calling">Calling the Renderscript code</h3>
+<li><strong>ScriptC</strong>: These are the user-defined scripts as described in <a
+href="#writing-an-rs-kernel">Writing a RenderScript Kernel</a> above. Every script has a Java class
+reflected by the RenderScript compiler in order to make it easy to access the script from Java code;
+this class will have the name <code>ScriptC_<em>filename</em></code>. For example, if the kernel
+above was located in <code>invert.rs</code> and a RenderScript context was already located in
+<code>mRS</code>, the Java code to instantiate the script would be:
-<p>You can call the Renderscript from your Android framework code by
-creating a Renderscript object by instantiating the (<code>ScriptC_<em>script_name</em></code>)
-class. This class contains a method, <code>forEach_root()</code>, that lets you invoke
-<code>rsForEach</code>. You give it the same parameters that you would if you were invoking it
-at the Renderscript runtime level. This technique allows your Android application to offload
-intensive mathematical calculations to Renderscript. See the <a href=
-"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute</a> sample to see
-how a simple Android application can utilize Renderscript.</p>
+<pre>ScriptC_invert invert = new ScriptC_invert(mRenderScript);</pre></li>
-<p>To call Renderscript at the Android framework level:</p>
+<li><strong>ScriptIntrinsic</strong>: These are built-in RenderScript kernels for common operations,
+such as Gaussian blur, convolution, and image blending. For more information, see the subclasses of
+{@link android.renderscript.ScriptIntrinsic}.</li>
-<ol>
- <li>Allocate memory that is needed by the Renderscript in your Android framework code.
- You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level
- 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only
- one or both {@link android.renderscript.Allocation}s.</li>
+</ul></li>
- <li>Create an instance of the <code>ScriptC_<em>script_name</em></code> class.</li>
+<li><strong>Populate Allocations with data.</strong> Except for Allocations created with {@link
+android.renderscript#createFromBitmap}, an Allocation will be populated with empty data when it is
+first created. To populate an Allocation, use one of the <code>copy</code> methods in {@link
+android.renderscript.Allocation}.</li>
- <li>Call <code>forEach_root()</code>, passing in the allocations, the
- Renderscript, and any optional user-defined data. The output allocation will contain the output
- of the Renderscript.</li>
-</ol>
+<li><strong>Set any necessary script globals.</strong> Globals may be set using methods in the same
+<code>ScriptC_<em>filename</em></code> class with methods named
+<code>set_<em>globalname</em></code>. For example, in order to set an <code>int</code> named
+<code>elements</code>, use the Java method <code>set_elements(int)</code>. RenderScript objects can
+also be set in kernels; for example, the <code>rs_allocation</code> variable named
+<code>lookup</code> can be set with the method <code>set_lookup(Allocation)</code>.</li>
-<p>The following example, taken from the <a href=
-"{@docRoot}resources/samples/RenderScript/HelloCompute/index.html">HelloCompute</a> sample, processes
-a bitmap and outputs a black and white version of it. The
-<code>createScript()</code> method carries out the steps described previously. This method calls the
-Renderscript, <code>mono.rs</code>, passing in memory allocations that store the bitmap to be processed
-as well as the eventual output bitmap. It then displays the processed bitmap onto the screen:</p>
-<pre>
-package com.example.android.rs.hellocompute;
+<li><strong>Launch the appropriate kernels.</strong> Methods to launch a given kernel will be
+reflected in the same <code>ScriptC_<em>filename</em></code> class with methods named
+<code>forEach_<em>kernelname</em>()</code>. These launches are asynchronous, and launches will be
+serialized in the order in which they are launched. Depending on the arguments to the kernel, the
+method will take either one or two Allocations. By default, a kernel will execute over the entire
+input or output Allocation; to execute over a subset of that Allocation, pass an appropriate {@link
+android.renderscript.Script.LaunchOptions} as the last argument to the <code>forEach</code> method.
-import android.app.Activity;
-import android.os.Bundle;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import android.renderscript.RenderScript;
-import android.renderscript.Allocation;
-import android.widget.ImageView;
+<p>Invoked functions can be launched using the <code>invoke_<em>functionname</em></code> methods
+reflected in the same <code>ScriptC_<em>filename</em></code> class.</p></li>
-public class HelloCompute extends Activity {
- private Bitmap mBitmapIn;
- private Bitmap mBitmapOut;
+<li><strong>Copy data out of {@link android.renderscript.Allocation} objects.</strong> In order to
+access data from an {@link android.renderscript.Allocation} from Java code, that data must be copied
+back to Java buffers using one of the <code>copy</code> methods in {@link
+android.renderscript.Allocation}. These functions will synchronize with asynchronous kernel and
+function launches as necessary.</li>
- private RenderScript mRS;
- private Allocation mInAllocation;
- private Allocation mOutAllocation;
- private ScriptC_mono mScript;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- mBitmapIn = loadBitmap(R.drawable.data);
- mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
- mBitmapIn.getConfig());
-
- ImageView in = (ImageView) findViewById(R.id.displayin);
- in.setImageBitmap(mBitmapIn);
-
- ImageView out = (ImageView) findViewById(R.id.displayout);
- out.setImageBitmap(mBitmapOut);
-
- createScript();
- }
- private void createScript() {
- mRS = RenderScript.create(this);
- mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
- Allocation.MipmapControl.MIPMAP_NONE,
- Allocation.USAGE_SCRIPT);
- mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
- mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);
- mScript.forEach_root(mInAllocation, mOutAllocation);
- mOutAllocation.copyTo(mBitmapOut);
- }
-
- private Bitmap loadBitmap(int resource) {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- return BitmapFactory.decodeResource(getResources(), resource, options);
- }
-}
-</pre>
-
-<p>To call Renderscript from another Renderscript file:</p>
-<ol>
- <li>Allocate memory that is needed by the Renderscript in your Android framework code.
- You need an input and output {@link android.renderscript.Allocation} for Android 3.2 (API level
- 13) platform versions and older. The Android 4.0 (API level 14) platform version requires only
- one or both {@link android.renderscript.Allocation}s.</li>
-
- <li>Call <code>rsForEach()</code>, passing in the allocations and any optional user-defined data.
- The output allocation will contain the output of the Renderscript.</li>
-</ol>
-
-<pre>
-rs_script script;
-rs_allocation in_allocation;
-rs_allocation out_allocation;
-UserData_t data;
-...
-rsForEach(script, in_allocation, out_allocation, &data, sizeof(data));
-</pre>
-</p>
-<p>In this example, assume that the script and memory allocations have already been
-allocated and bound at the Android framework level and that <code>UserData_t</code> is a struct
-declared previously. Passing a pointer to a struct and the size of the struct to <code>rsForEach</code>
-is optional, but useful if your Renderscript requires additional information other than
-the necessary memory allocations.</p>
-
-
-<h4>Script groups</h4>
-
-<p>You can group Renderscript scripts together and execute them all with a single call as though
-they were part of a single script. This allows Renderscript to optimize execution of the scripts
-in ways that it could not do if the scripts were executed individually.</p>
-
-<p>To build a script groupm, use the {@link android.renderscript.ScriptGroup.Builder} class to create a {@link android.renderscript.ScriptGroup}
-defining the operations. At execution time, Renderscript optimizes the run order and the connections between these
-operations for best performance.
-
-<p class="note"><strong>Important:</strong> The script group must be a direct acyclic graph for this feature to work.</p>
+<li><strong>Tear down the RenderScript context.</strong> The RenderScript context can be destroyed
+with {@link android.renderscript.RenderScript#destroy} or by allowing the RenderScript context
+object to be garbage collected. This will cause any further use of any object belonging to that
+context to throw an exception.</li> </ol>
\ No newline at end of file
diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd
index b5c53ff..d23ba69 100644
--- a/docs/html/guide/topics/renderscript/index.jd
+++ b/docs/html/guide/topics/renderscript/index.jd
@@ -1,6 +1,6 @@
page.title=Computation
page.landing=true
-page.landing.intro=Renderscript provides a platform-independent computation engine that operates at the native level. Use it to accelerate your apps that require extensive computational horsepower.
+page.landing.intro=RenderScript provides a platform-independent computation engine that operates at the native level. Use it to accelerate your apps that require extensive computational horsepower.
page.landing.image=
@jd:body
@@ -12,16 +12,16 @@
<a
href="http://android-developers.blogspot.com/2013/01/evolution-of-renderscript-performance.html">
- <h4>Evolution of Renderscript Performance</h4>
- <p>It’s been a year since the last blog post on Renderscript, and with the release
+ <h4>Evolution of RenderScript Performance</h4>
+ <p>It’s been a year since the last blog post on RenderScript, and with the release
of Android 4.2, it’s a good time to talk about the performance work that we’ve done
since then. One of the major goals of this past year was to improve the performance
- of common image-processing operations with Renderscript.</p> </a>
+ of common image-processing operations with RenderScript.</p> </a>
<a
href="http://android-developers.blogspot.com/2012/01/levels-in-renderscript.html">
- <h4>Levels in Renderscript</h4>
- <p>For ICS, Renderscript (RS) has been updated with several new features to simplify
+ <h4>Levels in RenderScript</h4>
+ <p>For ICS, RenderScript (RS) has been updated with several new features to simplify
adding compute acceleration to your application. RS is interesting for compute
acceleration when you have large buffers of data on which you need to do significant
processing. In this example we will look at applying a levels/saturation operation
@@ -30,11 +30,11 @@
<a
href="http://android-developers.blogspot.com/2011/03/renderscript.html">
- <h4>Renderscript Part 2</h4>
- <p>In Introducing Renderscript I gave a brief overview of this technology.
- In this post I’ll look at "compute" in more detail. In Renderscript we use
+ <h4>RenderScript Part 2</h4>
+ <p>In Introducing RenderScript I gave a brief overview of this technology.
+ In this post I’ll look at "compute" in more detail. In RenderScript we use
"compute" to mean offloading of data processing from Dalvik code to
- Renderscript code which may run on the same or different processor(s).</p>
+ RenderScript code which may run on the same or different processor(s).</p>
</a>
</div>
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 480fe65..55c8dc42 100644
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -480,4 +480,4 @@
<h2 id="checklist">Localization Checklist</h2>
-<p>For an overview of the process of localizing an Android application, see the <a href="{@docRoot}distribute/googleplay/publish/localization.html">Localization Checklist</a>.</p>
+<p>For an overview of the process of localizing an Android application, see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a>.</p>
diff --git a/docs/html/images/home/io-videos-2013.png b/docs/html/images/home/io-videos-2013.png
new file mode 100644
index 0000000..8655e8f
--- /dev/null
+++ b/docs/html/images/home/io-videos-2013.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 0799802..af271ee 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -13,21 +13,25 @@
<div class="frame">
<ul>
<li class="item carousel-home">
- <div class="content-left col-10">
- <a href="https://developers.google.com/live/android/browse">
- <img src="{@docRoot}images/home/io-gdl-2013.png" style="margin:60px 0 0">
- </a>
+ <div class="content-left col-11" style="padding-top:10px;">
+ <a href="{@docRoot}channels/io2013.html">
+ <img src="{@docRoot}images/home/io-videos-2013.png" style="margin:60px 0 0;
+ box-shadow: 3px 10px 18px 1px #999;">
+ </a>
</div>
- <div class="content-right col-5">
+ <div class="content-right col-4">
<h1>Watch the Android talks from Google I/O</h1>
<p>If you weren't able to attend Google I/O in person or couldn't make it
to all the talks, you can catch up on the action
with all the recordings, brought to you by
<a href="http://developers.google.com/live">Google Developers Live</a>.</p>
- <p><a href="https://developers.google.com/live/android/browse" class="button"
+ <p><a href="{@docRoot}channels/io2013.html" class="button"
>See the Android talks</a></p>
</div>
</li>
+
+
+
<li class="item carousel-home">
<div class="content-left col-11" style="padding-top:65px;">
<script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
@@ -38,7 +42,7 @@
<script type="text/javascript">
var params = { allowScriptAccess: "always" };
var atts = { id: "ytapiplayer" };
- swfobject.embedSWF("//www.youtube.com/v/RRelFvc6Czo?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
+ swfobject.embedSWF("//www.youtube.com/v/O8i4HUw7JYA?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
"ytapiplayer", "600", "338", "8", null, null, params, atts);
// Callback used to pause/resume carousel based on video state
@@ -67,9 +71,8 @@
</div>
</div>
<div class="content-right col-4">
- <h1 style="white-space:nowrap;line-height:1em;">Developer Story: Smule</h1>
- <p>The creators of AutoRap, Magic Piano, and Songify talk about launching on
- Android and the explosive global growth they’ve seen on Google Play.</p>
+ <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />redBus.in</h1>
+ <p>Bangalore-based developers redBus.in talk about how Android is helping them deliver a superior booking and travel experience to millions of daily bus riders in India.</p>
</div>
</li>
<li class="item carousel-home">
diff --git a/docs/html/reference/com/google/android/gcm/GCMBaseIntentService.html b/docs/html/reference/com/google/android/gcm/GCMBaseIntentService.html
index b230b88..ad50a35 100644
--- a/docs/html/reference/com/google/android/gcm/GCMBaseIntentService.html
+++ b/docs/html/reference/com/google/android/gcm/GCMBaseIntentService.html
@@ -838,6 +838,9 @@
<h2>Class Overview</h2>
+<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;"><strong>DEPRECATED.</strong> Please use the <a href=
+"http://developer.android.com/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"><code>GoogleCloudMessaging</code></a> API instead.</div>
+
<p itemprop="articleBody">Skeleton for application-specific <code><a href="/reference/android/app/IntentService.html">IntentService</a></code>s responsible for
handling communication from Google Cloud Messaging service.
<p>
diff --git a/docs/html/reference/com/google/android/gcm/GCMBroadcastReceiver.html b/docs/html/reference/com/google/android/gcm/GCMBroadcastReceiver.html
index 91c0994..ea36df4 100644
--- a/docs/html/reference/com/google/android/gcm/GCMBroadcastReceiver.html
+++ b/docs/html/reference/com/google/android/gcm/GCMBroadcastReceiver.html
@@ -737,6 +737,10 @@
<h2>Class Overview</h2>
+
+<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;"><strong>DEPRECATED.</strong> Please use the <a href=
+"http://developer.android.com/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"><code>GoogleCloudMessaging</code></a> API instead.</div>
+
<p itemprop="articleBody"><code><a href="/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a></code> that receives GCM messages and delivers them to
an application-specific <code><a href="/reference/com/google/android/gcm/GCMBaseIntentService.html">GCMBaseIntentService</a></code> subclass.
<p>
diff --git a/docs/html/reference/com/google/android/gcm/GCMConstants.html b/docs/html/reference/com/google/android/gcm/GCMConstants.html
index cb260e0..8b782b6 100644
--- a/docs/html/reference/com/google/android/gcm/GCMConstants.html
+++ b/docs/html/reference/com/google/android/gcm/GCMConstants.html
@@ -710,6 +710,8 @@
<h2>Class Overview</h2>
+<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;"><strong>DEPRECATED.</strong> Please use the <a href=
+"http://developer.android.com/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"><code>GoogleCloudMessaging</code></a> API instead.</div>
<p itemprop="articleBody">Constants used by the GCM library.
</p>
diff --git a/docs/html/reference/com/google/android/gcm/GCMRegistrar.html b/docs/html/reference/com/google/android/gcm/GCMRegistrar.html
index 545abe2..21a990f 100644
--- a/docs/html/reference/com/google/android/gcm/GCMRegistrar.html
+++ b/docs/html/reference/com/google/android/gcm/GCMRegistrar.html
@@ -713,6 +713,10 @@
<h2>Class Overview</h2>
+
+<div style="background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;"><strong>DEPRECATED.</strong> Please use the <a href=
+"http://developer.android.com/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"><code>GoogleCloudMessaging</code></a> API instead.</div>
+
<p itemprop="articleBody">Utilities for device registration.
<p>
<strong>Note:</strong> this class uses a private <code><a href="/reference/android/content/SharedPreferences.html">SharedPreferences</a></code>
diff --git a/docs/html/reference/com/google/android/gcm/package-summary.html b/docs/html/reference/com/google/android/gcm/package-summary.html
index d2b05e6..6c8a993 100644
--- a/docs/html/reference/com/google/android/gcm/package-summary.html
+++ b/docs/html/reference/com/google/android/gcm/package-summary.html
@@ -642,21 +642,19 @@
<table class="jd-sumtable-expando">
<tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="/reference/com/google/android/gcm/GCMBaseIntentService.html">GCMBaseIntentService</a></td>
- <td class="jd-descrcol" width="100%">Skeleton for application-specific <code><a href="/reference/android/app/IntentService.html">IntentService</a></code>s responsible for
- handling communication from Google Cloud Messaging service. </td>
+ <td class="jd-descrcol" width="100%">DEPRECATED. </td>
</tr>
<tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="/reference/com/google/android/gcm/GCMBroadcastReceiver.html">GCMBroadcastReceiver</a></td>
- <td class="jd-descrcol" width="100%"><code><a href="/reference/android/content/BroadcastReceiver.html">BroadcastReceiver</a></code> that receives GCM messages and delivers them to
- an application-specific <code><a href="/reference/com/google/android/gcm/GCMBaseIntentService.html">GCMBaseIntentService</a></code> subclass. </td>
+ <td class="jd-descrcol" width="100%">DEPRECATED. </td>
</tr>
<tr class="alt-color api apilevel-" >
<td class="jd-linkcol"><a href="/reference/com/google/android/gcm/GCMConstants.html">GCMConstants</a></td>
- <td class="jd-descrcol" width="100%">Constants used by the GCM library. </td>
+ <td class="jd-descrcol" width="100%">DEPRECATED. </td>
</tr>
<tr class=" api apilevel-" >
<td class="jd-linkcol"><a href="/reference/com/google/android/gcm/GCMRegistrar.html">GCMRegistrar</a></td>
- <td class="jd-descrcol" width="100%">Utilities for device registration. </td>
+ <td class="jd-descrcol" width="100%">DEPRECATED. </td>
</tr>
</table>
</div>
diff --git a/docs/html/reference/gcm-packages.html b/docs/html/reference/gcm-packages.html
index 8065be9..2b5dc2d 100644
--- a/docs/html/reference/gcm-packages.html
+++ b/docs/html/reference/gcm-packages.html
@@ -623,14 +623,15 @@
<tr class="alt-color api apilevel-" >
<td class="jd-linkcol">
<a href="/reference/com/google/android/gcm/package-summary.html">com.google.android.gcm</a></td>
- <td class="jd-descrcol" width="100%"></td>
+ <td class="jd-descrcol" width="100%"><strong>DEPRECATED.</strong> Please use the <a href=
+"http://developer.android.com/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html"><code>GoogleCloudMessaging</code></a> API instead of this client helper library. See <a href="http://developer.android.com/google/gcm/client.html">GCM Client</a> for more information.</td>
</tr>
<tr class=" api apilevel-" >
<td class="jd-linkcol">
<a href="/reference/com/google/android/gcm/server/package-summary.html">com.google.android.gcm.server</a></td>
- <td class="jd-descrcol" width="100%"></td>
+ <td class="jd-descrcol" width="100%">Helper library for GCM HTTP server operations. See <a href="http://developer.android.com/google/gcm/server.html">GCM Server</a> for more information.</td>
</tr>
diff --git a/docs/html/sdk/installing/migrate.jd b/docs/html/sdk/installing/migrate.jd
index d988a95..20a698b 100644
--- a/docs/html/sdk/installing/migrate.jd
+++ b/docs/html/sdk/installing/migrate.jd
@@ -15,26 +15,27 @@
<li>In Eclipse, select <strong>File > Export</strong>.</li>
<li>In the window that appears, open <strong>Android</strong> and select <strong>Generate Gradle
build files</strong>.</li>
-<li>Select the projects you want to export for Android Studio and click
+<li>Select the project you want to export for Android Studio and click
<strong>Finish</strong>.</li>
</ol>
-<p>Your selected projects remain in the same location but now contain a {@code build.gradle}
-file and are ready for Android Studio.</p>
+<p>Your selected project remains in the same location but now contains a {@code build.gradle}
+file and is ready for Android Studio.</p>
<h2 id="Export">Import into Android Studio</h2>
<ol>
- <li>In Android Studio, select <strong>File > Import Project</strong>.</li>
- <li>Locate a project you exported from Eclipse, select the project's root directory and
- click <strong>OK</strong>.</li>
- <li>Select <strong>Create project from existing sources</strong> and click
- <strong>Next</strong>.</li>
- <li>Follow the walk-through to complete the import process.</li>
+ <li>In Android Studio, close any projects currently open. You should see the
+ <strong>Welcome to Android Studio</strong> window.</li>
+ <li>Click <strong>Import Project</strong>.</li>
+ <li>Locate the project you exported from Eclipse, expand it, select the
+ <strong>build.gradle</strong> file and click <strong>OK</strong>.</li>
+ <li>In the following dialog, leave <strong>Use gradle wrapper</strong> selected and click
+ <strong>OK</strong>. (You do not need to specify the Gradle home.)</li>
</ol>
-<p>Now that your projects are imported to Android Studio,
+<p>Now that your project is imported to Android Studio,
read <a href="{@docRoot}sdk/installing/studio-tips.html">Tips and Tricks</a> for some
help getting started.</p>
diff --git a/docs/html/tools/devices/emulator.jd b/docs/html/tools/devices/emulator.jd
index fda233d..ea1549d 100644
--- a/docs/html/tools/devices/emulator.jd
+++ b/docs/html/tools/devices/emulator.jd
@@ -1,6 +1,4 @@
-page.title=Using the Android Emulator
-parent.title=Managing Virtual Devices
-parent.link=index.html
+page.title=Using the Emulator
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/tools/extras/support-library.jd b/docs/html/tools/extras/support-library.jd
index 9cc0361..60168f4 100644
--- a/docs/html/tools/extras/support-library.jd
+++ b/docs/html/tools/extras/support-library.jd
@@ -565,7 +565,7 @@
<li>Proceed to install the package.</li>
</ol>
-<p>When done, all files (including source code, samples, and the {@code .jar} files) are saved
+<p>When done, all files (including source code, samples, and the JAR files) are saved
into the <code><sdk>/extras/android/support/</code> directory. This directory contains
each of the different support libraries, such as the library for API level 4 and up and the library
for API level 13 and up, each named with the respective version (such as {@code v4/}).</p>
@@ -574,20 +574,57 @@
<h2 id="SettingUp">Setting Up a Project to Use a Library</h2>
<p>To add one of the libraries to your Android project:</p>
+<dl>
+ <dt>
+ Add the JAR file to your project.
+ </dt>
+ <dd>
+ Copy the JAR file for the library you want to use into your Android project. To do this:
+ <ul>
+ <li>
+ Create the directory {@code libs/} at the root of your project
+ (next to {@code src/}, {@code res/}, and so forth).
+ </li>
+ <li>
+ Locate the JAR file for the library you want to use and copy it into the
+ {@code libs/} directory.
+ <p>
+ For example, the library that supports API level 4 and up is located at
+ {@code <sdk>/extras/android/support/v4/android-support-v4.jar}.
+ </p>
+ </li>
+ </ul>
+ <p>
+ Your build system may expect to find the JAR file in a directory other than
+ {@code libs}. Read the documentation for your build system to learn where to put the
+ JAR file.
+ </p>
+ </dd>
+ <dt>
+ If necessary, add the {@code libs/} directory to your build path.
+ </dt>
+ <dd>
+ Read the documentation for your build system to learn how to add the JAR file to the
+ build path.
+ </dd>
+</dl>
+<p>
+ To confirm that you've added the JAR file to the correct directory and added it to the build
+ path:
+</p>
<ol>
- <li>In your Android project, create a directory named {@code libs} at the root of your
-project (next to {@code src/}, {@code res/}, etc.)</li>
- <li>Locate the JAR file for the library you want to use and copy it into the {@code
-libs/} directory.
- <p>For example, the library that supports API level 4 and up is located at {@code
-<sdk>/extras/android/support/v4/android-support-v4.jar}.</p>
- </li>
- <li>Add the JAR to your project build path.
- <p>In Eclipse, right-click the JAR file in the Package Explorer, select <strong>Build
-Path</strong> > <strong>Add to Build Path</strong>.</p>
- </li>
+ <li>
+ Edit one of your source files to add an {@code import} statement that imports a
+ class from the {@code android.support.*} package.
+ </li>
+ <li>
+ Build your app. The code should compile cleanly.
+ </li>
+ <li>
+ As a double-check, run your app. It should run correctly, without any runtime exceptions
+ indicating that the class in {@code android.support.*} can't be found.
+ </li>
</ol>
-
<p>Your application is now ready to use the library APIs. All the
provided APIs are available in the {@code android.support} package (for
example, {@code android.support.v4}).</p>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a63492e..6389880 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -53,7 +53,7 @@
<ul>
<li><a href="<?cs var:toroot ?>tools/devices/managing-avds.html"><span class="en">With AVD Manager</span></a></li>
<li><a href="<?cs var:toroot ?>tools/devices/managing-avds-cmdline.html"><span class="en">From the Command Line</span></a></li>
- <li><a href="<?cs var:toroot ?>tools/devices/emulator.html"><span class="en">Using the Android Emulator</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/devices/emulator.html"><span class="en">Using the Emulator</span></a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>tools/device.html"><span class="en">Using Hardware Devices</span></a></li>
diff --git a/docs/html/training/location/receive-location-updates.jd b/docs/html/training/location/receive-location-updates.jd
index eb4ffa3..e6e8c51 100644
--- a/docs/html/training/location/receive-location-updates.jd
+++ b/docs/html/training/location/receive-location-updates.jd
@@ -417,7 +417,7 @@
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL =
- MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN SECONDS;
+ MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
// A fast frequency ceiling in milliseconds
@@ -425,7 +425,7 @@
MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
...
// Define an object that holds accuracy and frequency parameters
- LocationResult mLocationRequest;
+ LocationRequest mLocationRequest;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -458,9 +458,11 @@
the request by calling
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#requestLocationUpdates(com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">requestLocationUpdates()</a></code>.
Since your client must be connected for your app to receive updates, you should
- connect the client and make the request in
+ connect the client in
{@link android.support.v4.app.FragmentActivity#onStart onStart()}. This ensures that you always
- have a valid, connected client while your app is visible.
+ have a valid, connected client while your app is visible. Since you need a connection before you
+ can request updates, make the update request in
+<code><a href="{@docRoot}reference/com/google/android/gms/common/GooglePlayServicesClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">ConnectionCallbacks.onConnected()</a></code>
</p>
<p>
Remember that the user may want to turn off location updates for various reasons. You should
@@ -536,6 +538,21 @@
}
}
...
+ /*
+ * Called by Location Services when the request to connect the
+ * client finishes successfully. At this point, you can
+ * request the current location or start periodic updates
+ */
+ @Override
+ public void onConnected(Bundle dataBundle) {
+ // Display the connection status
+ Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
+ // If already requested, start periodic updates
+ if (mUpdatesRequested) {
+ mLocationClient.requestLocationUpdates(mLocationRequest, this);
+ }
+ }
+ ...
}
</pre>
<p>
@@ -567,7 +584,12 @@
protected void onStop() {
// If the client is connected
if (mLocationClient.isConnected()) {
- stopPeriodicUpdates();
+ /*
+ * Remove location updates for a listener.
+ * The current Activity is the listener, so
+ * the argument is "this".
+ */
+ removeLocationUpdates(this);
}
/*
* After disconnect() is called, the client is
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 7c7cd01..bde978d 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -167,7 +167,7 @@
* @return The Drawable at the specified frame index
*/
public Drawable getFrame(int index) {
- return mAnimationState.getChildren()[index];
+ return mAnimationState.getChild(index);
}
/**
@@ -322,7 +322,7 @@
mDurations = orig.mDurations;
mOneShot = orig.mOneShot;
} else {
- mDurations = new int[getChildren().length];
+ mDurations = new int[getCapacity()];
mOneShot = true;
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 6d236d9..c8fce9e 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -869,10 +869,6 @@
drawable = new StateListDrawable();
} else if (name.equals("level-list")) {
drawable = new LevelListDrawable();
- /* Probably not doing this.
- } else if (name.equals("mipmap")) {
- drawable = new MipmapDrawable();
- */
} else if (name.equals("layer-list")) {
drawable = new LayerDrawable();
} else if (name.equals("transition")) {
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 762e27d..e75ec75 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -250,18 +250,21 @@
return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
}
+ @Override
public void invalidateDrawable(Drawable who) {
if (who == mCurrDrawable && getCallback() != null) {
getCallback().invalidateDrawable(this);
}
}
+ @Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
if (who == mCurrDrawable && getCallback() != null) {
getCallback().scheduleDrawable(this, what, when);
}
}
+ @Override
public void unscheduleDrawable(Drawable who, Runnable what) {
if (who == mCurrDrawable && getCallback() != null) {
getCallback().unscheduleDrawable(this, what);
@@ -415,11 +418,7 @@
@Override
public Drawable mutate() {
if (!mMutated && super.mutate() == this) {
- final int N = mDrawableContainerState.getChildCount();
- final Drawable[] drawables = mDrawableContainerState.getChildren();
- for (int i = 0; i < N; i++) {
- if (drawables[i] != null) drawables[i].mutate();
- }
+ mDrawableContainerState.mutate();
mMutated = true;
}
return this;
@@ -544,14 +543,33 @@
return pos;
}
+ final int getCapacity() {
+ return mDrawables.length;
+ }
+
public final int getChildCount() {
return mNumChildren;
}
+ /*
+ * @deprecated Use {@link #getChild} instead.
+ */
public final Drawable[] getChildren() {
return mDrawables;
}
+ public final Drawable getChild(int index) {
+ return mDrawables[index];
+ }
+
+ final void mutate() {
+ final int N = getChildCount();
+ final Drawable[] drawables = mDrawables;
+ for (int i = 0; i < N; i++) {
+ if (drawables[i] != null) drawables[i].mutate();
+ }
+ }
+
/** A boolean value indicating whether to use the maximum padding value of
* all frames in the set (false), or to use the padding value of the frame
* being shown (true). Default value is false.
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index 21be983..872fdce 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -164,8 +164,8 @@
mLows = orig.mLows;
mHighs = orig.mHighs;
} else {
- mLows = new int[getChildren().length];
- mHighs = new int[getChildren().length];
+ mLows = new int[getCapacity()];
+ mHighs = new int[getCapacity()];
}
}
diff --git a/graphics/java/android/graphics/drawable/MipmapDrawable.java b/graphics/java/android/graphics/drawable/MipmapDrawable.java
deleted file mode 100644
index cd39719..0000000
--- a/graphics/java/android/graphics/drawable/MipmapDrawable.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-
-import java.io.IOException;
-
-/**
- * @hide -- we are probably moving to do MipMaps in another way (more integrated
- * with the resource system).
- *
- * A resource that manages a number of alternate Drawables, and which actually draws the one which
- * size matches the most closely the drawing bounds. Providing several pre-scaled version of the
- * drawable helps minimizing the aliasing artifacts that can be introduced by the scaling.
- *
- * <p>
- * Use {@link #addDrawable(Drawable)} to define the different Drawables that will represent the
- * mipmap levels of this MipmapDrawable. The mipmap Drawable that will actually be used when this
- * MipmapDrawable is drawn is the one which has the smallest intrinsic height greater or equal than
- * the bounds' height. This selection ensures that the best available mipmap level is scaled down to
- * draw this MipmapDrawable.
- * </p>
- *
- * If the bounds' height is larger than the largest mipmap, the largest mipmap will be scaled up.
- * Note that Drawables without intrinsic height (i.e. with a negative value, such as Color) will
- * only be used if no other mipmap Drawable are provided. The Drawables' intrinsic heights should
- * not be changed after the Drawable has been added to this MipmapDrawable.
- *
- * <p>
- * The different mipmaps' parameters (opacity, padding, color filter, gravity...) should typically
- * be similar to ensure a continuous visual appearance when the MipmapDrawable is scaled. The aspect
- * ratio of the different mipmaps should especially be equal.
- * </p>
- *
- * A typical example use of a MipmapDrawable would be for an image which is intended to be scaled at
- * various sizes, and for which one wants to provide pre-scaled versions to precisely control its
- * appearance.
- *
- * <p>
- * The intrinsic size of a MipmapDrawable are inferred from those of the largest mipmap (in terms of
- * {@link Drawable#getIntrinsicHeight()}). On the opposite, its minimum
- * size is defined by the smallest provided mipmap.
- * </p>
-
- * It can be defined in an XML file with the <code><mipmap></code> element.
- * Each mipmap Drawable is defined in a nested <code><item></code>. For example:
- * <pre>
- * <mipmap xmlns:android="http://schemas.android.com/apk/res/android">
- * <item android:drawable="@drawable/my_image_8" />
- * <item android:drawable="@drawable/my_image_32" />
- * <item android:drawable="@drawable/my_image_128" />
- * </mipmap>
- *</pre>
- * <p>
- * With this XML saved into the res/drawable/ folder of the project, it can be referenced as
- * the drawable for an {@link android.widget.ImageView}. Assuming that the heights of the provided
- * drawables are respectively 8, 32 and 128 pixels, the first one will be scaled down when the
- * bounds' height is lower or equal than 8 pixels. The second drawable will then be used up to a
- * height of 32 pixels and the largest drawable will be used for greater heights.
- * </p>
- * @attr ref android.R.styleable#MipmapDrawableItem_drawable
- */
-public class MipmapDrawable extends DrawableContainer {
- private final MipmapContainerState mMipmapContainerState;
- private boolean mMutated;
-
- public MipmapDrawable() {
- this(null, null);
- }
-
- /**
- * Adds a Drawable to the list of available mipmap Drawables. The Drawable actually used when
- * this MipmapDrawable is drawn is determined from its bounds.
- *
- * This method has no effect if drawable is null.
- *
- * @param drawable The Drawable that will be added to list of available mipmap Drawables.
- */
-
- public void addDrawable(Drawable drawable) {
- if (drawable != null) {
- mMipmapContainerState.addDrawable(drawable);
- onDrawableAdded();
- }
- }
-
- private void onDrawableAdded() {
- // selectDrawable assumes that the container content does not change.
- // When a Drawable is added, the same index can correspond to a new Drawable, and since
- // selectDrawable has a fast exit case when oldIndex==newIndex, the new drawable could end
- // up not being used in place of the previous one if they happen to share the same index.
- // This make sure the new computed index can actually replace the previous one.
- selectDrawable(-1);
- onBoundsChange(getBounds());
- }
-
- // overrides from Drawable
-
- @Override
- protected void onBoundsChange(Rect bounds) {
- final int index = mMipmapContainerState.indexForBounds(bounds);
-
- // Will call invalidateSelf() if needed
- selectDrawable(index);
-
- super.onBoundsChange(bounds);
- }
-
- @Override
- public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
- throws XmlPullParserException, IOException {
-
- super.inflate(r, parser, attrs);
-
- int type;
-
- final int innerDepth = parser.getDepth() + 1;
- int depth;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && ((depth = parser.getDepth()) >= innerDepth
- || type != XmlPullParser.END_TAG)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- if (depth > innerDepth || !parser.getName().equals("item")) {
- continue;
- }
-
- TypedArray a = r.obtainAttributes(attrs,
- com.android.internal.R.styleable.MipmapDrawableItem);
-
- int drawableRes = a.getResourceId(
- com.android.internal.R.styleable.MipmapDrawableItem_drawable, 0);
-
- a.recycle();
-
- Drawable dr;
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes);
- } else {
- while ((type = parser.next()) == XmlPullParser.TEXT) {
- }
- if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException(
- parser.getPositionDescription()
- + ": <item> tag requires a 'drawable' attribute or "
- + "child tag defining a drawable");
- }
- dr = Drawable.createFromXmlInner(r, parser, attrs);
- }
-
- mMipmapContainerState.addDrawable(dr);
- }
-
- onDrawableAdded();
- }
-
- @Override
- public Drawable mutate() {
- if (!mMutated && super.mutate() == this) {
- mMipmapContainerState.mMipmapHeights = mMipmapContainerState.mMipmapHeights.clone();
- mMutated = true;
- }
- return this;
- }
-
- private final static class MipmapContainerState extends DrawableContainerState {
- private int[] mMipmapHeights;
-
- MipmapContainerState(MipmapContainerState orig, MipmapDrawable owner, Resources res) {
- super(orig, owner, res);
-
- if (orig != null) {
- mMipmapHeights = orig.mMipmapHeights;
- } else {
- mMipmapHeights = new int[getChildren().length];
- }
-
- // Change the default value
- setConstantSize(true);
- }
-
- /**
- * Returns the index of the child mipmap drawable that will best fit the provided bounds.
- * This index is determined by comparing bounds' height and children intrinsic heights.
- * The returned mipmap index is the smallest mipmap which height is greater or equal than
- * the bounds' height. If the bounds' height is larger than the largest mipmap, the largest
- * mipmap index is returned.
- *
- * @param bounds The bounds of the MipMapDrawable.
- * @return The index of the child Drawable that will best fit these bounds, or -1 if there
- * are no children mipmaps.
- */
- public int indexForBounds(Rect bounds) {
- final int boundsHeight = bounds.height();
- final int N = getChildCount();
- for (int i = 0; i < N; i++) {
- if (boundsHeight <= mMipmapHeights[i]) {
- return i;
- }
- }
-
- // No mipmap larger than bounds found. Use largest one which will be scaled up.
- if (N > 0) {
- return N - 1;
- }
- // No Drawable mipmap at all
- return -1;
- }
-
- /**
- * Adds a Drawable to the list of available mipmap Drawables. This list can be retrieved
- * using {@link DrawableContainer.DrawableContainerState#getChildren()} and this method
- * ensures that it is always sorted by increasing {@link Drawable#getIntrinsicHeight()}.
- *
- * @param drawable The Drawable that will be added to children list
- */
- public void addDrawable(Drawable drawable) {
- // Insert drawable in last position, correctly resetting cached values and
- // especially mComputedConstantSize
- int pos = addChild(drawable);
-
- // Bubble sort the last drawable to restore the sort by intrinsic height
- final int drawableHeight = drawable.getIntrinsicHeight();
-
- while (pos > 0) {
- final Drawable previousDrawable = mDrawables[pos-1];
- final int previousIntrinsicHeight = previousDrawable.getIntrinsicHeight();
-
- if (drawableHeight < previousIntrinsicHeight) {
- mDrawables[pos] = previousDrawable;
- mMipmapHeights[pos] = previousIntrinsicHeight;
-
- mDrawables[pos-1] = drawable;
- mMipmapHeights[pos-1] = drawableHeight;
- pos--;
- } else {
- break;
- }
- }
- }
-
- /**
- * Intrinsic sizes are those of the largest available mipmap.
- * Minimum sizes are those of the smallest available mipmap.
- */
- @Override
- protected void computeConstantSize() {
- final int N = getChildCount();
- if (N > 0) {
- final Drawable smallestDrawable = mDrawables[0];
- mConstantMinimumWidth = smallestDrawable.getMinimumWidth();
- mConstantMinimumHeight = smallestDrawable.getMinimumHeight();
-
- final Drawable largestDrawable = mDrawables[N-1];
- mConstantWidth = largestDrawable.getIntrinsicWidth();
- mConstantHeight = largestDrawable.getIntrinsicHeight();
- } else {
- mConstantWidth = mConstantHeight = -1;
- mConstantMinimumWidth = mConstantMinimumHeight = 0;
- }
- mComputedConstantSize = true;
- }
-
- @Override
- public Drawable newDrawable() {
- return new MipmapDrawable(this, null);
- }
-
- @Override
- public Drawable newDrawable(Resources res) {
- return new MipmapDrawable(this, res);
- }
-
- @Override
- public void growArray(int oldSize, int newSize) {
- super.growArray(oldSize, newSize);
- int[] newInts = new int[newSize];
- System.arraycopy(mMipmapHeights, 0, newInts, 0, oldSize);
- mMipmapHeights = newInts;
- }
- }
-
- private MipmapDrawable(MipmapContainerState state, Resources res) {
- MipmapContainerState as = new MipmapContainerState(state, this, res);
- mMipmapContainerState = as;
- setConstantState(as);
- onDrawableAdded();
- }
-}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index f8f3ac9..5ecd296 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -228,7 +228,7 @@
* @see #getStateSet(int)
*/
public Drawable getStateDrawable(int index) {
- return mStateListState.getChildren()[index];
+ return mStateListState.getChild(index);
}
/**
@@ -278,9 +278,9 @@
super(orig, owner, res);
if (orig != null) {
- mStateSets = orig.mStateSets;
+ mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length);
} else {
- mStateSets = new int[getChildren().length][];
+ mStateSets = new int[getCapacity()][];
}
}
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 3d4d40a..362b586 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -31,46 +31,29 @@
import android.os.Trace;
/**
- * <p>
- * Memory allocation class for renderscript. An allocation combines a
- * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
- * This implies that all memory in Renderscript is typed.
- * </p>
+ * <p> This class provides the primary method through which data is passed to
+ * and from RenderScript kernels. An Allocation provides the backing store for
+ * a given {@link android.renderscript.Type}. </p>
*
- * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
- * synchronized and it's possible for allocations to exist in multiple memory spaces
- * concurrently. Currently those spaces are:</p>
- * <ul>
- * <li>Script: accessable by RS scripts.</li>
- * <li>Graphics Texture: accessable as a graphics texture.</li>
- * <li>Graphics Vertex: accessable as graphical vertex data.</li>
- * <li>Graphics Constants: Accessable as constants in user shaders</li>
- * </ul>
- * </p>
- * <p>
- * For example, when creating a allocation for a texture, the user can
- * specify its memory spaces as both script and textures. This means that it can both
- * be used as script binding and as a GPU texture for rendering. To maintain
- * synchronization if a script modifies an allocation used by other targets it must
- * call a synchronizing function to push the updates to the memory, otherwise the results
- * are undefined.
- * </p>
- * <p>By default, Android system side updates are always applied to the script accessable
- * memory. If this is not present, they are then applied to the various HW
- * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()}
- * call is necessary after the script data is updated to
- * keep the other memory spaces in sync.</p>
+ * <p>An Allocation also contains a set of usage flags that denote how the
+ * Allocation could be used. For example, an Allocation may have usage flags
+ * specifying that it can be used from a script as well as input to a {@link
+ * android.renderscript.Sampler}. A developer must synchronize across these
+ * different usages using {@link android.renderscript.Allocation#syncAll} in
+ * order to ensure that different users of the Allocation have a consistent view
+ * of memory. For example, in the case where an Allocation is used as the output
+ * of one kernel and as Sampler input in a later kernel, a developer must call
+ * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
+ * second kernel to ensure correctness.
*
- * <p>Allocation data is uploaded in one of two primary ways. For simple
- * arrays there are copyFrom() functions that take an array from the control code and
- * copy it to the slave memory store. Both type checked and unchecked copies are provided.
- * The unchecked variants exist to allow apps to copy over arrays of structures from a
- * control language that does not support structures.</p>
+ * <p>An Allocation can be populated with the {@link #copyFrom} routines. For
+ * more complex Element types, the {@link #copyFromUnchecked} methods can be
+ * used to copy from byte arrays or similar constructs.</p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
public class Allocation extends BaseObj {
@@ -98,97 +81,102 @@
new HashMap<Integer, Allocation>();
IoInputNotifier mBufferNotifier;
+ /**
+ * The usage of the Allocation. These signal to RenderScript where to place
+ * the Allocation in memory.
+ *
+ */
/**
- * The usage of the allocation. These signal to renderscript
- * where to place the allocation in memory.
- *
- * SCRIPT The allocation will be bound to and accessed by
- * scripts.
+ * The Allocation will be bound to and accessed by scripts.
*/
public static final int USAGE_SCRIPT = 0x0001;
/**
- * GRAPHICS_TEXTURE The allocation will be used as a texture
- * source by one or more graphics programs.
+ * The Allocation will be used as a texture source by one or more graphics
+ * programs.
*
*/
public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
/**
- * GRAPHICS_VERTEX The allocation will be used as a graphics
- * mesh.
+ * The Allocation will be used as a graphics mesh.
+ *
+ * This was deprecated in API level 16.
*
*/
public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
/**
- * GRAPHICS_CONSTANTS The allocation will be used as the source
- * of shader constants by one or more programs.
+ * The Allocation will be used as the source of shader constants by one or
+ * more programs.
+ *
+ * This was deprecated in API level 16.
*
*/
public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
/**
- * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
- * target for offscreen rendering
+ * The Allocation will be used as a target for offscreen rendering
+ *
+ * This was deprecated in API level 16.
*
*/
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
/**
- * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
- * consumer. This usage will cause the allocation to be created
- * read only.
+ * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+ * consumer. This usage will cause the Allocation to be created as
+ * read-only.
*
*/
public static final int USAGE_IO_INPUT = 0x0020;
/**
- * USAGE_IO_OUTPUT The allocation will be used as a
- * SurfaceTexture producer. The dimensions and format of the
- * SurfaceTexture will be forced to those of the allocation.
+ * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+ * producer. The dimensions and format of the {@link
+ * android.graphics.SurfaceTexture} will be forced to those of the
+ * Allocation.
*
*/
public static final int USAGE_IO_OUTPUT = 0x0040;
/**
- * USAGE_SHARED The allocation's backing store will be inherited
- * from another object (usually a Bitmap); calling appropriate
- * copy methods will be significantly faster than if the entire
- * allocation were copied every time.
+ * The Allocation's backing store will be inherited from another object
+ * (usually a {@link android.graphics.Bitmap}); copying to or from the
+ * original source Bitmap will cause a synchronization rather than a full
+ * copy. {@link #syncAll} may also be used to synchronize the Allocation
+ * and the source Bitmap.
*
- * This is set by default for allocations created with
- * CreateFromBitmap(RenderScript, Bitmap) in API version 18 and
- * higher.
+ * <p>This is set by default for allocations created with {@link
+ * #createFromBitmap} in API version 18 and higher.</p>
*
*/
public static final int USAGE_SHARED = 0x0080;
/**
- * Controls mipmap behavior when using the bitmap creation and
- * update functions.
+ * Controls mipmap behavior when using the bitmap creation and update
+ * functions.
*/
public enum MipmapControl {
/**
- * No mipmaps will be generated and the type generated from the
- * incoming bitmap will not contain additional LODs.
+ * No mipmaps will be generated and the type generated from the incoming
+ * bitmap will not contain additional LODs.
*/
MIPMAP_NONE(0),
/**
- * A Full mipmap chain will be created in script memory. The
- * type of the allocation will contain a full mipmap chain. On
- * upload to graphics the full chain will be transfered.
+ * A full mipmap chain will be created in script memory. The Type of
+ * the Allocation will contain a full mipmap chain. On upload, the full
+ * chain will be transferred.
*/
MIPMAP_FULL(1),
/**
- * The type of the allocation will be the same as MIPMAP_NONE.
- * It will not contain mipmaps. On upload to graphics the
- * graphics copy of the allocation data will contain a full
- * mipmap chain generated from the top level in script memory.
+ * The Type of the Allocation will be the same as MIPMAP_NONE. It will
+ * not contain mipmaps. On upload, the allocation data will contain a
+ * full mipmap chain generated from the top level in script memory.
*/
MIPMAP_ON_SYNC_TO_TEXTURE(2);
@@ -208,10 +196,10 @@
/**
- * Get the element of the type of the Allocation.
+ * Get the {@link android.renderscript.Element} of the {@link
+ * android.renderscript.Type} of the Allocation.
*
- * @return Element that describes the structure of data in the
- * allocation
+ * @return Element
*
*/
public Element getElement() {
@@ -221,8 +209,7 @@
/**
* Get the usage flags of the Allocation.
*
- * @return usage flags associated with the allocation. e.g.
- * script, texture, etc.
+ * @return usage this Allocation's set of the USAGE_* flags OR'd together
*
*/
public int getUsage() {
@@ -351,7 +338,7 @@
}
/**
- * Get the type of the Allocation.
+ * Get the {@link android.renderscript.Type} of the Allocation.
*
* @return Type
*
@@ -361,8 +348,8 @@
}
/**
- * Propagate changes from one usage of the allocation to the
- * remaining usages of the allocation.
+ * Propagate changes from one usage of the Allocation to the
+ * other usages of the Allocation.
*
*/
public void syncAll(int srcLocation) {
@@ -391,8 +378,10 @@
}
/**
- * Send a buffer to the output stream. The contents of the
- * Allocation will be undefined after this operation.
+ * Send a buffer to the output stream. The contents of the Allocation will
+ * be undefined after this operation. This operation is only valid if {@link
+ * #USAGE_IO_OUTPUT} is set on the Allocation.
+ *
*
*/
public void ioSend() {
@@ -415,7 +404,8 @@
}
/**
- * Receive the latest input into the Allocation.
+ * Receive the latest input into the Allocation. This operation
+ * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
*
*/
public void ioReceive() {
@@ -430,7 +420,7 @@
}
/**
- * Copy an array of RS objects to the allocation.
+ * Copy an array of RS objects to the Allocation.
*
* @param d Source array.
*/
@@ -506,9 +496,9 @@
}
/**
- * Copy an allocation from an array. This variant is not type
- * checked which allows an application to fill in structured
- * data from an array.
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
*
* @param d the source data array
*/
@@ -526,9 +516,9 @@
}
/**
- * Copy an allocation from an array. This variant is not type
- * checked which allows an application to fill in structured
- * data from an array.
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
*
* @param d the source data array
*/
@@ -546,9 +536,9 @@
}
/**
- * Copy an allocation from an array. This variant is not type
- * checked which allows an application to fill in structured
- * data from an array.
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
*
* @param d the source data array
*/
@@ -566,9 +556,9 @@
}
/**
- * Copy an allocation from an array. This variant is not type
- * checked which allows an application to fill in structured
- * data from an array.
+ * Copy into this Allocation from an array. This method does not guarantee
+ * that the Allocation is compatible with the input buffer; it copies memory
+ * without reinterpretation.
*
* @param d the source data array
*/
@@ -587,9 +577,9 @@
/**
- * Copy an allocation from an array. This variant is type
- * checked and will generate exceptions if the Allocation type
- * is not a 32 bit integer type.
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * android.renderscript.Element} is not a 32 bit integer type.
*
* @param d the source data array
*/
@@ -607,9 +597,9 @@
}
/**
- * Copy an allocation from an array. This variant is type
- * checked and will generate exceptions if the Allocation type
- * is not a 16 bit integer type.
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * android.renderscript.Element} is not a 16 bit integer type.
*
* @param d the source data array
*/
@@ -627,9 +617,9 @@
}
/**
- * Copy an allocation from an array. This variant is type
- * checked and will generate exceptions if the Allocation type
- * is not a 8 bit integer type.
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * android.renderscript.Element} is not an 8 bit integer type.
*
* @param d the source data array
*/
@@ -647,9 +637,9 @@
}
/**
- * Copy an allocation from an array. This variant is type
- * checked and will generate exceptions if the Allocation type
- * is not a 32 bit float type.
+ * Copy into this Allocation from an array. This variant is type checked
+ * and will generate exceptions if the Allocation's {@link
+ * android.renderscript.Element} is not a 32 bit float type.
*
* @param d the source data array
*/
@@ -667,8 +657,15 @@
}
/**
- * Copy an allocation from a bitmap. The height, width, and
- * format of the bitmap must match the existing allocation.
+ * Copy into an Allocation from a {@link android.graphics.Bitmap}. The
+ * height, width, and format of the bitmap must match the existing
+ * allocation.
+ *
+ * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
+ * android.graphics.Bitmap} used to create the Allocation with {@link
+ * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
+ * this will synchronize the Allocation with the latest data from the {@link
+ * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
*
* @param b the source bitmap
*/
@@ -689,7 +686,7 @@
}
/**
- * Copy an allocation from an allocation. The types of both allocations
+ * Copy an Allocation from an Allocation. The types of both allocations
* must be identical.
*
* @param a the source allocation
@@ -705,8 +702,8 @@
}
/**
- * This is only intended to be used by auto-generate code reflected from the
- * renderscript script files.
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files and should not be used by developers.
*
* @param xoff
* @param fp
@@ -725,8 +722,8 @@
}
/**
- * This is only intended to be used by auto-generate code reflected from the
- * renderscript script files.
+ * This is only intended to be used by auto-generated code reflected from
+ * the RenderScript script files.
*
* @param xoff
* @param component_number
@@ -772,23 +769,22 @@
}
/**
- * Generate a mipmap chain. Requires the type of the allocation
- * include mipmaps.
+ * Generate a mipmap chain. This is only valid if the Type of the Allocation
+ * includes mipmaps.
*
- * This function will generate a complete set of mipmaps from
- * the top level lod and place them into the script memoryspace.
+ * <p>This function will generate a complete set of mipmaps from the top
+ * level LOD and place them into the script memory space.</p>
*
- * If the allocation is also using other memory spaces a
- * followup sync will be required.
+ * <p>If the Allocation is also using other memory spaces, a call to {@link
+ * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
*/
public void generateMipmaps() {
mRS.nAllocationGenerateMipmaps(getID(mRS));
}
/**
- * Copy part of an allocation from an array. This variant is
- * not type checked which allows an application to fill in
- * structured data from an array.
+ * Copy an array into part of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -803,9 +799,8 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * not type checked which allows an application to fill in
- * structured data from an array.
+ * Copy an array into part of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -820,9 +815,8 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * not type checked which allows an application to fill in
- * structured data from an array.
+ * Copy an array into part of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -837,9 +831,8 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * not type checked which allows an application to fill in
- * structured data from an array.
+ * Copy an array into part of this Allocation. This method does not
+ * guarantee that the Allocation is compatible with the input buffer.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -854,9 +847,9 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * type checked and will generate exceptions if the Allocation
- * type is not a 32 bit integer type.
+ * Copy an array into part of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation type is not a 32 bit
+ * integer type.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -870,9 +863,9 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * type checked and will generate exceptions if the Allocation
- * type is not a 16 bit integer type.
+ * Copy an array into part of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation type is not a 16 bit
+ * integer type.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -886,9 +879,9 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * type checked and will generate exceptions if the Allocation
- * type is not a 8 bit integer type.
+ * Copy an array into part of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation type is not an 8 bit
+ * integer type.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -902,9 +895,9 @@
}
/**
- * Copy part of an allocation from an array. This variant is
- * type checked and will generate exceptions if the Allocation
- * type is not a 32 bit float type.
+ * Copy an array into part of this Allocation. This variant is type checked
+ * and will generate exceptions if the Allocation type is not a 32 bit float
+ * type.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -917,7 +910,7 @@
Trace.traceEnd(RenderScript.TRACE_TAG);
}
/**
- * Copy part of an allocation from another allocation.
+ * Copy part of an Allocation into this Allocation.
*
* @param off The offset of the first element to be copied.
* @param count The number of elements to be copied.
@@ -987,14 +980,14 @@
}
/**
- * Copy a rectangular region from the array into the allocation.
- * The incoming array is assumed to be tightly packed.
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed.
*
- * @param xoff X offset of the region to update
- * @param yoff Y offset of the region to update
- * @param w Width of the incoming region to update
- * @param h Height of the incoming region to update
- * @param data to be placed into the allocation
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
*/
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
@@ -1003,6 +996,16 @@
Trace.traceEnd(RenderScript.TRACE_TAG);
}
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
validateIsInt16();
@@ -1010,6 +1013,16 @@
Trace.traceEnd(RenderScript.TRACE_TAG);
}
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
validateIsInt32();
@@ -1017,6 +1030,16 @@
Trace.traceEnd(RenderScript.TRACE_TAG);
}
+ /**
+ * Copy from an array into a rectangular region in this Allocation. The
+ * array is assumed to be tightly packed.
+ *
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param data to be placed into the Allocation
+ */
public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
validateIsFloat32();
@@ -1025,16 +1048,16 @@
}
/**
- * Copy a rectangular region into the allocation from another
- * allocation.
+ * Copy a rectangular region from an Allocation into a rectangular region in
+ * this Allocation.
*
- * @param xoff X offset of the region to update.
- * @param yoff Y offset of the region to update.
- * @param w Width of the incoming region to update.
- * @param h Height of the incoming region to update.
- * @param data source allocation.
- * @param dataXoff X offset in data of the region to update.
- * @param dataYoff Y offset in data of the region to update.
+ * @param xoff X offset of the region in this Allocation
+ * @param yoff Y offset of the region in this Allocation
+ * @param w Width of the region to update.
+ * @param h Height of the region to update.
+ * @param data source Allocation.
+ * @param dataXoff X offset in source Allocation
+ * @param dataYoff Y offset in source Allocation
*/
public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
Allocation data, int dataXoff, int dataYoff) {
@@ -1049,13 +1072,13 @@
}
/**
- * Copy a bitmap into an allocation. The height and width of
- * the update will use the height and width of the incoming
- * bitmap.
+ * Copy a {@link android.graphics.Bitmap} into an Allocation. The height
+ * and width of the update will use the height and width of the {@link
+ * android.graphics.Bitmap}.
*
- * @param xoff X offset of the region to update
- * @param yoff Y offset of the region to update
- * @param data the bitmap to be copied
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param data the Bitmap to be copied
*/
public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
@@ -1138,14 +1161,14 @@
/**
* @hide
* Copy a rectangular region from the array into the allocation.
- * The incoming array is assumed to be tightly packed.
+ * The array is assumed to be tightly packed.
*
- * @param xoff X offset of the region to update
- * @param yoff Y offset of the region to update
- * @param zoff Z offset of the region to update
- * @param w Width of the incoming region to update
- * @param h Height of the incoming region to update
- * @param d Depth of the incoming region to update
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param zoff Z offset of the region to update in this Allocation
+ * @param w Width of the region to update
+ * @param h Height of the region to update
+ * @param d Depth of the region to update
* @param data to be placed into the allocation
*/
public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) {
@@ -1185,15 +1208,16 @@
* Copy a rectangular region into the allocation from another
* allocation.
*
- * @param xoff X offset of the region to update.
- * @param yoff Y offset of the region to update.
- * @param w Width of the incoming region to update.
- * @param h Height of the incoming region to update.
- * @param d Depth of the incoming region to update.
+ * @param xoff X offset of the region to update in this Allocation
+ * @param yoff Y offset of the region to update in this Allocation
+ * @param zoff Z offset of the region to update in this Allocation
+ * @param w Width of the region to update.
+ * @param h Height of the region to update.
+ * @param d Depth of the region to update.
* @param data source allocation.
- * @param dataXoff X offset in data of the region to update.
- * @param dataYoff Y offset in data of the region to update.
- * @param dataZoff Z offset in data of the region to update
+ * @param dataXoff X offset of the region in the source Allocation
+ * @param dataYoff Y offset of the region in the source Allocation
+ * @param dataZoff Z offset of the region in the source Allocation
*/
public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
Allocation data, int dataXoff, int dataYoff, int dataZoff) {
@@ -1206,8 +1230,8 @@
/**
- * Copy from the Allocation into a Bitmap. The bitmap must
- * match the dimensions of the Allocation.
+ * Copy from the Allocation into a {@link android.graphics.Bitmap}. The
+ * bitmap must match the dimensions of the Allocation.
*
* @param b The bitmap to be set from the Allocation.
*/
@@ -1221,9 +1245,9 @@
}
/**
- * Copy from the Allocation into a byte array. The array must
- * be at least as large as the Allocation. The allocation must
- * be of an 8 bit elemental type.
+ * Copy from the Allocation into a byte array. The array must be at least
+ * as large as the Allocation. The allocation must be of an 8 bit integer
+ * {@link android.renderscript.Element} type.
*
* @param d The array to be set from the Allocation.
*/
@@ -1236,9 +1260,9 @@
}
/**
- * Copy from the Allocation into a short array. The array must
- * be at least as large as the Allocation. The allocation must
- * be of an 16 bit elemental type.
+ * Copy from the Allocation into a short array. The array must be at least
+ * as large as the Allocation. The allocation must be of an 16 bit integer
+ * {@link android.renderscript.Element} type.
*
* @param d The array to be set from the Allocation.
*/
@@ -1251,9 +1275,9 @@
}
/**
- * Copy from the Allocation into a int array. The array must be
- * at least as large as the Allocation. The allocation must be
- * of an 32 bit elemental type.
+ * Copy from the Allocation into a int array. The array must be at least as
+ * large as the Allocation. The allocation must be of an 32 bit integer
+ * {@link android.renderscript.Element} type.
*
* @param d The array to be set from the Allocation.
*/
@@ -1266,9 +1290,9 @@
}
/**
- * Copy from the Allocation into a float array. The array must
- * be at least as large as the Allocation. The allocation must
- * be of an 32 bit float elemental type.
+ * Copy from the Allocation into a float array. The array must be at least
+ * as large as the Allocation. The allocation must be of an 32 bit float
+ * {@link android.renderscript.Element} type.
*
* @param d The array to be set from the Allocation.
*/
@@ -1281,20 +1305,19 @@
}
/**
- * Resize a 1D allocation. The contents of the allocation are
- * preserved. If new elements are allocated objects are created
- * with null contents and the new region is otherwise undefined.
+ * Resize a 1D allocation. The contents of the allocation are preserved.
+ * If new elements are allocated objects are created with null contents and
+ * the new region is otherwise undefined.
*
- * If the new region is smaller the references of any objects
- * outside the new region will be released.
+ * <p>If the new region is smaller the references of any objects outside the
+ * new region will be released.</p>
*
- * A new type will be created with the new dimension.
+ * <p>A new type will be created with the new dimension.</p>
*
* @param dimX The new size of the allocation.
*
- * @deprecated Renderscript objects should be immutable once
- * created. The replacement is to create a new allocation and copy the
- * contents.
+ * @deprecated RenderScript objects should be immutable once created. The
+ * replacement is to create a new allocation and copy the contents.
*/
public synchronized void resize(int dimX) {
if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
@@ -1318,11 +1341,13 @@
}
/**
+ * Creates a new Allocation with the given {@link
+ * android.renderscript.Type}, mipmap flag, and usage flags.
*
- * @param type renderscript type describing data layout
+ * @param type RenderScript type describing data layout
* @param mips specifies desired mipmap behaviour for the
* allocation
- * @param usage bit field specifying how the allocation is
+ * @param usage bit field specifying how the Allocation is
* utilized
*/
static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
@@ -1340,8 +1365,8 @@
}
/**
- * Creates a renderscript allocation with the size specified by
- * the type and no mipmaps generated by default
+ * Creates an Allocation with the size specified by the type and no mipmaps
+ * generated by default
*
* @param rs Context to which the allocation will belong.
* @param type renderscript type describing data layout
@@ -1355,12 +1380,11 @@
}
/**
- * Creates a renderscript allocation for use by the script with
- * the size specified by the type and no mipmaps generated by
- * default
+ * Creates an Allocation for use by scripts with a given {@link
+ * android.renderscript.Type} and no mipmaps
*
- * @param rs Context to which the allocation will belong.
- * @param type renderscript type describing data layout
+ * @param rs Context to which the Allocation will belong.
+ * @param type RenderScript Type describing data layout
*
* @return allocation
*/
@@ -1369,13 +1393,12 @@
}
/**
- * Creates a renderscript allocation with a specified number of
- * given elements
+ * Creates an Allocation with a specified number of given elements
*
- * @param rs Context to which the allocation will belong.
- * @param e describes what each element of an allocation is
- * @param count specifies the number of element in the allocation
- * @param usage bit field specifying how the allocation is
+ * @param rs Context to which the Allocation will belong.
+ * @param e Element to use in the Allocation
+ * @param count the number of Elements in the Allocation
+ * @param usage bit field specifying how the Allocation is
* utilized
*
* @return allocation
@@ -1397,12 +1420,11 @@
}
/**
- * Creates a renderscript allocation with a specified number of
- * given elements
+ * Creates an Allocation with a specified number of given elements
*
- * @param rs Context to which the allocation will belong.
- * @param e describes what each element of an allocation is
- * @param count specifies the number of element in the allocation
+ * @param rs Context to which the Allocation will belong.
+ * @param e Element to use in the Allocation
+ * @param count the number of Elements in the Allocation
*
* @return allocation
*/
@@ -1438,16 +1460,16 @@
}
/**
- * Creates a renderscript allocation from a bitmap
+ * Creates an Allocation from a {@link android.graphics.Bitmap}.
*
* @param rs Context to which the allocation will belong.
- * @param b bitmap source for the allocation data
+ * @param b Bitmap source for the allocation data
* @param mips specifies desired mipmap behaviour for the
* allocation
* @param usage bit field specifying how the allocation is
* utilized
*
- * @return renderscript allocation containing bitmap data
+ * @return Allocation containing bitmap data
*
*/
static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
@@ -1494,9 +1516,9 @@
}
/**
- * For allocations used with io operations, returns the handle
- * onto a raw buffer that is being managed by the screen
- * compositor.
+ * Returns the handle to a raw buffer that is being managed by the screen
+ * compositor. This operation is only valid for Allocations with {@link
+ * #USAGE_IO_INPUT}.
*
* @return Surface object associated with allocation
*
@@ -1516,7 +1538,8 @@
}
/**
- * Associate a surface for io output with this allocation
+ * Associate a {@link android.view.Surface} with this Allocation. This
+ * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
*
* @param sur Surface to associate with allocation
*/
@@ -1530,16 +1553,17 @@
}
/**
- * Creates a RenderScript allocation from a bitmap.
+ * Creates an Allocation from a {@link android.graphics.Bitmap}.
*
- * With target API version 18 or greater, this allocation will be
- * created with USAGE_SHARED. With target API version 17 or lower,
- * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
+ * <p>With target API version 18 or greater, this Allocation will be created
+ * with {@link #USAGE_SHARED}, {@link #USAGE_SCRIPT}, and {@link
+ * #USAGE_GRAPHICS_TEXTURE}. With target API version 17 or lower, this
+ * Allocation will be created with {@link #USAGE_GRAPHICS_TEXTURE}.</p>
*
* @param rs Context to which the allocation will belong.
* @param b bitmap source for the allocation data
*
- * @return renderscript allocation containing bitmap data
+ * @return Allocation containing bitmap data
*
*/
static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
@@ -1552,12 +1576,13 @@
}
/**
- * Creates a cubemap allocation from a bitmap containing the
- * horizontal list of cube faces. Each individual face must be
- * the same size and power of 2
+ * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
+ * containing the horizontal list of cube faces. Each face must be a square,
+ * have the same size as all other faces, and have a width that is a power
+ * of 2.
*
* @param rs Context to which the allocation will belong.
- * @param b bitmap with cubemap faces layed out in the following
+ * @param b Bitmap with cubemap faces layed out in the following
* format: right, left, top, bottom, front, back
* @param mips specifies desired mipmap behaviour for the cubemap
* @param usage bit field specifying how the cubemap is utilized
@@ -1600,10 +1625,10 @@
}
/**
- * Creates a non-mipmapped cubemap allocation for use as a
- * graphics texture from a bitmap containing the horizontal list
- * of cube faces. Each individual face must be the same size and
- * power of 2
+ * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
+ * from a {@link android.graphics.Bitmap} containing the horizontal list of
+ * cube faces. Each face must be a square, have the same size as all other
+ * faces, and have a width that is a power of 2.
*
* @param rs Context to which the allocation will belong.
* @param b bitmap with cubemap faces layed out in the following
@@ -1619,9 +1644,9 @@
}
/**
- * Creates a cubemap allocation from 6 bitmaps containing
- * the cube faces. All the faces must be the same size and
- * power of 2
+ * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
+ * objects containing the cube faces. Each face must be a square, have the
+ * same size as all other faces, and have a width that is a power of 2.
*
* @param rs Context to which the allocation will belong.
* @param xpos cubemap face in the positive x direction
@@ -1686,10 +1711,10 @@
}
/**
- * Creates a non-mipmapped cubemap allocation for use as a
- * graphics texture from 6 bitmaps containing
- * the cube faces. All the faces must be the same size and
- * power of 2
+ * Creates a non-mipmapped cubemap Allocation for use as a sampler input
+ * from 6 {@link android.graphics.Bitmap} objects containing the cube
+ * faces. Each face must be a square, have the same size as all other faces,
+ * and have a width that is a power of 2.
*
* @param rs Context to which the allocation will belong.
* @param xpos cubemap face in the positive x direction
@@ -1715,8 +1740,8 @@
}
/**
- * Creates a renderscript allocation from the bitmap referenced
- * by resource id
+ * Creates an Allocation from the Bitmap referenced
+ * by resource ID.
*
* @param rs Context to which the allocation will belong.
* @param res application resources
@@ -1726,7 +1751,7 @@
* @param usage bit field specifying how the allocation is
* utilized
*
- * @return renderscript allocation containing resource data
+ * @return Allocation containing resource data
*
*/
static public Allocation createFromBitmapResource(RenderScript rs,
@@ -1736,6 +1761,9 @@
int usage) {
rs.validate();
+ if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
+ throw new RSIllegalArgumentException("Unsupported usage specified.");
+ }
Bitmap b = BitmapFactory.decodeResource(res, id);
Allocation alloc = createFromBitmap(rs, b, mips, usage);
b.recycle();
@@ -1743,18 +1771,19 @@
}
/**
- * Creates a non-mipmapped renderscript allocation to use as a
- * graphics texture from the bitmap referenced by resource id
+ * Creates a non-mipmapped Allocation to use as a graphics texture from the
+ * {@link android.graphics.Bitmap} referenced by resource ID.
*
- * With target API version 18 or greater, this allocation will be
- * created with USAGE_SHARED. With target API version 17 or lower,
- * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
+ * <p>With target API version 18 or greater, this allocation will be created
+ * with {@link #USAGE_SCRIPT} and {@link #USAGE_GRAPHICS_TEXTURE}. With
+ * target API version 17 or lower, this allocation will be created with
+ * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
*
* @param rs Context to which the allocation will belong.
* @param res application resources
* @param id resource id to load the data from
*
- * @return renderscript allocation containing resource data
+ * @return Allocation containing resource data
*
*/
static public Allocation createFromBitmapResource(RenderScript rs,
@@ -1763,7 +1792,7 @@
if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
return createFromBitmapResource(rs, res, id,
MipmapControl.MIPMAP_NONE,
- USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
+ USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
}
return createFromBitmapResource(rs, res, id,
MipmapControl.MIPMAP_NONE,
@@ -1771,8 +1800,7 @@
}
/**
- * Creates a renderscript allocation containing string data
- * encoded in UTF-8 format
+ * Creates an Allocation containing string data encoded in UTF-8 format.
*
* @param rs Context to which the allocation will belong.
* @param str string to create the allocation from
@@ -1799,11 +1827,10 @@
/**
* @hide
*
- * Interface to handle notification when new buffers are
- * available via USAGE_IO_INPUT. An application will receive
- * one notification when a buffer is available. Additional
- * buffers will not trigger new notifications until a buffer is
- * processed.
+ * Interface to handle notification when new buffers are available via
+ * {@link #USAGE_IO_INPUT}. An application will receive one notification
+ * when a buffer is available. Additional buffers will not trigger new
+ * notifications until a buffer is processed.
*/
public interface IoInputNotifier {
public void onBufferAvailable(Allocation a);
@@ -1812,7 +1839,7 @@
/**
* @hide
*
- * Set a notification handler for USAGE_IO_INPUT
+ * Set a notification handler for {@link #USAGE_IO_INPUT}.
*
* @param callback instance of the IoInputNotifier class to be called
* when buffer arrive.
@@ -1836,4 +1863,3 @@
}
-
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index 85d86e5..a6645bb 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -22,6 +22,7 @@
import android.util.TypedValue;
/**
+ * Only intended for use by generated reflected code.
*
**/
public class AllocationAdapter extends Allocation {
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index f464f9b..e17d79a 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -19,9 +19,9 @@
import android.util.Log;
/**
- * BaseObj is the base class for interfacing with native renderscript objects.
- * It primarly contains code for tracking the native object ID and forcably
- * disconecting the object from the native allocation for early cleanup.
+ * BaseObj is the base class for all RenderScript objects owned by a RS context.
+ * It is responsible for lifetime management and resource tracking. This class
+ * should not be used by a user application.
*
**/
public class BaseObj {
@@ -75,8 +75,7 @@
/**
* setName assigns a name to an object. This object can later be looked up
- * by this name. This name will also be retained if the object is written
- * to an A3D file.
+ * by this name.
*
* @param name The name to assign to the object.
*/
@@ -125,10 +124,9 @@
}
/**
- * destroy disconnects the object from the native object effectively
- * rendering this java object dead. The primary use is to force immediate
- * cleanup of resources when it is believed the GC will not respond quickly
- * enough.
+ * Frees any native resources associated with this object. The
+ * primary use is to force immediate cleanup of resources when it is
+ * believed the GC will not respond quickly enough.
*/
synchronized public void destroy() {
if(mDestroyed) {
diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java
index 7df5f2e..cf34f3a 100644
--- a/graphics/java/android/renderscript/Byte2.java
+++ b/graphics/java/android/renderscript/Byte2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript byte2 type back to the Android system.
+ * Class for exposing the native RenderScript byte2 type back to the Android system.
*
**/
public class Byte2 {
diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java
index 02a01c1..266e94d 100644
--- a/graphics/java/android/renderscript/Byte3.java
+++ b/graphics/java/android/renderscript/Byte3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript byte3 type back to the Android system.
+ * Class for exposing the native RenderScript byte3 type back to the Android system.
*
**/
public class Byte3 {
diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java
index a55a696..68c8f52 100644
--- a/graphics/java/android/renderscript/Byte4.java
+++ b/graphics/java/android/renderscript/Byte4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript byte4 type back to the Android system.
+ * Class for exposing the native RenderScript byte4 type back to the Android system.
*
**/
public class Byte4 {
diff --git a/graphics/java/android/renderscript/Double2.java b/graphics/java/android/renderscript/Double2.java
index 9f4f328..29fd515 100644
--- a/graphics/java/android/renderscript/Double2.java
+++ b/graphics/java/android/renderscript/Double2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript double2 type back
+ * Class for exposing the native RenderScript double2 type back
* to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Double3.java b/graphics/java/android/renderscript/Double3.java
index eb55142..818952e 100644
--- a/graphics/java/android/renderscript/Double3.java
+++ b/graphics/java/android/renderscript/Double3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript double3 type back
+ * Class for exposing the native RenderScript double3 type back
* to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Double4.java b/graphics/java/android/renderscript/Double4.java
index 4755a76..7775ab7 100644
--- a/graphics/java/android/renderscript/Double4.java
+++ b/graphics/java/android/renderscript/Double4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript double4 type back
+ * Class for exposing the native RenderScript double4 type back
* to the Android system.
*
**/
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index f6c07d1..3838c61 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -20,31 +20,37 @@
import android.util.Log;
/**
- * <p>The most basic data type. An element represents one cell of a memory allocation.
- * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms.
- * Examples of basic elements are:</p>
- * <ul>
- * <li>Single float value</li>
- * <li>4 element float vector</li>
- * <li>single RGB-565 color</li>
- * <li>single unsigned int 16</li>
- * </ul>
- * <p>Complex elements contain a list of sub-elements and names that
- * represents a structure of data. The fields can be accessed by name
- * from a script or shader. The memory layout is defined and ordered. Data
- * alignment is determined by the most basic primitive type. i.e. a float4
- * vector will be aligned to sizeof(float) and not sizeof(float4). The
- * ordering of elements in memory will be the order in which they were added
- * with each component aligned as necessary. No re-ordering will be done.</p>
+ * <p>An Element represents one item within an {@link
+ * android.renderscript.Allocation}. An Element is roughly equivalent to a C
+ * type in a RenderScript kernel. Elements may be basic or complex. Some basic
+ * elements are</p> <ul> <li>A single float value (equivalent to a float in a
+ * kernel)</li> <li>A four-element float vector (equivalent to a float4 in a
+ * kernel)</li> <li>An unsigned 32-bit integer (equivalent to an unsigned int in
+ * a kernel)</li> <li>A single signed 8-bit integer (equivalent to a char in a
+ * kernel)</li> </ul> <p>A complex element is roughly equivalent to a C struct
+ * and contains a number of basic or complex Elements. From Java code, a complex
+ * element contains a list of sub-elements and names that represents a
+ * particular data structure. Structs used in RS scripts are available to Java
+ * code by using the {@code ScriptField_structname} class that is reflected from
+ * a particular script.</p>
*
- * <p>The primary source of elements are from scripts. A script that exports a
- * bind point for a data structure generates a Renderscript element to represent the
- * data exported by the script. The other common source of elements is from bitmap formats.</p>
+ * <p>Basic Elements are comprised of a {@link
+ * android.renderscript.Element.DataType} and a {@link
+ * android.renderscript.Element.DataKind}. The DataType encodes C type
+ * information of an Element, while the DataKind encodes how that Element should
+ * be interpreted by a {@link android.renderscript.Sampler}. Note that {@link
+ * android.renderscript.Allocation} objects with DataKind {@link
+ * android.renderscript.Element.DataKind#USER} cannot be used as input for a
+ * {@link android.renderscript.Sampler}. In general, {@link
+ * android.renderscript.Allocation} objects that are intended for use with a
+ * {@link android.renderscript.Sampler} should use bitmap-derived Elements such
+ * as {@link android.renderscript.Element#RGBA_8888} or {@link
+ * android.renderscript#Element.A_8}.</p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
public class Element extends BaseObj {
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index 730d973..fed97d6 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -21,7 +21,7 @@
/**
* Utility class for packing arguments and structures from Android system objects to
- * Renderscript objects.
+ * RenderScript objects.
*
* This class is only intended to be used to support the
* reflected code generated by the RS tool chain. It should not
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index 8b0222a..e41f02d 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -30,9 +30,9 @@
/**
* @hide
* @deprecated in API 16
- * FileA3D allows users to load Renderscript objects from files
+ * FileA3D allows users to load RenderScript objects from files
* or resources stored on disk. It could be used to load items
- * such as 3D geometry data converted to a Renderscript format from
+ * such as 3D geometry data converted to a RenderScript format from
* content creation tools. Currently only meshes are supported
* in FileA3D.
*
@@ -56,7 +56,7 @@
UNKNOWN (0),
/**
* @deprecated in API 16
- * Renderscript Mesh object
+ * RenderScript Mesh object
**/
MESH (1);
@@ -72,7 +72,7 @@
/**
* @deprecated in API 16
- * IndexEntry contains information about one of the Renderscript
+ * IndexEntry contains information about one of the RenderScript
* objects inside the file's index. It could be used to query the
* object's type and also name and load the object itself if
* necessary.
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index 1d4ce36..0f730fe 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript float2 type back to the Android system.
+ * Class for exposing the native RenderScript float2 type back to the Android system.
*
**/
public class Float2 {
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index ffd1135..749865f1 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript float2 type back to the Android system.
+ * Class for exposing the native RenderScript float2 type back to the Android system.
*
**/
public class Float3 {
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index c7cc3ae..7ddf6aa 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript float2 type back to the Android system.
+ * Class for exposing the native RenderScript float2 type back to the Android system.
*
**/
public class Float4 {
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index 1a8d5bf..0375d2b 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -39,7 +39,7 @@
* faces, and different font sizes. During creation, the Android system quieries device's screen DPI to
* ensure proper sizing across multiple device configurations.</p>
* <p>Fonts are rendered using screen-space positions and no state setup beyond binding a
- * font to the Renderscript is required. A note of caution on performance, though the state changes
+ * font to the RenderScript is required. A note of caution on performance, though the state changes
* are transparent to the user, they do happen internally, and it is more efficient to
* render large batches of text in sequence. It is also more efficient to render multiple
* characters at once instead of one by one to improve draw call batching.</p>
diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java
index 434af21..71b5dd5 100644
--- a/graphics/java/android/renderscript/Int2.java
+++ b/graphics/java/android/renderscript/Int2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript int2 type back to the Android system.
+ * Class for exposing the native RenderScript int2 type back to the Android system.
*
**/
public class Int2 {
diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java
index 333ccf8..719c908 100644
--- a/graphics/java/android/renderscript/Int3.java
+++ b/graphics/java/android/renderscript/Int3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript int3 type back to the Android system.
+ * Class for exposing the native RenderScript int3 type back to the Android system.
*
**/
public class Int3 {
diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java
index 8734c95..eefb349 100644
--- a/graphics/java/android/renderscript/Int4.java
+++ b/graphics/java/android/renderscript/Int4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript int4 type back to the Android system.
+ * Class for exposing the native RenderScript int4 type back to the Android system.
*
**/
public class Int4 {
diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java
index 95ea18c..bd8382d 100644
--- a/graphics/java/android/renderscript/Long2.java
+++ b/graphics/java/android/renderscript/Long2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript long2 type back to the Android system.
+ * Class for exposing the native RenderScript long2 type back to the Android system.
**/
public class Long2 {
public Long2() {
diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java
index 96ee885..3e94942 100644
--- a/graphics/java/android/renderscript/Long3.java
+++ b/graphics/java/android/renderscript/Long3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript long3 type back to the Android system.
+ * Class for exposing the native RenderScript long3 type back to the Android system.
**/
public class Long3 {
public Long3() {
diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java
index 50e664c..00fb7e6 100644
--- a/graphics/java/android/renderscript/Long4.java
+++ b/graphics/java/android/renderscript/Long4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript long4 type back to the Android system.
+ * Class for exposing the native RenderScript long4 type back to the Android system.
**/
public class Long4 {
public Long4() {
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 39abd4f..d3621fa 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript rs_matrix2x2 type back to the Android system.
+ * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
*
**/
public class Matrix2f {
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index 5e9a7ca..8c3c330 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript rs_matrix3x3 type back to the Android system.
+ * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
*
**/
public class Matrix3f {
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index 4600424..cd18e30 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript rs_matrix4x4 type back to the Android system.
+ * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
*
**/
public class Matrix4f {
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index d0d383d..bca4aa3 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -24,7 +24,7 @@
* @hide
* @deprecated in API 16
* <p>This class is a container for geometric data displayed with
- * Renderscript. Internally, a mesh is a collection of allocations that
+ * RenderScript. Internally, a mesh is a collection of allocations that
* represent vertex data (positions, normals, texture
* coordinates) and index data such as triangles and lines. </p>
* <p>
@@ -32,7 +32,7 @@
* allocation that is provided separately, as multiple allocation
* objects, or done as a combination of both. When a
* vertex channel name matches an input in the vertex program,
- * Renderscript automatically connects the two together.
+ * RenderScript automatically connects the two together.
* </p>
* <p>
* Parts of the mesh can be rendered with either explicit
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index 9bd103e..bc2ca35 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -276,7 +276,7 @@
try {
mShader = new String(str, 0, strLength, "UTF-8");
} catch (UnsupportedEncodingException e) {
- Log.e("Renderscript shader creation", "Could not decode shader string");
+ Log.e("RenderScript shader creation", "Could not decode shader string");
}
return this;
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index dd0f9f5..b9ba3fd 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -23,7 +23,7 @@
/**
* @hide
* @deprecated in API 16
- * <p>The Renderscript fragment program, also known as fragment shader is responsible
+ * <p>The RenderScript fragment program, also known as fragment shader is responsible
* for manipulating pixel data in a user defined way. It's constructed from a GLSL
* shader string containing the program body, textures inputs, and a Type object
* that describes the constants used by the program. Similar to the vertex programs,
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 50e32f6..1c5a191 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -16,9 +16,9 @@
/**
* @hide
- * <p>The Renderscript vertex program, also known as a vertex shader, describes a stage in
+ * <p>The RenderScript vertex program, also known as a vertex shader, describes a stage in
* the graphics pipeline responsible for manipulating geometric data in a user-defined way.
- * The object is constructed by providing the Renderscript system with the following data:</p>
+ * The object is constructed by providing the RenderScript system with the following data:</p>
* <ul>
* <li>Element describing its varying inputs or attributes</li>
* <li>GLSL shader string that defines the body of the program</li>
@@ -28,7 +28,7 @@
* <p>Once the program is created, you bind it to the graphics context, RenderScriptGL, and it will be used for
* all subsequent draw calls until you bind a new program. If the program has constant inputs,
* the user needs to bind an allocation containing those inputs. The allocation's type must match
- * the one provided during creation. The Renderscript library then does all the necessary plumbing
+ * the one provided during creation. The RenderScript library then does all the necessary plumbing
* to send those constants to the graphics hardware. Varying inputs to the shader, such as position, normal,
* and texture coordinates are matched by name between the input Element and the Mesh object being drawn.
* The signatures don't have to be exact or in any strict order. As long as the input name in the shader
diff --git a/graphics/java/android/renderscript/RSDriverException.java b/graphics/java/android/renderscript/RSDriverException.java
index ce85b53..9e6507f 100644
--- a/graphics/java/android/renderscript/RSDriverException.java
+++ b/graphics/java/android/renderscript/RSDriverException.java
@@ -19,7 +19,7 @@
/**
* Base class for all exceptions thrown by the Android
- * Renderscript
+ * RenderScript
*/
public class RSDriverException extends RSRuntimeException {
public RSDriverException(String string) {
diff --git a/graphics/java/android/renderscript/RSIllegalArgumentException.java b/graphics/java/android/renderscript/RSIllegalArgumentException.java
index 954c0e8..5c68594 100644
--- a/graphics/java/android/renderscript/RSIllegalArgumentException.java
+++ b/graphics/java/android/renderscript/RSIllegalArgumentException.java
@@ -19,7 +19,7 @@
/**
* Base class for all exceptions thrown by the Android
- * Renderscript
+ * RenderScript
*/
public class RSIllegalArgumentException extends RSRuntimeException {
public RSIllegalArgumentException(String string) {
diff --git a/graphics/java/android/renderscript/RSInvalidStateException.java b/graphics/java/android/renderscript/RSInvalidStateException.java
index 691aeba..c881898 100644
--- a/graphics/java/android/renderscript/RSInvalidStateException.java
+++ b/graphics/java/android/renderscript/RSInvalidStateException.java
@@ -19,7 +19,7 @@
/**
* Base class for all exceptions thrown by the Android
- * Renderscript
+ * RenderScript
*/
public class RSInvalidStateException extends RSRuntimeException {
public RSInvalidStateException(String string) {
diff --git a/graphics/java/android/renderscript/RSRuntimeException.java b/graphics/java/android/renderscript/RSRuntimeException.java
index 5a16478..b4b629e 100644
--- a/graphics/java/android/renderscript/RSRuntimeException.java
+++ b/graphics/java/android/renderscript/RSRuntimeException.java
@@ -19,7 +19,7 @@
/**
* Base class for all exceptions thrown by the Android
- * Renderscript
+ * RenderScript
*/
public class RSRuntimeException
extends java.lang.RuntimeException {
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 3c6c720..308d97a 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -36,8 +36,8 @@
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
*/
public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 8071073..4de4766 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -33,15 +33,14 @@
import android.os.Trace;
/**
- * Renderscript base master class. An instance of this class creates native
- * worker threads for processing commands from this object. This base class
- * does not provide any extended capabilities beyond simple data processing.
- * For extended capabilities use derived classes such as RenderScriptGL.
+ * This class provides access to a RenderScript context, which controls RenderScript
+ * initialization, resource management, and teardown. An instance of the RenderScript
+ * class must be created before any other RS objects can be created.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
public class RenderScript {
@@ -912,11 +911,14 @@
//
/**
- * Base class application should derive from for handling RS messages
- * coming from their scripts. When a script calls sendToClient the data
- * fields will be filled in and then the run method called by a message
- * handling thread. This will occur some time after sendToClient completes
- * in the script.
+ * The base class from which an application should derive in order
+ * to receive RS messages from scripts. When a script calls {@code
+ * rsSendToClient}, the data fields will be filled, and the run
+ * method will be called on a separate thread. This will occur
+ * some time after {@code rsSendToClient} completes in the script,
+ * as {@code rsSendToClient} is asynchronous. Message handlers are
+ * not guaranteed to have completed when {@link
+ * android.renderscript.RenderScript#finish} returns.
*
*/
public static class RSMessageHandler implements Runnable {
@@ -927,9 +929,10 @@
}
}
/**
- * If an application is expecting messages it should set this field to an
- * instance of RSMessage. This instance will receive all the user messages
- * sent from sendToClient by scripts from this context.
+ * If an application is expecting messages, it should set this
+ * field to an instance of {@link RSMessageHandler}. This
+ * instance will receive all the user messages sent from {@code
+ * sendToClient} by scripts from this context.
*
*/
RSMessageHandler mMessageCallback = null;
@@ -953,9 +956,9 @@
}
/**
- * Runtime error base class. An application should derive from this class
- * if it wishes to install an error handler. When errors occur at runtime
- * the fields in this class will be filled and the run method called.
+ * The runtime error handler base class. An application should derive from this class
+ * if it wishes to install an error handler. When errors occur at runtime,
+ * the fields in this class will be filled, and the run method will be called.
*
*/
public static class RSErrorHandler implements Runnable {
@@ -968,7 +971,7 @@
/**
* Application Error handler. All runtime errors will be dispatched to the
* instance of RSAsyncError set here. If this field is null a
- * RSRuntimeException will instead be thrown with details about the error.
+ * {@link RSRuntimeException} will instead be thrown with details about the error.
* This will cause program termaination.
*
*/
@@ -982,10 +985,9 @@
}
/**
- * RenderScript worker threads priority enumeration. The default value is
- * NORMAL. Applications wishing to do background processing such as
- * wallpapers should set their priority to LOW to avoid starving forground
- * processes.
+ * RenderScript worker thread priority enumeration. The default value is
+ * NORMAL. Applications wishing to do background processing should set
+ * their priority to LOW to avoid starving forground processes.
*/
public enum Priority {
LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
@@ -1052,7 +1054,7 @@
}
if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
RS_MESSAGE_TO_CLIENT_USER) {
- throw new RSDriverException("Error processing message from Renderscript.");
+ throw new RSDriverException("Error processing message from RenderScript.");
}
if(mRS.mMessageCallback != null) {
@@ -1137,7 +1139,7 @@
}
/**
- * Create a basic RenderScript context.
+ * Create a RenderScript context.
*
* @hide
* @param ctx The context.
@@ -1163,7 +1165,7 @@
}
/**
- * Create a basic RenderScript context.
+ * Create a RenderScript context.
*
* @param ctx The context.
* @return RenderScript
@@ -1173,7 +1175,7 @@
}
/**
- * Create a basic RenderScript context.
+ * Create a RenderScript context.
*
*
* @param ctx The context.
@@ -1196,8 +1198,8 @@
}
/**
- * Wait for any commands in the fifo between the java bindings and native to
- * be processed.
+ * Wait for any pending asynchronous opeations (such as copies to a RS
+ * allocation or RS script executions) to complete.
*
*/
public void finish() {
@@ -1205,8 +1207,9 @@
}
/**
- * Destroy this renderscript context. Once this function is called its no
- * longer legal to use this or any objects created by this context.
+ * Destroys this RenderScript context. Once this function is called,
+ * using this context or any objects belonging to this context is
+ * illegal.
*
*/
public void destroy() {
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 52034b1..bac9c68 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -31,7 +31,7 @@
/**
* @hide
* @deprecated in API 16
- * The Graphics derivitive of Renderscript. Extends the basic context to add a
+ * The Graphics derivitive of RenderScript. Extends the basic context to add a
* root script which is the display window for graphical output. When the
* system needs to update the display the currently bound root script will be
* called. This script is expected to issue the rendering commands to repaint
@@ -39,8 +39,8 @@
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
public class RenderScriptGL extends RenderScript {
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 057e9b5..623055fe 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -28,9 +28,14 @@
import android.graphics.BitmapFactory;
/**
- * Sampler object which defines how data is extracted from textures. Samplers
- * are attached to Program objects (currently only ProgramFragment) when those objects
- * need to access texture data.
+ * Sampler object that defines how Allocations can be read as textures within a
+ * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
+ * function to return values from normalized coordinates.
+ *
+ * Any Allocation used with a Sampler must have been created with {@link
+ * android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a Sampler on
+ * an {@link android.renderscript.Allocation} that was not created with {@link
+ * android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is undefined.
**/
public class Sampler extends BaseObj {
public enum Value {
@@ -275,9 +280,8 @@
}
/**
- * Builder for creating non-standard samplers. Usefull if mix and match of
- * wrap modes is necesary or if anisotropic filtering is desired.
- *
+ * Builder for creating non-standard samplers. This is only necessary if
+ * a Sampler with different min and mag modes is desired.
*/
public static class Builder {
RenderScript mRS;
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index f0579ca..0026e0e 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -19,7 +19,8 @@
import android.util.SparseArray;
/**
- *
+ * The parent class for all executable scripts. This should not be used by
+ * applications.
**/
public class Script extends BaseObj {
@@ -46,14 +47,6 @@
private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
/**
* Only to be used by generated reflected classes.
- *
- *
- * @param slot
- * @param sig
- * @param ein
- * @param eout
- *
- * @return KernelID
*/
protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
KernelID k = mKIDs.get(slot);
@@ -92,11 +85,6 @@
private final SparseArray<FieldID> mFIDs = new SparseArray();
/**
* Only to be used by generated reflected classes.
- *
- * @param slot
- * @param e
- *
- * @return FieldID
*/
protected FieldID createFieldID(int slot, Element e) {
FieldID f = mFIDs.get(slot);
@@ -118,7 +106,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param slot
*/
protected void invoke(int slot) {
mRS.nScriptInvoke(getID(mRS), slot);
@@ -127,8 +114,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param slot
- * @param v
*/
protected void invoke(int slot, FieldPacker v) {
if (v != null) {
@@ -141,10 +126,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param slot
- * @param ain
- * @param aout
- * @param v
*/
protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
if (ain == null && aout == null) {
@@ -169,11 +150,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param slot
- * @param ain
- * @param aout
- * @param v
- * @param sc
*/
protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
if (ain == null && aout == null) {
@@ -208,8 +184,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param va
- * @param slot
*/
public void bindAllocation(Allocation va, int slot) {
mRS.validate();
@@ -223,8 +197,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, float v) {
mRS.nScriptSetVarF(getID(mRS), index, v);
@@ -236,8 +208,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, double v) {
mRS.nScriptSetVarD(getID(mRS), index, v);
@@ -249,8 +219,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, int v) {
mRS.nScriptSetVarI(getID(mRS), index, v);
@@ -263,8 +231,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, long v) {
mRS.nScriptSetVarJ(getID(mRS), index, v);
@@ -277,8 +243,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, boolean v) {
mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
@@ -290,8 +254,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param o
*/
public void setVar(int index, BaseObj o) {
mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
@@ -300,8 +262,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void setVar(int index, FieldPacker v) {
mRS.nScriptSetVarV(getID(mRS), index, v.getData());
@@ -310,10 +270,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
- * @param e
- * @param dims
*/
public void setVar(int index, FieldPacker v, Element e, int[] dims) {
mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims);
@@ -322,8 +278,6 @@
/**
* Only intended for use by generated reflected code.
*
- * @param index
- * @param v
*/
public void getVarV(int index, FieldPacker v) {
mRS.nScriptGetVarV(getID(mRS), index, v.getData());
@@ -338,6 +292,10 @@
}
}
+ /**
+ * Only intended for use by generated reflected code.
+ *
+ */
public static class Builder {
RenderScript mRS;
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 6975534..b0a5759 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -30,7 +30,8 @@
import java.lang.reflect.Modifier;
/**
- *
+ * The superclass for all user-defined scripts. This is only
+ * intended to be used by the generated derived classes.
**/
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
diff --git a/graphics/java/android/renderscript/ScriptGroup.java b/graphics/java/android/renderscript/ScriptGroup.java
index 7afdb39..1416641 100644
--- a/graphics/java/android/renderscript/ScriptGroup.java
+++ b/graphics/java/android/renderscript/ScriptGroup.java
@@ -20,24 +20,26 @@
import java.util.ArrayList;
/**
- * ScriptGroup creates a groups of scripts which are executed
- * together based upon upon one execution call as if they were
- * all part of a single script. The scripts may be connected
- * internally or to an external allocation. For the internal
- * connections the intermediate results are not observable after
- * the execution of the script.
+ * ScriptGroup creates a group of kernels that are executed
+ * together with one execution call as if they were a single kernel.
+ * The kernels may be connected internally or to an external allocation.
+ * The intermediate results for internal connections are not observable
+ * after the execution of the script.
* <p>
- * The external connections are grouped into inputs and outputs.
+ * External connections are grouped into inputs and outputs.
* All outputs are produced by a script kernel and placed into a
- * user supplied allocation. Inputs are similar but supply the
- * input of a kernal. Inputs bounds to a script are set directly
- * upon the script.
+ * user-supplied allocation. Inputs provide the input of a kernel.
+ * Inputs bound to script globals are set directly upon the script.
* <p>
* A ScriptGroup must contain at least one kernel. A ScriptGroup
* must contain only a single directed acyclic graph (DAG) of
* script kernels and connections. Attempting to create a
* ScriptGroup with multiple DAGs or attempting to create
* a cycle within a ScriptGroup will throw an exception.
+ * <p>
+ * Currently, all kernels in a ScriptGroup must be from separate
+ * Script objects. Attempting to use multiple kernels from the same
+ * Script object will result in an {@link android.renderscript.RSInvalidStateException}.
*
**/
public final class ScriptGroup extends BaseObj {
@@ -93,8 +95,8 @@
/**
* Sets an input of the ScriptGroup. This specifies an
- * Allocation to be used for the kernels which require a kernel
- * input and that input is provided external to the group.
+ * Allocation to be used for kernels that require an input
+ * Allocation provided from outside of the ScriptGroup.
*
* @param s The ID of the kernel where the allocation should be
* connected.
@@ -113,8 +115,8 @@
/**
* Sets an output of the ScriptGroup. This specifies an
- * Allocation to be used for the kernels which require a kernel
- * output and that output is provided external to the group.
+ * Allocation to be used for the kernels that require an output
+ * Allocation visible after the ScriptGroup is executed.
*
* @param s The ID of the kernel where the allocation should be
* connected.
@@ -133,8 +135,8 @@
/**
* Execute the ScriptGroup. This will run all the kernels in
- * the script. The state of the connecting lines will not be
- * observable after this operation.
+ * the ScriptGroup. No internal connection results will be visible
+ * after execution of the ScriptGroup.
*/
public void execute() {
mRS.nScriptGroupExecute(getID(mRS));
@@ -142,20 +144,25 @@
/**
- * Create a ScriptGroup. There are two steps to creating a
- * ScriptGoup.
+ * Helper class to build a ScriptGroup. A ScriptGroup is
+ * created in two steps.
* <p>
- * First all the Kernels to be used by the group should be
- * added. Once this is done the kernels should be connected.
- * Kernels cannot be added once a connection has been made.
+ * First, all kernels to be used by the ScriptGroup should be added.
* <p>
- * Second, add connections. There are two forms of connections.
- * Kernel to Kernel and Kernel to Field. Kernel to Kernel is
- * higher performance and should be used where possible. The
- * line of connections cannot form a loop. If a loop is detected
- * an exception is thrown.
+ * Second, add connections between kernels. There are two types
+ * of connections: kernel to kernel and kernel to field.
+ * Kernel to kernel allows a kernel's output to be passed to
+ * another kernel as input. Kernel to field allows the output of
+ * one kernel to be bound as a script global. Kernel to kernel is
+ * higher performance and should be used where possible.
* <p>
- * Once all the connections are made a call to create will
+ * A ScriptGroup must contain a single directed acyclic graph (DAG); it
+ * cannot contain cycles. Currently, all kernels used in a ScriptGroup
+ * must come from different Script objects. Additionally, all kernels
+ * in a ScriptGroup must have at least one input, output, or internal
+ * connection.
+ * <p>
+ * Once all connections are made, a call to {@link #create} will
* return the ScriptGroup object.
*
*/
@@ -166,10 +173,10 @@
private int mKernelCount;
/**
- * Create a builder for generating a ScriptGroup.
+ * Create a Builder for generating a ScriptGroup.
*
*
- * @param rs The Renderscript context.
+ * @param rs The RenderScript context.
*/
public Builder(RenderScript rs) {
mRS = rs;
diff --git a/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java b/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
index 86f37d8..34540a1 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsic3DLUT.java
@@ -40,7 +40,7 @@
*
* The defaults tables are identity.
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for intputs and outputs
*
* @return ScriptIntrinsic3DLUT
@@ -55,6 +55,13 @@
return new ScriptIntrinsic3DLUT(id, rs, e);
}
+ /**
+ * Sets the {@link android.renderscript.Allocation} to be used as the lookup table.
+ *
+ * The lookup table must use the same {@link android.renderscript.Element} as the intrinsic.
+ *
+ */
+
public void setLUT(Allocation lut) {
final Type t = lut.getType();
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
index 65c69c0..0e05bc8 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -18,8 +18,7 @@
/**
- * Intrinsic kernels for blending two buffers. Each blend function is a separate
- * kernel to make it easy to change between blend modes.
+ * Intrinsic kernels for blending two {@link android.renderscript.Allocation} objects.
**/
public class ScriptIntrinsicBlend extends ScriptIntrinsic {
ScriptIntrinsicBlend(int id, RenderScript rs) {
@@ -27,11 +26,10 @@
}
/**
- * Supported elements types are uchar4
+ * Supported elements types are {@link Element#U8_4}
*
- *
- * @param rs
- * @param e
+ * @param rs The RenderScript context
+ * @param e Element type for inputs and outputs
*
* @return ScriptIntrinsicBlend
*/
@@ -53,7 +51,7 @@
}
/**
- * dst = {0, 0, 0, 0}
+ * Sets dst = {0, 0, 0, 0}
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -73,7 +71,7 @@
/**
- * dst = src
+ * Sets dst = src
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -92,8 +90,9 @@
}
/**
- * dst = dst
- * This is a NOP
+ * Sets dst = dst
+ *
+ * This is a NOP.
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -112,7 +111,7 @@
}
/**
- * dst = src + dst * (1.0 - src.a)
+ * Sets dst = src + dst * (1.0 - src.a)
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -131,7 +130,7 @@
}
/**
- * dst = dst + src * (1.0 - dst.a)
+ * Sets dst = dst + src * (1.0 - dst.a)
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -150,7 +149,7 @@
}
/**
- * dst = src * dst.a
+ * Sets dst = src * dst.a
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -169,7 +168,7 @@
}
/**
- * dst = dst * src.a
+ * Sets dst = dst * src.a
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -188,7 +187,7 @@
}
/**
- * dst = src * (1.0 - dst.a)
+ * Sets dst = src * (1.0 - dst.a)
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -207,7 +206,7 @@
}
/**
- * dst = dst * (1.0 - src.a)
+ * Sets dst = dst * (1.0 - src.a)
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -266,7 +265,7 @@
}
/**
- * dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
+ * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -295,7 +294,7 @@
}
*/
/**
- * dst = src * dst
+ * Sets dst = src * dst
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -391,7 +390,7 @@
}
*/
/**
- * dst = min(src + dst, 1.0)
+ * Sets dst = min(src + dst, 1.0)
*
* @param ain The source buffer
* @param aout The destination buffer
@@ -410,7 +409,7 @@
}
/**
- * dst = max(dst - src, 0.0)
+ * Sets dst = max(dst - src, 0.0)
*
* @param ain The source buffer
* @param aout The destination buffer
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
index 2848f64..aaf5ffc 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -40,7 +40,7 @@
*
* Supported elements types are {@link Element#U8_4}
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for inputs and outputs
*
* @return ScriptIntrinsicBlur
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index f7e844e..77b9385 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -41,7 +41,7 @@
*
* Supported elements types are {@link Element#U8_4}
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for intputs and outputs
*
* @return ScriptIntrinsicColorMatrix
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index d54df96..c9c54b2 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -41,7 +41,7 @@
* <p> [ 0, 0, 0 ]
* </code>
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for intputs and outputs
*
* @return ScriptIntrinsicConvolve3x3
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index 1f52e3f..c6e1e39 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -42,7 +42,7 @@
* <p> [ 0, 0, 0, 0, 0 ]
* </code>
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for intputs and outputs
*
* @return ScriptIntrinsicConvolve5x5
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
index f5ca261..0f7ab38 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -47,7 +47,7 @@
*
* The defaults tables are identity.
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for intputs and outputs
*
* @return ScriptIntrinsicLUT
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index dc8a5aa..9b5de9b 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -36,7 +36,7 @@
*
* Supported elements types are {@link Element#U8_4}
*
- * @param rs The Renderscript context
+ * @param rs The RenderScript context
* @param e Element type for output
*
* @return ScriptIntrinsicYuvToRGB
diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java
index 617f1f5..7c6027f 100644
--- a/graphics/java/android/renderscript/Short2.java
+++ b/graphics/java/android/renderscript/Short2.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript Short2 type back to the Android system.
+ * Class for exposing the native RenderScript Short2 type back to the Android system.
*
**/
public class Short2 {
diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java
index b9ca49b..49de05e 100644
--- a/graphics/java/android/renderscript/Short3.java
+++ b/graphics/java/android/renderscript/Short3.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript short3 type back to the Android system.
+ * Class for exposing the native RenderScript short3 type back to the Android system.
*
**/
public class Short3 {
diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java
index d5f2db5..a7807a4 100644
--- a/graphics/java/android/renderscript/Short4.java
+++ b/graphics/java/android/renderscript/Short4.java
@@ -21,7 +21,7 @@
/**
- * Class for exposing the native Renderscript short4 type back to the Android system.
+ * Class for exposing the native RenderScript short4 type back to the Android system.
*
**/
public class Short4 {
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index a5e24ce..ef08c29 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -23,24 +23,29 @@
import android.util.Log;
/**
- * <p>Type is an allocation template. It consists of an Element and one or more
- * dimensions. It describes only the layout of memory but does not allocate any
- * storage for the data that is described.</p>
+ * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
+ * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
+ * android.renderscript.Type.Builder}.</p>
*
- * <p>A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
- * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned
- * any positive integral value within the constraints of available memory. A
- * single dimension allocation would have an X dimension of greater than zero
- * while the Y and Z dimensions would be zero to indicate not present. In this
- * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
- * x=10, y=0 would be considered 1 dimensional.</p>
+ * <p>A Type always includes an {@link android.renderscript.Element} and an X
+ * dimension. A Type may be multidimensional, up to three dimensions. A nonzero
+ * value in the Y or Z dimensions indicates that the dimension is present. Note
+ * that a Type with only a given X dimension and a Type with the same X
+ * dimension but Y = 1 are not equivalent.</p>
*
- * <p>The LOD and Faces dimensions are booleans to indicate present or not present.</p>
+ * <p>A Type also supports inclusion of level of detail (LOD) or cube map
+ * faces. LOD and cube map faces are booleans to indicate present or not
+ * present. </p>
+ *
+ * <p>A Type also supports YUV format information to support an {@link
+ * android.renderscript.Allocation} in a YUV format. The YUV formats supported
+ * are {@link android.graphics.ImageFormat#YV12} and {@link
+ * android.graphics.ImageFormat#NV21}.</p>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
- * <p>For more information about creating an application that uses Renderscript, read the
- * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
* </div>
**/
public class Type extends BaseObj {
@@ -277,11 +282,9 @@
}
/**
- * Set the YUV layout for a Type. This controls how the memory is
- * interpreted. Generally and application should not need to call this
- * function and it would be set by the Camera.
+ * Set the YUV layout for a Type.
*
- * only NV21, YV12. Enums from ImageFormat
+ * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
*/
public Builder setYuvFormat(int yuvFormat) {
switch (yuvFormat) {
@@ -299,7 +302,7 @@
/**
- * Validate structure and create a new type.
+ * Validate structure and create a new Type.
*
* @return Type
*/
diff --git a/graphics/java/android/renderscript/package.html b/graphics/java/android/renderscript/package.html
index eb178c1..a844956 100644
--- a/graphics/java/android/renderscript/package.html
+++ b/graphics/java/android/renderscript/package.html
@@ -2,6 +2,11 @@
<BODY>
<p>RenderScript provides support for high-performance computation across heterogeneous processors.</p>
+<p>This package is for the latest native version of RenderScript included on
+Android devices. Developers interested in running RenderScript on any Android
+device running {@link android.os.Build.VERSION_CODES#GINGERBREAD} or newer
+should see the {@link android.support.v8.renderscript} package.
+
<p>For more information, see the
<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
{@more}
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java b/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java
deleted file mode 100644
index 5fcc3bc..0000000
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.MipmapDrawable;
-import android.graphics.drawable.DrawableContainer.DrawableContainerState;
-import android.test.InstrumentationTestCase;
-
-public class MipmapDrawableTest extends InstrumentationTestCase {
- private MockMipmapDrawable mMipmapDrawable;
-
- private DrawableContainerState mDrawableContainerState;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mMipmapDrawable = new MockMipmapDrawable();
- mDrawableContainerState = (DrawableContainerState) mMipmapDrawable.getConstantState();
- }
-
- public void testMipmapDrawable() {
- new MipmapDrawable();
- // Check the values set in the constructor
- assertNotNull(new MipmapDrawable().getConstantState());
- assertTrue(new MockMipmapDrawable().hasCalledOnBoundsChanged());
- }
-
- public void testAddDrawable() {
- assertEquals(0, mDrawableContainerState.getChildCount());
-
- // nothing happens if drawable is null
- mMipmapDrawable.reset();
- mMipmapDrawable.addDrawable(null);
- assertEquals(0, mDrawableContainerState.getChildCount());
- assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- mMipmapDrawable.reset();
- mMipmapDrawable.addDrawable(new MockDrawable());
- assertEquals(1, mDrawableContainerState.getChildCount());
- assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- mMipmapDrawable.reset();
- mMipmapDrawable.addDrawable(new MockDrawable());
- assertEquals(2, mDrawableContainerState.getChildCount());
- assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
- }
-
- public void testSortedByHeight() {
- Drawable small = new MockDrawable(8);
- Drawable medium = new MockDrawable(32);
- Drawable large = new MockDrawable(128);
-
- mMipmapDrawable.addDrawable(medium);
- assertSame(medium, mDrawableContainerState.getChildren()[0]);
-
- mMipmapDrawable.addDrawable(small);
- assertSame(small, mDrawableContainerState.getChildren()[0]);
- assertSame(medium, mDrawableContainerState.getChildren()[1]);
-
- mMipmapDrawable.addDrawable(large);
- assertSame(small, mDrawableContainerState.getChildren()[0]);
- assertSame(medium, mDrawableContainerState.getChildren()[1]);
- assertSame(large, mDrawableContainerState.getChildren()[2]);
-
- mMipmapDrawable.addDrawable(small);
- assertSame(small, mDrawableContainerState.getChildren()[0]);
- assertSame(small, mDrawableContainerState.getChildren()[1]);
- assertSame(medium, mDrawableContainerState.getChildren()[2]);
- assertSame(large, mDrawableContainerState.getChildren()[3]);
-
- mMipmapDrawable.addDrawable(medium);
- assertSame(small, mDrawableContainerState.getChildren()[0]);
- assertSame(small, mDrawableContainerState.getChildren()[1]);
- assertSame(medium, mDrawableContainerState.getChildren()[2]);
- assertSame(medium, mDrawableContainerState.getChildren()[3]);
- assertSame(large, mDrawableContainerState.getChildren()[4]);
-
- mMipmapDrawable.addDrawable(large);
- assertSame(small, mDrawableContainerState.getChildren()[0]);
- assertSame(small, mDrawableContainerState.getChildren()[1]);
- assertSame(medium, mDrawableContainerState.getChildren()[2]);
- assertSame(medium, mDrawableContainerState.getChildren()[3]);
- assertSame(large, mDrawableContainerState.getChildren()[4]);
- assertSame(large, mDrawableContainerState.getChildren()[5]);
- }
-
- public void testSetBoundsOneItem() {
- // the method is not called if same bounds are set
- mMipmapDrawable.reset();
- mMipmapDrawable.setBounds(mMipmapDrawable.getBounds());
- assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- // the method is called if different bounds are set, even without drawables
- mMipmapDrawable.reset();
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
- assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- // adding an item should check bounds to see if new drawable is more appropriate
- mMipmapDrawable.reset();
- Drawable item = new MockDrawable(42);
- mMipmapDrawable.addDrawable(item);
- assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- // the method is called if different bounds are set
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
- assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
- // check that correct drawable is selected for any size.
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() - 1));
- assertSame(item, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight()));
- assertSame(item, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() + 1));
- assertSame(item, mMipmapDrawable.getCurrent());
- }
-
- public void testSetBounds() {
- Drawable small = new MockDrawable(8);
- Drawable medium = new MockDrawable(32);
- Drawable large = new MockDrawable(128);
-
- mMipmapDrawable.addDrawable(large);
- mMipmapDrawable.addDrawable(small);
- mMipmapDrawable.addDrawable(medium);
-
- // check that correct drawable is selected.
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() - 1));
- assertSame(small, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight()));
- assertSame(small, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() + 1));
- assertSame(medium, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() - 1));
- assertSame(medium, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight()));
- assertSame(medium, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() + 1));
- assertSame(large, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() - 1));
- assertSame(large, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight()));
- assertSame(large, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() + 1));
- assertSame(large, mMipmapDrawable.getCurrent());
- }
-
- public void testSizes() {
- // Check default value with no mipmap defined
- assertEquals(-1, mMipmapDrawable.getIntrinsicHeight());
- assertEquals(-1, mMipmapDrawable.getIntrinsicWidth());
- assertEquals(0, mMipmapDrawable.getMinimumHeight());
- assertEquals(0, mMipmapDrawable.getMinimumWidth());
-
- Drawable small = new MockDrawable(8, 4);
- Drawable medium = new MockDrawable(32, 16);
- Drawable large = new MockDrawable(128, 64);
-
- mMipmapDrawable.addDrawable(medium);
- assertEquals(medium.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
- assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
-
- mMipmapDrawable.addDrawable(large);
- assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
- assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
-
- mMipmapDrawable.addDrawable(small);
- assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
- assertEquals(small.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
- }
-
- public void testReplacementWhenAdded() {
- Drawable small = new MockDrawable(8);
- Drawable medium = new MockDrawable(32);
- Drawable large = new MockDrawable(128);
-
- // Small bounds, so that the smallest mipmap should always be selected
- mMipmapDrawable.setBounds(new Rect(0, 0, 0, 0));
-
- // Providing smaller versions, that should immediately be used as current
- mMipmapDrawable.addDrawable(large);
- assertSame(large, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.addDrawable(medium);
- assertSame(medium, mMipmapDrawable.getCurrent());
-
- mMipmapDrawable.addDrawable(small);
- assertSame(small, mMipmapDrawable.getCurrent());
- }
-
- private class MockMipmapDrawable extends MipmapDrawable {
- private boolean mHasCalledOnBoundsChanged;
-
- public boolean hasCalledOnBoundsChanged() {
- return mHasCalledOnBoundsChanged;
- }
-
- public void reset() {
- mHasCalledOnBoundsChanged = false;
- }
-
- @Override
- protected void onBoundsChange(Rect bounds) {
- super.onBoundsChange(bounds);
- mHasCalledOnBoundsChanged = true;
- }
- }
-
- private class MockDrawable extends Drawable {
- int mIntrinsicHeight;
- int mMinimumHeight;
-
- public MockDrawable() {
- this(0);
- }
-
- public MockDrawable(int intrinsicHeight) {
- this(intrinsicHeight, intrinsicHeight);
- }
-
- public MockDrawable(int intrinsicHeight, int minimumHeight) {
- mIntrinsicHeight = intrinsicHeight;
- mMinimumHeight = minimumHeight;
- }
-
- @Override
- public void draw(Canvas canvas) {
- }
-
- @Override
- public int getOpacity() {
- return 0;
- }
-
- @Override
- public void setAlpha(int alpha) {
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mIntrinsicHeight;
- }
-
- @Override
- public int getMinimumHeight() {
- return mMinimumHeight;
- }
- }
-}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 771ac45..5a30472 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -41,6 +41,7 @@
SkiaShader.cpp \
Snapshot.cpp \
Stencil.cpp \
+ Texture.cpp \
TextureCache.cpp \
TextDropShadowCache.cpp
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 8511e7c..782c052 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -15,6 +15,7 @@
*/
#include "AssetAtlas.h"
+#include "Caches.h"
#include <GLES2/gl2ext.h>
@@ -33,12 +34,14 @@
mImage = new Image(buffer);
if (mImage->getTexture()) {
- mTexture = new Texture();
+ Caches& caches = Caches::getInstance();
+
+ mTexture = new Texture(caches);
mTexture->id = mImage->getTexture();
mTexture->width = buffer->getWidth();
mTexture->height = buffer->getHeight();
- createEntries(map, count);
+ createEntries(caches, map, count);
} else {
ALOGW("Could not create atlas image");
@@ -82,7 +85,7 @@
* instead of applying the changes to the virtual textures.
*/
struct DelegateTexture: public Texture {
- DelegateTexture(Texture* delegate): Texture(), mDelegate(delegate) { }
+ DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { }
virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
@@ -100,7 +103,7 @@
/**
* TODO: This method does not take the rotation flag into account
*/
-void AssetAtlas::createEntries(int* map, int count) {
+void AssetAtlas::createEntries(Caches& caches, int* map, int count) {
const float width = float(mTexture->width);
const float height = float(mTexture->height);
@@ -117,7 +120,7 @@
x / width, (x + bitmap->width()) / width,
y / height, (y + bitmap->height()) / height);
- Texture* texture = new DelegateTexture(mTexture);
+ Texture* texture = new DelegateTexture(caches, mTexture);
Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
texture->id = mTexture->id;
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 793e300..2624907 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -34,6 +34,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
/**
* An asset atlas holds a collection of framework bitmaps in a single OpenGL
* texture. Each bitmap is associated with a location, defined in pixels,
@@ -157,7 +159,7 @@
Texture* getEntryTexture(SkBitmap* const bitmap) const;
private:
- void createEntries(int* map, int count);
+ void createEntries(Caches& caches, int* map, int count);
Texture* mTexture;
Image* mImage;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f08b5ca..23b5d76 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -47,11 +47,13 @@
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
-Caches::Caches(): Singleton<Caches>(), mExtensions(Extensions::getInstance()), mInitialized(false) {
+Caches::Caches(): Singleton<Caches>(),
+ mExtensions(Extensions::getInstance()), mInitialized(false) {
init();
initFont();
initConstraints();
initProperties();
+ initStaticProperties();
initExtensions();
mDebugLevel = readDebugLevel();
@@ -99,6 +101,8 @@
mInitialized = true;
+ resetBoundTextures();
+
return true;
}
@@ -137,6 +141,18 @@
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
}
+void Caches::initStaticProperties() {
+ gpuPixelBuffersEnabled = false;
+
+ // OpenGL ES 3.0+ specific features
+ if (mExtensions.getMajorGlVersion() >= 3) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "true") > 0) {
+ gpuPixelBuffersEnabled = !strcmp(property, "true");
+ }
+ }
+}
+
bool Caches::initProperties() {
bool prevDebugLayersUpdates = debugLayersUpdates;
bool prevDebugOverdraw = debugOverdraw;
@@ -478,6 +494,24 @@
}
}
+void Caches::bindTexture(GLuint texture) {
+ if (mBoundTextures[mTextureUnit] != texture) {
+ glBindTexture(GL_TEXTURE_2D, texture);
+ mBoundTextures[mTextureUnit] = texture;
+ }
+}
+
+void Caches::bindTexture(GLenum target, GLuint texture) {
+ if (mBoundTextures[mTextureUnit] != texture) {
+ glBindTexture(target, texture);
+ mBoundTextures[mTextureUnit] = texture;
+ }
+}
+
+void Caches::resetBoundTextures() {
+ memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint));
+}
+
///////////////////////////////////////////////////////////////////////////////
// Scissor
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 18aeeab..bd31ec3 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -55,6 +55,7 @@
// Globals
///////////////////////////////////////////////////////////////////////////////
+// GL ES 2.0 defines that at least 16 texture units must be supported
#define REQUIRED_TEXTURE_UNITS_COUNT 3
#define REGION_MESH_QUAD_COUNT 512
@@ -79,6 +80,7 @@
static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
static const GLsizei gMeshCount = 4;
+// Must define as many texture units as specified by REQUIRED_TEXTURE_UNITS_COUNT
static const GLenum gTextureUnits[] = {
GL_TEXTURE0,
GL_TEXTURE1,
@@ -223,6 +225,22 @@
void activeTexture(GLuint textureUnit);
/**
+ * Binds the specified texture as a GL_TEXTURE_2D texture.
+ */
+ void bindTexture(GLuint texture);
+
+ /**
+ * Binds the specified texture..
+ */
+ void bindTexture(GLenum target, GLuint texture);
+
+ /**
+ * Signals that the cache of bound textures should be cleared.
+ * Other users of the context may have altered which textures are bound.
+ */
+ void resetBoundTextures();
+
+ /**
* Sets the scissor for the current surface.
*/
bool setScissor(GLint x, GLint y, GLint width, GLint height);
@@ -302,6 +320,8 @@
AssetAtlas assetAtlas;
+ bool gpuPixelBuffersEnabled;
+
// Debug methods
PFNGLINSERTEVENTMARKEREXTPROC eventMark;
PFNGLPUSHGROUPMARKEREXTPROC startMark;
@@ -314,6 +334,7 @@
void initFont();
void initExtensions();
void initConstraints();
+ void initStaticProperties();
static void eventMarkNull(GLsizei length, const GLchar* marker) { }
static void startMarkNull(GLsizei length, const GLchar* marker) { }
@@ -360,6 +381,8 @@
bool mInitialized;
uint32_t mFunctorsCount;
+
+ GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT];
}; // class Caches
}; // namespace uirenderer
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 5f84329..97c34dc 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -129,7 +129,12 @@
void setName(const char* name) {
if (name) {
- mName.setTo(name);
+ char* lastPeriod = strrchr(name, '.');
+ if (lastPeriod) {
+ mName.setTo(lastPeriod + 1);
+ } else {
+ mName.setTo(name);
+ }
}
}
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index 19b3849..4dc85e0 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -24,12 +24,15 @@
// Lifecycle
///////////////////////////////////////////////////////////////////////////////
+Dither::Dither(): mCaches(NULL), mInitialized(false), mDitherTexture(0) {
+}
+
void Dither::bindDitherTexture() {
if (!mInitialized) {
bool useFloatTexture = Extensions::getInstance().getMajorGlVersion() >= 3;
glGenTextures(1, &mDitherTexture);
- glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+ mCaches->bindTexture(mDitherTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -68,7 +71,7 @@
mInitialized = true;
} else {
- glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+ mCaches->bindTexture(mDitherTexture);
}
}
@@ -84,8 +87,10 @@
///////////////////////////////////////////////////////////////////////////////
void Dither::setupProgram(Program* program, GLuint* textureUnit) {
+ if (!mCaches) mCaches = &Caches::getInstance();
+
GLuint textureSlot = (*textureUnit)++;
- Caches::getInstance().activeTexture(textureSlot);
+ mCaches->activeTexture(textureSlot);
bindDitherTexture();
diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h
index 4d1f921..546236be 100644
--- a/libs/hwui/Dither.h
+++ b/libs/hwui/Dither.h
@@ -24,9 +24,7 @@
namespace android {
namespace uirenderer {
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
+class Caches;
// Must be a power of two
#define DITHER_KERNEL_SIZE 4
@@ -39,7 +37,7 @@
*/
class Dither {
public:
- Dither(): mInitialized(false), mDitherTexture(0) { }
+ Dither();
void clear();
void setupProgram(Program* program, GLuint* textureUnit);
@@ -47,6 +45,7 @@
private:
void bindDitherTexture();
+ Caches* mCaches;
bool mInitialized;
GLuint mDitherTexture;
};
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index a9bf13e..3e3d882 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -376,7 +376,7 @@
if (cacheTexture->getTextureId() != lastTextureId) {
lastTextureId = cacheTexture->getTextureId();
caches.activeTexture(0);
- glBindTexture(GL_TEXTURE_2D, lastTextureId);
+ caches.bindTexture(lastTextureId);
}
if (cacheTexture->upload()) {
@@ -429,7 +429,7 @@
first = false;
}
- glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
+ caches.bindTexture(texture->getTextureId());
texture->setLinearFiltering(mLinearFiltering, false);
TextureVertex* mesh = texture->mesh();
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 507ed95..1ed04fa 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -173,7 +173,7 @@
GradientInfo info;
getGradientInfo(colors, count, info);
- Texture* texture = new Texture;
+ Texture* texture = new Texture();
texture->width = info.width;
texture->height = 2;
texture->blend = info.hasAlpha;
@@ -286,7 +286,7 @@
memcpy(pixels + rowBytes, pixels, rowBytes);
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
if (mUseFloatTexture) {
diff --git a/libs/hwui/Image.cpp b/libs/hwui/Image.cpp
index 35ca40d..77c2300 100644
--- a/libs/hwui/Image.cpp
+++ b/libs/hwui/Image.cpp
@@ -18,6 +18,7 @@
#include <utils/Log.h>
+#include "Caches.h"
#include "Image.h"
namespace android {
@@ -38,7 +39,7 @@
} else {
// Create a 2D texture to sample from the EGLImage
glGenTextures(1, &mTexture);
- glBindTexture(GL_TEXTURE_2D, mTexture);
+ Caches::getInstance().bindTexture(mTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
GLenum status = GL_NO_ERROR;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 4adad05..60c38ba 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -28,7 +28,8 @@
namespace android {
namespace uirenderer {
-Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
+Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
+ caches(Caches::getInstance()), texture(caches) {
mesh = NULL;
meshIndices = NULL;
meshElementCount = 0;
@@ -47,11 +48,11 @@
debugDrawUpdate = false;
hasDrawnSinceUpdate = false;
deferredList = NULL;
- Caches::getInstance().resourceCache.incrementRefcount(this);
+ caches.resourceCache.incrementRefcount(this);
}
Layer::~Layer() {
- if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+ if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter);
removeFbo();
deleteTexture();
@@ -76,7 +77,7 @@
return true;
}
- const uint32_t maxTextureSize = Caches::getInstance().maxTextureSize;
+ const uint32_t maxTextureSize = caches.maxTextureSize;
if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
desiredWidth, desiredHeight, maxTextureSize, maxTextureSize);
@@ -89,7 +90,7 @@
setSize(desiredWidth, desiredHeight);
if (fbo) {
- Caches::getInstance().activeTexture(0);
+ caches.activeTexture(0);
bindTexture();
allocateTexture();
@@ -120,14 +121,14 @@
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
- Caches::getInstance().renderBufferCache.put(stencil);
+ caches.renderBufferCache.put(stencil);
stencil = NULL;
}
if (fbo) {
if (flush) LayerRenderer::flushLayer(this);
// If put fails the cache will delete the FBO
- Caches::getInstance().fboCache.put(fbo);
+ caches.fboCache.put(fbo);
fbo = 0;
}
}
@@ -138,11 +139,51 @@
void Layer::setColorFilter(SkiaColorFilter* filter) {
if (colorFilter) {
- Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+ caches.resourceCache.decrementRefcount(colorFilter);
}
colorFilter = filter;
if (colorFilter) {
- Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
+ caches.resourceCache.incrementRefcount(colorFilter);
+ }
+}
+
+void Layer::bindTexture() const {
+ if (texture.id) {
+ caches.bindTexture(renderTarget, texture.id);
+ }
+}
+
+void Layer::bindStencilRenderBuffer() const {
+ if (stencil) {
+ stencil->bind();
+ }
+}
+
+void Layer::generateTexture() {
+ if (!texture.id) {
+ glGenTextures(1, &texture.id);
+ }
+}
+
+void Layer::deleteTexture() {
+ if (texture.id) {
+ glDeleteTextures(1, &texture.id);
+ texture.id = 0;
+ }
+}
+
+void Layer::clearTexture() {
+ texture.id = 0;
+}
+
+void Layer::allocateTexture() {
+#if DEBUG_LAYERS
+ ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
+#endif
+ if (texture.id) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 7186603..326b25a 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -40,6 +40,7 @@
///////////////////////////////////////////////////////////////////////////////
// Forward declarations
+class Caches;
class OpenGLRenderer;
class DisplayList;
class DeferredDisplayList;
@@ -221,50 +222,19 @@
ANDROID_API void setColorFilter(SkiaColorFilter* filter);
- inline void bindTexture() const {
- if (texture.id) {
- glBindTexture(renderTarget, texture.id);
- }
- }
+ void bindStencilRenderBuffer() const;
- inline void bindStencilRenderBuffer() const {
- if (stencil) {
- stencil->bind();
- }
- }
-
- inline void generateTexture() {
- if (!texture.id) {
- glGenTextures(1, &texture.id);
- }
- }
-
- inline void deleteTexture() {
- if (texture.id) {
- glDeleteTextures(1, &texture.id);
- texture.id = 0;
- }
- }
+ void bindTexture() const;
+ void generateTexture();
+ void allocateTexture();
+ void deleteTexture();
/**
* When the caller frees the texture itself, the caller
* must call this method to tell this layer that it lost
* the texture.
*/
- void clearTexture() {
- texture.id = 0;
- }
-
- inline void allocateTexture() {
-#if DEBUG_LAYERS
- ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
-#endif
- if (texture.id) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
+ ANDROID_API void clearTexture();
inline mat4& getTexTransform() {
return texTransform;
@@ -320,6 +290,8 @@
bool hasDrawnSinceUpdate;
private:
+ Caches& caches;
+
/**
* Name of the FBO used to render the layer. If the name is 0
* this layer is not backed by an FBO, but a simple texture.
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 3e55fff..987daae 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -436,7 +436,7 @@
if ((error = glGetError()) != GL_NO_ERROR) goto error;
caches.activeTexture(0);
- glBindTexture(GL_TEXTURE_2D, texture);
+ caches.bindTexture(texture);
glPixelStorei(GL_PACK_ALIGNMENT, bitmap->bytesPerPixel());
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f12119a..f5343b1 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -371,6 +371,7 @@
dirtyClip();
mCaches.activeTexture(0);
+ mCaches.resetBoundTextures();
mCaches.blend = true;
glEnable(GL_BLEND);
@@ -3109,7 +3110,7 @@
void OpenGLRenderer::setupShader(SkiaShader* shader) {
mDrawModifiers.mShader = shader;
if (mDrawModifiers.mShader) {
- mDrawModifiers.mShader->set(&mCaches.textureCache, &mCaches.gradientCache);
+ mDrawModifiers.mShader->setCaches(mCaches);
}
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 6286e94..e9ea2f32 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -888,7 +888,7 @@
* prior to calling this method.
*/
inline void bindTexture(GLuint texture) {
- glBindTexture(GL_TEXTURE_2D, texture);
+ mCaches.bindTexture(texture);
}
/**
@@ -896,7 +896,7 @@
* prior to calling this method.
*/
inline void bindExternalTexture(GLuint texture) {
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
+ mCaches.bindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
}
/**
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index fdb10e2..3f6485c 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -139,7 +139,7 @@
static PathTexture* createTexture(float left, float top, float offset,
uint32_t width, uint32_t height, uint32_t id) {
- PathTexture* texture = new PathTexture();
+ PathTexture* texture = new PathTexture(Caches::getInstance());
texture->left = left;
texture->top = top;
texture->offset = offset;
@@ -300,7 +300,7 @@
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
// Textures are Alpha8
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index dd1f996..a191f0e 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -58,7 +58,7 @@
* Alpha texture used to represent a path.
*/
struct PathTexture: public Texture {
- PathTexture(): Texture() {
+ PathTexture(Caches& caches): Texture(caches) {
}
~PathTexture() {
diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp
index 8280370..29f8756 100644
--- a/libs/hwui/PixelBuffer.cpp
+++ b/libs/hwui/PixelBuffer.cpp
@@ -147,14 +147,8 @@
///////////////////////////////////////////////////////////////////////////////
PixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) {
- bool gpuBuffer = type == kBufferType_Auto && Extensions::getInstance().getMajorGlVersion() >= 3;
- if (gpuBuffer) {
- char property[PROPERTY_VALUE_MAX];
- if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "false") > 0) {
- if (!strcmp(property, "true")) {
- return new GpuPixelBuffer(format, width, height);
- }
- }
+ if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) {
+ return new GpuPixelBuffer(format, width, height);
}
return new CpuPixelBuffer(format, width, height);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 7c68b5b..dbbb956 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -123,9 +123,9 @@
/**
* Indicates whether PBOs can be used to back pixel buffers.
- * Accepted values are "true" and "false".
+ * Accepted values are "true" and "false". Default is true.
*/
-#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "hwui.use_gpu_pixel_buffers"
+#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "ro.hwui.use_gpu_pixel_buffers"
// These properties are defined in mega-bytes
#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index c38eedb..797ed10 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -69,9 +69,13 @@
mGenerationId = shader.mGenerationId;
}
+SkiaShader::SkiaShader(): mCaches(NULL) {
+}
+
SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
- mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) {
+ mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend),
+ mCaches(NULL) {
setMatrix(matrix);
mGenerationId = 0;
}
@@ -87,7 +91,7 @@
}
void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ mCaches->bindTexture(texture->id);
texture->setWrapST(wrapS, wrapT);
}
@@ -114,7 +118,7 @@
}
void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
- Texture* texture = mTextureCache->get(mBitmap);
+ Texture* texture = mCaches->textureCache.get(mBitmap);
if (!texture) return;
mTexture = texture;
@@ -229,7 +233,7 @@
GLuint textureSlot = (*textureUnit)++;
Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+ Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
// Uniforms
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -349,7 +353,7 @@
GLuint textureSlot = (*textureUnit)++;
Caches::getInstance().activeTexture(textureSlot);
- Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+ Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
// Uniforms
bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -359,7 +363,7 @@
bindUniformColor(program->getUniform("endColor"), mColors[1]);
}
- Caches::getInstance().dither.setupProgram(program, textureUnit);
+ mCaches->dither.setupProgram(program, textureUnit);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
@@ -394,12 +398,6 @@
return copy;
}
-void SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) {
- SkiaShader::set(textureCache, gradientCache);
- mFirst->set(textureCache, gradientCache);
- mSecond->set(textureCache, gradientCache);
-}
-
void SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) {
mFirst->describe(description, extensions);
mSecond->describe(description, extensions);
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index bc12b0d..a63431c 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -33,6 +33,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
///////////////////////////////////////////////////////////////////////////////
// Base shader
///////////////////////////////////////////////////////////////////////////////
@@ -77,9 +79,8 @@
return mType;
}
- virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
- mTextureCache = textureCache;
- mGradientCache = gradientCache;
+ virtual void setCaches(Caches& caches) {
+ mCaches = &caches;
}
uint32_t getGenerationId() {
@@ -103,8 +104,7 @@
void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
protected:
- SkiaShader() {
- }
+ SkiaShader();
/**
* The appropriate texture unit must have been activated prior to invoking
@@ -118,8 +118,7 @@
SkShader::TileMode mTileY;
bool mBlend;
- TextureCache* mTextureCache;
- GradientCache* mGradientCache;
+ Caches* mCaches;
mat4 mUnitMatrix;
mat4 mShaderMatrix;
@@ -229,7 +228,11 @@
~SkiaComposeShader();
SkiaShader* copy();
- void set(TextureCache* textureCache, GradientCache* gradientCache);
+ void setCaches(Caches& caches) {
+ SkiaShader::setCaches(caches);
+ mFirst->setCaches(caches);
+ mSecond->setCaches(caches);
+ }
void describe(ProgramDescription& description, const Extensions& extensions);
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 6976eaa..3b6cb91 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -18,6 +18,7 @@
#include <utils/JenkinsHash.h>
+#include "Caches.h"
#include "Debug.h"
#include "TextDropShadowCache.h"
#include "Properties.h"
@@ -182,7 +183,9 @@
return NULL;
}
- texture = new ShadowTexture;
+ Caches& caches = Caches::getInstance();
+
+ texture = new ShadowTexture(caches);
texture->left = shadow.penX;
texture->top = shadow.penY;
texture->width = shadow.width;
@@ -202,7 +205,7 @@
glGenTextures(1, &texture->id);
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ caches.bindTexture(texture->id);
// Textures are Alpha8
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 0bed72b6..04d7357 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -30,6 +30,8 @@
namespace android {
namespace uirenderer {
+class Caches;
+
struct ShadowText {
ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL),
flags(0), italicStyle(0.0f), scaleX(0), text(NULL), positions(NULL) {
@@ -114,7 +116,7 @@
* Alpha texture used to represent a shadow.
*/
struct ShadowTexture: public Texture {
- ShadowTexture(): Texture() {
+ ShadowTexture(Caches& caches): Texture(caches) {
}
float left;
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
new file mode 100644
index 0000000..e06227c
--- /dev/null
+++ b/libs/hwui/Texture.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/Log.h>
+
+#include "Caches.h"
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+Texture::Texture(): id(0), generation(0), blend(false), width(0), height(0),
+ cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+ mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+ mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+ mFirstFilter(true), mFirstWrap(true), mCaches(Caches::getInstance()) {
+}
+
+Texture::Texture(Caches& caches): id(0), generation(0), blend(false), width(0), height(0),
+ cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+ mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+ mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+ mFirstFilter(true), mFirstWrap(true), mCaches(caches) {
+}
+
+void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
+ GLenum renderTarget) {
+
+ if (mFirstWrap || force || wrapS != mWrapS || wrapT != mWrapT) {
+ mFirstWrap = false;
+
+ mWrapS = wrapS;
+ mWrapT = wrapT;
+
+ if (bindTexture) {
+ mCaches.bindTexture(renderTarget, id);
+ }
+
+ glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
+ glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
+ }
+}
+
+void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force,
+ GLenum renderTarget) {
+
+ if (mFirstFilter || force || min != mMinFilter || mag != mMagFilter) {
+ mFirstFilter = false;
+
+ mMinFilter = min;
+ mMagFilter = mag;
+
+ if (bindTexture) {
+ mCaches.bindTexture(renderTarget, id);
+ }
+
+ if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
+
+ glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
+ glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
+ }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index f84cd67..d249741 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -22,81 +22,34 @@
namespace android {
namespace uirenderer {
+class Caches;
class UvMapper;
/**
* Represents an OpenGL texture.
*/
-struct Texture {
- Texture() {
- cleanup = false;
- bitmapSize = 0;
-
- wrapS = GL_CLAMP_TO_EDGE;
- wrapT = GL_CLAMP_TO_EDGE;
-
- minFilter = GL_NEAREST;
- magFilter = GL_NEAREST;
-
- mipMap = false;
-
- firstFilter = true;
- firstWrap = true;
-
- id = 0;
-
- uvMapper = NULL;
- }
+class Texture {
+public:
+ Texture();
+ Texture(Caches& caches);
virtual ~Texture() { }
- void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
+ inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
setWrapST(wrap, wrap, bindTexture, force, renderTarget);
}
virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
- bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
- if (firstWrap || force || wrapS != this->wrapS || wrapT != this->wrapT) {
- firstWrap = false;
-
- this->wrapS = wrapS;
- this->wrapT = wrapT;
-
- if (bindTexture) {
- glBindTexture(renderTarget, id);
- }
-
- glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
- glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
- }
- }
-
- void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
+ inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
}
virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
- bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
-
- if (firstFilter || force || min != minFilter || mag != magFilter) {
- firstFilter = false;
-
- minFilter = min;
- magFilter = mag;
-
- if (bindTexture) {
- glBindTexture(renderTarget, id);
- }
-
- if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
-
- glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
- glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
- }
- }
+ bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
/**
* Name of the texture.
@@ -140,17 +93,19 @@
/**
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
*/
- GLenum wrapS;
- GLenum wrapT;
+ GLenum mWrapS;
+ GLenum mWrapT;
/**
* Last filters set on this texture. Defaults to GL_NEAREST.
*/
- GLenum minFilter;
- GLenum magFilter;
+ GLenum mMinFilter;
+ GLenum mMagFilter;
- bool firstFilter;
- bool firstWrap;
+ bool mFirstFilter;
+ bool mFirstWrap;
+
+ Caches& mCaches;
}; // struct Texture
class AutoTexture {
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 2378eb5..7f5b80f 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -139,7 +139,7 @@
}
}
- texture = new Texture;
+ texture = new Texture();
texture->bitmapSize = size;
generateTexture(bitmap, texture, false);
@@ -162,7 +162,7 @@
}
Texture* TextureCache::getTransient(SkBitmap* bitmap) {
- Texture* texture = new Texture;
+ Texture* texture = new Texture();
texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
texture->cleanup = true;
@@ -235,7 +235,7 @@
texture->width = bitmap->width();
texture->height = bitmap->height();
- glBindTexture(GL_TEXTURE_2D, texture->id);
+ Caches::getInstance().bindTexture(texture->id);
switch (bitmap->getConfig()) {
case SkBitmap::kA8_Config:
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 6c5267d..2d58338 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -17,6 +17,7 @@
#include <SkGlyph.h>
#include "CacheTexture.h"
+#include "../Caches.h"
#include "../Debug.h"
#include "../Extensions.h"
#include "../PixelBuffer.h"
@@ -110,7 +111,8 @@
CacheTexture::CacheTexture(uint16_t width, uint16_t height, uint32_t maxQuadCount) :
mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height),
mLinearFiltering(false), mDirty(false), mNumGlyphs(0),
- mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount) {
+ mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount),
+ mCaches(Caches::getInstance()) {
mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
@@ -166,7 +168,7 @@
mLinearFiltering = linearFiltering;
const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
- if (bind) glBindTexture(GL_TEXTURE_2D, getTextureId());
+ if (bind) mCaches.bindTexture(getTextureId());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
}
@@ -186,7 +188,7 @@
if (!mTextureId) {
glGenTextures(1, &mTextureId);
- glBindTexture(GL_TEXTURE_2D, mTextureId);
+ mCaches.bindTexture(mTextureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Initialize texture dimensions
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mWidth, mHeight, 0,
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index ddcc836..8c3ea0b 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -30,6 +30,7 @@
namespace android {
namespace uirenderer {
+class Caches;
class PixelBuffer;
/**
@@ -178,9 +179,10 @@
TextureVertex* mMesh;
uint32_t mCurrentQuad;
uint32_t mMaxQuadCount;
+ Caches& mCaches;
CacheBlock* mCacheBlocks;
- Rect mDirtyRect;
bool mHasES3;
+ Rect mDirtyRect;
};
}; // namespace uirenderer
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 33ba229..9e13ca4 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -71,7 +71,9 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.Surface;
import android.view.VolumePanel;
+import android.view.WindowManager;
import com.android.internal.telephony.ITelephony;
import com.android.internal.util.XmlUtils;
@@ -431,6 +433,7 @@
private volatile IRingtonePlayer mRingtonePlayer;
private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
+ private int mDeviceRotation = Surface.ROTATION_0;
// Request to override default use of A2DP for media.
private boolean mBluetoothA2dpEnabled;
@@ -452,7 +455,9 @@
AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET |
AudioSystem.DEVICE_OUT_ALL_USB;
+ // TODO merge orientation and rotation
private final boolean mMonitorOrientation;
+ private final boolean mMonitorRotation;
private boolean mDockAudioMediaEnabled = true;
@@ -545,14 +550,21 @@
intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- // Register a configuration change listener only if requested by system properties
- // to monitor orientation changes (off by default)
+ // TODO merge orientation and rotation
mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false);
if (mMonitorOrientation) {
Log.v(TAG, "monitoring device orientation");
// initialize orientation in AudioSystem
setOrientationForAudioSystem();
}
+ mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
+ if (mMonitorRotation) {
+ mDeviceRotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay().getRotation();
+ Log.v(TAG, "monitoring device rotation, initial=" + mDeviceRotation);
+ // initialize rotation in AudioSystem
+ setRotationForAudioSystem();
+ }
context.registerReceiver(mReceiver, intentFilter);
@@ -3497,6 +3509,9 @@
if (mMonitorOrientation) {
setOrientationForAudioSystem();
}
+ if (mMonitorRotation) {
+ setRotationForAudioSystem();
+ }
synchronized (mBluetoothA2dpEnabledLock) {
AudioSystem.setForceUse(AudioSystem.FOR_MEDIA,
@@ -6375,15 +6390,17 @@
// Device orientation
//==========================================================================================
/**
- * Handles device configuration changes that may map to a change in the orientation.
- * This feature is optional, and is defined by the definition and value of the
- * "ro.audio.monitorOrientation" system property.
+ * Handles device configuration changes that may map to a change in the orientation
+ * or orientation.
+ * Monitoring orientation and rotation is optional, and is defined by the definition and value
+ * of the "ro.audio.monitorOrientation" and "ro.audio.monitorRotation" system properties.
*/
private void handleConfigurationChanged(Context context) {
try {
// reading new orientation "safely" (i.e. under try catch) in case anything
// goes wrong when obtaining resources and configuration
Configuration config = context.getResources().getConfiguration();
+ // TODO merge rotation and orientation
if (mMonitorOrientation) {
int newOrientation = config.orientation;
if (newOrientation != mDeviceOrientation) {
@@ -6391,6 +6408,14 @@
setOrientationForAudioSystem();
}
}
+ if (mMonitorRotation) {
+ int newRotation = ((WindowManager) context.getSystemService(
+ Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
+ if (newRotation != mDeviceRotation) {
+ mDeviceRotation = newRotation;
+ setRotationForAudioSystem();
+ }
+ }
sendMsg(mAudioHandler,
MSG_CONFIGURE_SAFE_MEDIA_VOLUME,
SENDMSG_REPLACE,
@@ -6439,7 +6464,7 @@
}
mVolumePanel.setLayoutDirection(config.getLayoutDirection());
} catch (Exception e) {
- Log.e(TAG, "Error retrieving device orientation: " + e);
+ Log.e(TAG, "Error handling configuration change: ", e);
}
}
@@ -6466,6 +6491,25 @@
}
}
+ private void setRotationForAudioSystem() {
+ switch (mDeviceRotation) {
+ case Surface.ROTATION_0:
+ AudioSystem.setParameters("rotation=0");
+ break;
+ case Surface.ROTATION_90:
+ AudioSystem.setParameters("rotation=90");
+ break;
+ case Surface.ROTATION_180:
+ AudioSystem.setParameters("rotation=180");
+ break;
+ case Surface.ROTATION_270:
+ AudioSystem.setParameters("rotation=270");
+ break;
+ default:
+ Log.e(TAG, "Unknown device rotation");
+ }
+ }
+
// Handles request to override default use of A2DP for media.
public void setBluetoothA2dpOnInt(boolean on) {
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index c0fbd2e..774964e 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -35,20 +35,29 @@
* It is generally used like this:
*
* <pre>
- * MediaMuxer muxer = new MediaMuxer(...);
+ * MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
+ * // More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
+ * // or MediaExtractor.getTrackFormat().
* MediaFormat audioFormat = new MediaFormat(...);
* MediaFormat videoFormat = new MediaFormat(...);
* int audioTrackIndex = muxer.addTrack(audioFormat);
* int videoTrackIndex = muxer.addTrack(videoFormat);
- * ByteBuffer inputBuffer = ByteBuffer.allocate(...);
+ * ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
+ * boolean finished = false;
+ * BufferInfo bufferInfo = new BufferInfo();
+ *
* muxer.start();
- * while(inputBuffer has new data) {
- * if (new data is audio sample) {
- * muxer.writeSampleData(audioTrackIndex, inputBuffer, ...);
- * } else if (new data is video sample) {
- * muxer.writeSampleData(videoTrackIndex, inputBuffer, ...);
+ * while(!finished) {
+ * // getInputBuffer() will fill the inputBuffer with one frame of encoded
+ * // sample from either MediaCodec or MediaExtractor, set isAudioSample to
+ * // true when the sample is audio data, set up all the fields of bufferInfo,
+ * // and return true if there are no more samples.
+ * finished = getInputBuffer(inputBuffer, isAudioSample, bufferInfo);
+ * if (!finished) {
+ * int currentTrackIndex = isAudioSample ? audioTrackIndex : videoTrackIndex;
+ * muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
* }
- * }
+ * };
* muxer.stop();
* muxer.release();
* </pre>
@@ -74,16 +83,6 @@
public static final int MUXER_OUTPUT_MPEG_4 = 0;
};
- /**
- * The sample is a sync sample, which does not require other video samples
- * to decode. This flag is used in {@link #writeSampleData} to indicate
- * which sample is a sync sample.
- */
- /* Keep this flag in sync with its equivalent in
- * include/media/stagefright/MediaMuxer.h.
- */
- public static final int SAMPLE_FLAG_SYNC = 1;
-
// All the native functions are listed here.
private static native int nativeSetup(FileDescriptor fd, int format);
private static native void nativeRelease(int nativeObject);
@@ -260,10 +259,13 @@
* Writes an encoded sample into the muxer.
* <p>The application needs to make sure that the samples are written into
* the right tracks. Also, it needs to make sure the samples for each track
- * are written in chronological order.</p>
+ * are written in chronological order (e.g. in the order they are provided
+ * by the encoder.)</p>
* @param byteBuf The encoded sample.
* @param trackIndex The track index for this sample.
* @param bufferInfo The buffer information related to this sample.
+ * MediaMuxer uses the flags provided in {@link MediaCodec.BufferInfo},
+ * to signal sync frames.
*/
public void writeSampleData(int trackIndex, ByteBuffer byteBuf,
BufferInfo bufferInfo) {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index f745163..b729640 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -16,9 +16,14 @@
package android.media;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
+import android.net.Proxy;
+import android.net.ProxyProperties;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -864,6 +869,7 @@
*/
public void setDataSource(Context context, Uri uri, Map<String, String> headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ disableProxyListener();
String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) {
@@ -896,8 +902,13 @@
}
Log.d(TAG, "Couldn't open file on client side, trying server side");
+
setDataSource(uri.toString(), headers);
- return;
+
+ if (scheme.equalsIgnoreCase("http")
+ || scheme.equalsIgnoreCase("https")) {
+ setupProxyListener(context);
+ }
}
/**
@@ -948,6 +959,8 @@
private void setDataSource(String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ disableProxyListener();
+
final Uri uri = Uri.parse(path);
if ("file".equals(uri.getScheme())) {
path = uri.getPath();
@@ -991,7 +1004,13 @@
* @param length the length in bytes of the data to be played
* @throws IllegalStateException if it is called in an invalid state
*/
- public native void setDataSource(FileDescriptor fd, long offset, long length)
+ public void setDataSource(FileDescriptor fd, long offset, long length)
+ throws IOException, IllegalArgumentException, IllegalStateException {
+ disableProxyListener();
+ _setDataSource(fd, offset, length);
+ }
+
+ private native void _setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException;
/**
@@ -1332,6 +1351,8 @@
_reset();
// make sure none of the listeners get called anymore
mEventHandler.removeCallbacksAndMessages(null);
+
+ disableProxyListener();
}
private native void _reset();
@@ -2449,4 +2470,57 @@
return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
}
+
+ private Context mProxyContext = null;
+ private ProxyReceiver mProxyReceiver = null;
+
+ private void setupProxyListener(Context context) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Proxy.PROXY_CHANGE_ACTION);
+ mProxyReceiver = new ProxyReceiver();
+ mProxyContext = context;
+
+ Intent currentProxy =
+ context.getApplicationContext().registerReceiver(mProxyReceiver, filter);
+
+ if (currentProxy != null) {
+ handleProxyBroadcast(currentProxy);
+ }
+ }
+
+ private void disableProxyListener() {
+ if (mProxyReceiver == null) {
+ return;
+ }
+
+ Context appContext = mProxyContext.getApplicationContext();
+ if (appContext != null) {
+ appContext.unregisterReceiver(mProxyReceiver);
+ }
+
+ mProxyReceiver = null;
+ mProxyContext = null;
+ }
+
+ private void handleProxyBroadcast(Intent intent) {
+ ProxyProperties props =
+ (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
+
+ if (props == null || props.getHost() == null) {
+ updateProxyConfig(null);
+ } else {
+ updateProxyConfig(props);
+ }
+ }
+
+ private class ProxyReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
+ handleProxyBroadcast(intent);
+ }
+ }
+ }
+
+ private native void updateProxyConfig(ProxyProperties props);
}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index e6693b9..d653d94 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -231,7 +231,7 @@
final int count = mCallbacks.size();
for (int i = 0; i < count; i++) {
CallbackInfo cbi = mCallbacks.get(i);
- if ((cbi.flags & CALLBACK_FLAG_ACTIVE_SCAN) != 0
+ if ((cbi.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0
&& (cbi.type & type) != 0) {
return true;
}
@@ -330,7 +330,7 @@
* discover and select a new route.
* </p>
*/
- public static final int CALLBACK_FLAG_ACTIVE_SCAN = 1 << 0;
+ public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1 << 0;
/**
* Flag for {@link #addCallback}: Do not filter route events.
@@ -439,7 +439,7 @@
* @param types Types of routes this callback is interested in
* @param cb Callback to add
* @param flags Flags to control the behavior of the callback.
- * May be zero or a combination of {@link #CALLBACK_FLAG_ACTIVE_SCAN} and
+ * May be zero or a combination of {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} and
* {@link #CALLBACK_FLAG_UNFILTERED_EVENTS}.
*/
public void addCallback(int types, Callback cb, int flags) {
@@ -453,7 +453,7 @@
info = new CallbackInfo(cb, types, flags, this);
sStatic.mCallbacks.add(info);
}
- if ((info.flags & CALLBACK_FLAG_ACTIVE_SCAN) != 0) {
+ if ((info.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
sStatic.updateActiveScan();
}
}
@@ -467,7 +467,7 @@
int index = findCallbackInfo(cb);
if (index >= 0) {
CallbackInfo info = sStatic.mCallbacks.remove(index);
- if ((info.flags & CALLBACK_FLAG_ACTIVE_SCAN) != 0) {
+ if ((info.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
sStatic.updateActiveScan();
}
} else {
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 031326e..52c0c2d 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -193,10 +193,14 @@
* The effect descriptor contains information on a particular effect implemented in the
* audio framework:<br>
* <ul>
- * <li>type: UUID identifying the effect type</li>
+ * <li>type: UUID identifying the effect type. May be one of:
+ * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
+ * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
+ * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
+ * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
+ * </li>
* <li>uuid: UUID for this particular implementation</li>
- * <li>connectMode: {@link #EFFECT_INSERT}, {@link #EFFECT_AUXILIARY} or
- * {at_link #EFFECT_PRE_PROCESSING}</li>
+ * <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
* <li>name: human readable effect name</li>
* <li>implementor: human readable effect implementor name</li>
* </ul>
@@ -208,6 +212,19 @@
public Descriptor() {
}
+ /**
+ * @param type UUID identifying the effect type. May be one of:
+ * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
+ * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
+ * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
+ * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
+ * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
+ * @param uuid UUID for this particular implementation
+ * @param connectMode {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
+ * @param name human readable effect name
+ * @param implementor human readable effect implementor name
+ *
+ */
public Descriptor(String type, String uuid, String connectMode,
String name, String implementor) {
this.type = UUID.fromString(type);
@@ -234,13 +251,14 @@
*/
public UUID uuid;
/**
- * Indicates if the effect is of insert category {@link #EFFECT_INSERT}, auxiliary
- * category {@link #EFFECT_AUXILIARY} or pre processing category
- * {at_link #EFFECT_PRE_PROCESSING}. Insert effects (Typically an Equalizer) are applied
+ * Indicates if the effect is of insert category {@link #EFFECT_INSERT} or auxiliary
+ * category {@link #EFFECT_AUXILIARY}.
+ * Insert effects (typically an {@link Equalizer}) are applied
* to the entire audio source and usually not shared by several sources. Auxiliary effects
* (typically a reverberator) are applied to part of the signal (wet) and the effect output
* is added to the original signal (dry).
- * Audio pre processing are applied to audio captured on a particular AudioRecord.
+ * Audio pre processing are applied to audio captured on a particular
+ * {@link android.media.AudioRecord}.
*/
public String connectMode;
/**
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index c5098ce..7c607ea 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -55,6 +55,10 @@
jfieldID surface_texture;
jmethodID post_event;
+
+ jmethodID proxyConfigGetHost;
+ jmethodID proxyConfigGetPort;
+ jmethodID proxyConfigGetExclusionList;
};
static fields_t fields;
@@ -622,6 +626,20 @@
if (fields.surface_texture == NULL) {
return;
}
+
+ clazz = env->FindClass("android/net/ProxyProperties");
+ if (clazz == NULL) {
+ return;
+ }
+
+ fields.proxyConfigGetHost =
+ env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
+
+ fields.proxyConfigGetPort =
+ env->GetMethodID(clazz, "getPort", "()I");
+
+ fields.proxyConfigGetExclusionList =
+ env->GetMethodID(clazz, "getExclusionList", "()Ljava/lang/String;");
}
static void
@@ -823,6 +841,49 @@
;
}
+static void
+android_media_MediaPlayer_updateProxyConfig(
+ JNIEnv *env, jobject thiz, jobject proxyProps)
+{
+ ALOGV("updateProxyConfig");
+ sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
+ if (thisplayer == NULL) {
+ return;
+ }
+
+ if (proxyProps == NULL) {
+ thisplayer->updateProxyConfig(
+ NULL /* host */, 0 /* port */, NULL /* exclusionList */);
+ } else {
+ jstring hostObj = (jstring)env->CallObjectMethod(
+ proxyProps, fields.proxyConfigGetHost);
+
+ const char *host = env->GetStringUTFChars(hostObj, NULL);
+
+ int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
+
+ jstring exclusionListObj = (jstring)env->CallObjectMethod(
+ proxyProps, fields.proxyConfigGetExclusionList);
+
+ const char *exclusionList =
+ env->GetStringUTFChars(exclusionListObj, NULL);
+
+ if (host != NULL && exclusionListObj != NULL) {
+ thisplayer->updateProxyConfig(host, port, exclusionList);
+ }
+
+ if (exclusionList != NULL) {
+ env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
+ exclusionList = NULL;
+ }
+
+ if (host != NULL) {
+ env->ReleaseStringUTFChars(hostObj, host);
+ host = NULL;
+ }
+ }
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -832,7 +893,7 @@
(void *)android_media_MediaPlayer_setDataSourceAndHeaders
},
- {"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
+ {"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
{"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
{"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
@@ -867,6 +928,7 @@
{"getParameter", "(ILandroid/os/Parcel;)V", (void *)android_media_MediaPlayer_getParameter},
{"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I", (void *)android_media_MediaPlayer_setRetransmitEndpoint},
{"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer},
+ {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
};
static const char* const kClassPathName = "android/media/MediaPlayer";
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java
index fa59fa4..23b9705 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraStressTestRunner.java
@@ -19,6 +19,8 @@
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.CameraStressTest;
+import com.android.mediaframeworktest.functional.camera.CameraFunctionalTest;
+import com.android.mediaframeworktest.functional.camera.CameraPairwiseTest;
import junit.framework.TestSuite;
@@ -28,6 +30,8 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(CameraStressTest.class);
+ suite.addTestSuite(CameraFunctionalTest.class);
+ suite.addTestSuite(CameraPairwiseTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraTestHelper.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraTestHelper.java
new file mode 100644
index 0000000..8bf741c
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/CameraTestHelper.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2013 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.mediaframeworktest;
+
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.PictureCallback;
+import android.hardware.Camera.ShutterCallback;
+import android.os.Environment;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+public class CameraTestHelper {
+
+ public Camera mCamera;
+ private String TAG = "CameraTestHelper";
+ private static final int CAMERA_ID = 0;
+ private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
+ private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds
+ protected static final String CAMERA_STRESS_IMAGES_DIRECTORY = "cameraStressImages";
+ private static final String CAMERA_STRESS_IMAGES_PREFIX = "camera-stress-test";
+ private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
+
+ private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
+ public void onError(int error, android.hardware.Camera camera) {
+ Assert.fail(String.format("Camera error, code: %d", error));
+ }
+ }
+
+ private ShutterCallback shutterCallback = new ShutterCallback() {
+ @Override
+ public void onShutter() {
+ Log.v(TAG, "Shutter");
+ }
+ };
+
+ private PictureCallback rawCallback = new PictureCallback() {
+ @Override
+ public void onPictureTaken(byte[] data, Camera camera) {
+ Log.v(TAG, "Raw picture taken");
+ }
+ };
+
+ private PictureCallback jpegCallback = new PictureCallback() {
+ @Override
+ public void onPictureTaken(byte[] data, Camera camera) {
+ FileOutputStream fos = null;
+
+ try {
+ Log.v(TAG, "JPEG picture taken");
+ fos = new FileOutputStream(String.format("%s/%s/%s-%d.jpg",
+ Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY,
+ CAMERA_STRESS_IMAGES_PREFIX, System.currentTimeMillis()));
+ fos.write(data);
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "File not found: " + e.toString());
+ } catch (IOException e) {
+ Log.e(TAG, "Error accessing file: " + e.toString());
+ } finally {
+ try {
+ if (fos != null) {
+ fos.close();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Error closing file: " + e.toString());
+ }
+ }
+ }
+ };
+
+ /**
+ * Helper method for prepping test
+ */
+ public void setupCameraTest() {
+ // Create the test images directory if it doesn't exist
+ File stressImagesDirectory = new File(String.format("%s/%s",
+ Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
+ if (!stressImagesDirectory.exists()) {
+ stressImagesDirectory.mkdir();
+ }
+
+ mCamera = Camera.open(CAMERA_ID);
+ }
+
+ /**
+ * Helper method for getting the available parameters of the default camera
+ */
+ public Parameters getCameraParameters() {
+ mCamera = Camera.open(CAMERA_ID);
+ Parameters params = mCamera.getParameters();
+ mCamera.release();
+ return params;
+ }
+
+ /**
+ * Helper method for taking a photo
+ */
+ public void capturePhoto() throws Exception {
+ mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
+ Thread.sleep(WAIT_GENERIC);
+ mCamera.stopPreview();
+ mCamera.release();
+ }
+
+ /**
+ * Helper method for cleaning up pics taken during tests
+ */
+ public void cleanupTestImages() {
+ try {
+ File stressImagesDirectory = new File(String.format("%s/%s",
+ Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
+ File[] stressImages = stressImagesDirectory.listFiles();
+ for (File f : stressImages) {
+ f.delete();
+ }
+ } catch (SecurityException e) {
+ Log.e(TAG, "Security manager access violation: " + e.toString());
+ }
+ }
+
+ /**
+ * Helper method for setting the camera parameters
+ */
+ public void setParameters(Parameters params) {
+ try {
+ mCamera.setParameters(params);
+ } catch (Exception e) {
+ Log.e(TAG, "Error setting camera parameters");
+ }
+ }
+
+ /**
+ * Helper method for starting up the camera preview
+ */
+ public void startCameraPreview(SurfaceHolder surfaceHolder) throws Exception {
+ mCamera.setErrorCallback(mCameraErrorCallback);
+ mCamera.setPreviewDisplay(surfaceHolder);
+ mCamera.startPreview();
+ Thread.sleep(WAIT_GENERIC);
+ }
+}
+
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
index ed9bb97..10df2e6 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
@@ -48,9 +48,9 @@
import java.io.FileDescriptor;
import java.net.InetAddress;
-
+
public class MediaFrameworkTest extends Activity implements SurfaceHolder.Callback {
-
+
//public static Surface video_sf;
public static SurfaceView mSurfaceView;
private MediaController mMediaController;
@@ -58,10 +58,10 @@
private MediaPlayer mpmidi;
private MediaPlayer mpmp3;
private String testfilepath = "/sdcard/awb.awb";
-
+
public static AssetFileDescriptor midiafd;
public static AssetFileDescriptor mp3afd;
-
+
public static Bitmap mDestBitmap;
public static ImageView mOverlayView;
private SurfaceHolder mSurfaceHolder = null;
@@ -82,10 +82,10 @@
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(this);
-
+
//Get the midi fd
midiafd = this.getResources().openRawResourceFd(R.raw.testmidi);
-
+
//Get the mp3 fd
mp3afd = this.getResources().openRawResourceFd(R.raw.testmp3);
mOverlayView.setLayoutParams(lp);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
new file mode 100644
index 0000000..e6f0aaf
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 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.mediaframeworktest.functional.camera;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.CameraTestHelper;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import com.android.mediaframeworktest.CameraStressTestRunner;
+
+import junit.framework.Assert;
+
+/**
+ * Junit / Instrumentation test case for the following camera APIs:
+ * - flash
+ * - exposure compensation
+ * - white balance
+ * - focus mode
+ *
+ * adb shell am instrument
+ * -e class com.android.mediaframeworktest.functional.camera.CameraFunctionalTest
+ * -w com.android.mediaframework/.CameraStressTestRunner
+ */
+public class CameraFunctionalTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
+ private CameraTestHelper mCameraTestHelper;
+ private Handler mHandler;
+ private Thread mLooperThread;
+ private Writer mOutput;
+
+ private String TAG = "CameraFunctionalTest";
+
+ public CameraFunctionalTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ final Semaphore sem = new Semaphore(0);
+ mLooperThread = new Thread() {
+ @Override
+ public void run() {
+ Log.v(TAG, "starting looper");
+ Looper.prepare();
+ mHandler = new Handler();
+ sem.release();
+ Looper.loop();
+ Log.v(TAG, "quit looper");
+ }
+ };
+ mLooperThread.start();
+ if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to start the looper.");
+ }
+ getActivity();
+ super.setUp();
+
+ mCameraTestHelper = new CameraTestHelper();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHandler != null) {
+ mHandler.getLooper().quit();
+ mHandler = null;
+ }
+ if (mLooperThread != null) {
+ mLooperThread.join(WAIT_TIMEOUT);
+ if (mLooperThread.isAlive()) {
+ fail("Failed to stop the looper.");
+ }
+ mLooperThread = null;
+ }
+ super.tearDown();
+ }
+
+ private void runOnLooper(final Runnable command) throws InterruptedException {
+ final Semaphore sem = new Semaphore(0);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ command.run();
+ } finally {
+ sem.release();
+ }
+ }
+ });
+ if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to run the command on the looper.");
+ }
+ }
+
+ /**
+ * Functional test iterating on the range of supported exposure compensation levels
+ */
+ @LargeTest
+ public void testFunctionalCameraExposureCompensation() throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
+
+ int min = params.getMinExposureCompensation();
+ int max = params.getMaxExposureCompensation();
+ assertFalse("Adjusting exposure not supported", (max == 0 && min == 0));
+ float step = params.getExposureCompensationStep();
+ int stepsPerEV = (int) Math.round(Math.pow((double) step, -1));
+
+ // only get integer values for exposure compensation
+ for (int i = min; i <= max; i += stepsPerEV) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+ Log.v(TAG, "Setting exposure compensation index to " + i);
+ params.setExposureCompensation(i);
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
+ }
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Camera exposure compensation test Exception");
+ }
+ }
+
+ /**
+ * Functional test iterating on the various flash modes (on, off, auto, torch)
+ */
+ @LargeTest
+ public void testFunctionalCameraFlashModes() throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
+ List<String> supportedFlashModes = params.getSupportedFlashModes();
+ assertNotNull("No flash modes supported", supportedFlashModes);
+
+ for (int i = 0; i < supportedFlashModes.size(); i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+ Log.v(TAG, "Setting flash mode to " + supportedFlashModes.get(i));
+ params.setFlashMode(supportedFlashModes.get(i));
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
+ }
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Camera flash mode test Exception");
+ }
+ }
+
+ /**
+ * Functional test iterating on the various focus modes (auto, infinitiy, macro, etc.)
+ */
+ @LargeTest
+ public void testFunctionalCameraFocusModes() throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
+ List<String> supportedFocusModes = params.getSupportedFocusModes();
+ assertNotNull("No focus modes supported", supportedFocusModes);
+
+ for (int i = 0; i < supportedFocusModes.size(); i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+ Log.v(TAG, "Setting focus mode to: " + supportedFocusModes.get(i));
+ params.setFocusMode(supportedFocusModes.get(i));
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
+ }
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Camera focus modes test Exception");
+ }
+ }
+
+ /**
+ * Functional test iterating on the various white balances (auto, daylight, cloudy, etc.)
+ */
+ @LargeTest
+ public void testFunctionalCameraWhiteBalance() throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
+ List<String> supportedWhiteBalance = params.getSupportedWhiteBalance();
+ assertNotNull("No white balance modes supported", supportedWhiteBalance);
+
+ for (int i = 0; i < supportedWhiteBalance.size(); i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+ Log.v(TAG, "Setting white balance to: " + supportedWhiteBalance.get(i));
+ params.setWhiteBalance(supportedWhiteBalance.get(i));
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
+ }
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Camera focus modes test Exception");
+ }
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
new file mode 100644
index 0000000..61b708a
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2013 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.mediaframeworktest.functional.camera;
+
+import android.hardware.Camera;
+import android.hardware.Camera.PictureCallback;
+import android.hardware.Camera.ShutterCallback;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.FloatMath;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.CameraStressTestRunner;
+import com.android.mediaframeworktest.CameraTestHelper;
+import junit.framework.Assert;
+
+/**
+ * Junit / Instrumentation test case for camera API pairwise testing
+ * Settings tested against: flash mode, exposure compensation, white balance,
+ * scene mode, picture size, and geotagging
+ *
+ * adb shell am instrument
+ * - e class com.android.mediaframeworktest.stress.CameraPairwiseTest
+ * - w com.android.mediaframeworktest/.CameraStressTestRunner
+ */
+public class CameraPairwiseTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private CameraTestHelper mCameraTestHelper;
+ private Handler mHandler;
+ private Thread mLooperThread;
+ private String TAG = "CameraPairwiseTest";
+
+ private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
+
+ // coordinates of the Getty Museuem in Los Angeles
+ private static final double MOCK_LATITUDE = 34.076621;
+ private static final double MOCK_LONGITUDE = -118.473215;
+
+ // camera setting enums
+ public enum Flash { ON, OFF, AUTO };
+ public enum Exposure { MIN, MAX, NONE };
+ public enum WhiteBalance { DAYLIGHT, FLUORESCENT, CLOUDY, INCANDESCENT, AUTO };
+ public enum SceneMode { SUNSET, ACTION, PARTY, NIGHT, AUTO };
+ public enum PictureSize { SMALL, MEDIUM, LARGE };
+ public enum Geotagging { ON, OFF };
+
+ public CameraPairwiseTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ final Semaphore sem = new Semaphore(0);
+ mLooperThread = new Thread() {
+ @Override
+ public void run() {
+ Log.v(TAG, "starting looper");
+ Looper.prepare();
+ mHandler = new Handler();
+ sem.release();
+ Looper.loop();
+ Log.v(TAG, "quit looper");
+ }
+ };
+ mLooperThread.start();
+ if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to start the looper.");
+ }
+ getActivity();
+ super.setUp();
+
+ mCameraTestHelper = new CameraTestHelper();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHandler != null) {
+ mHandler.getLooper().quit();
+ mHandler = null;
+ }
+ if (mLooperThread != null) {
+ mLooperThread.join(WAIT_TIMEOUT);
+ if (mLooperThread.isAlive()) {
+ fail("Failed to stop the looper.");
+ }
+ mLooperThread = null;
+ }
+ super.tearDown();
+ }
+
+ private void runOnLooper(final Runnable command) throws InterruptedException {
+ final Semaphore sem = new Semaphore(0);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ command.run();
+ } finally {
+ sem.release();
+ }
+ }
+ });
+ if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to run the command on the looper.");
+ }
+ }
+
+ /**
+ * Flash: Auto / Exposure: None / WB: Daylight
+ * Scene: Sunset / Pic: Medium / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario01() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: Min / WB: Fluorescent
+ * Scene: Auto / Pic: Large / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario02() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.FLUORESCENT, SceneMode.AUTO,
+ PictureSize.LARGE, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Off / Exposure: Max / WB: Auto
+ * Scene: Night / Pic: Small / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario03() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT,
+ PictureSize.SMALL, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Off / Exposure: Max / WB: Cloudy
+ * Scene: Auto / Pic: Med / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario04() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.CLOUDY, SceneMode.AUTO,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Max / WB: Incandescent
+ * Scene: Auto / Pic: Large / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario05() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.INCANDESCENT,
+ SceneMode.AUTO, PictureSize.LARGE, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: None / WB: Cloudy
+ * Scene: Auto / Pic: Small / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario06() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.CLOUDY, SceneMode.AUTO,
+ PictureSize.SMALL, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Min / WB: Auto
+ * Scene: Action / Pic: Small / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario07() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION,
+ PictureSize.SMALL, Geotagging.ON);
+ }
+
+ /**
+ * Flash: On / Exposure: Min / WB: Auto
+ * Scene: Action / Pic: Medium / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario08() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.MIN, WhiteBalance.AUTO, SceneMode.ACTION,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: Min / WB: Auto
+ * Scene: Night / Pic: Large / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario09() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.NIGHT,
+ PictureSize.LARGE, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: Min / WB: Daylight
+ * Scene: Sunset / Pic: Small / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario10() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
+ PictureSize.SMALL, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: Max / WB: Daylight
+ * Scene: Sunset / Pic: Large / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario11() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.SUNSET,
+ PictureSize.LARGE, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Min / WB: Cloudy
+ * Scene: Auto / Pic: Large / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario12() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.CLOUDY, SceneMode.AUTO,
+ PictureSize.LARGE, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: None / WB: Auto
+ * Scene: Party / Pic: Medium / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario13() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY,
+ PictureSize.MEDIUM, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: None / WB: Auto
+ * Scene: Night / Pic: Small / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario14() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.AUTO, SceneMode.NIGHT,
+ PictureSize.SMALL, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: None / WB: Incandescent
+ * Scene: Auto / Pic: Medium / Geo: on
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario15() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.INCANDESCENT, SceneMode.AUTO,
+ PictureSize.MEDIUM, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Min / WB: Auto
+ * Scene: Party / Pic: Small / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario16() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MIN, WhiteBalance.AUTO, SceneMode.PARTY,
+ PictureSize.SMALL, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: Min / WB: Incandescent
+ * Scene: Auto / Pic: Small / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario17() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.INCANDESCENT, SceneMode.AUTO,
+ PictureSize.SMALL, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: None / WB: Auto
+ * Scene: Party / Pic: Large / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario18() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.NONE, WhiteBalance.AUTO, SceneMode.PARTY,
+ PictureSize.LARGE, Geotagging.OFF);
+ }
+
+ /**
+ * Flash Off / Exposure: None / WB: Auto
+ * Scene: Action / Pic: Large / Geo: off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario19() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.NONE, WhiteBalance.AUTO, SceneMode.ACTION,
+ PictureSize.LARGE, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: Max / WB: Fluorescent
+ * Scene: Auto / Pic: Medium / Geo: Off
+ */
+ @LargeTest
+ public void testCameraPairwiseScenario20() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MAX, WhiteBalance.FLUORESCENT, SceneMode.AUTO,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Off / Exposure: Min / WB: Auto
+ * Scene: Auto / Pic: Medium / Geo: off
+ */
+ public void testCameraPairwiseScenario21() throws Exception {
+ genericPairwiseTestCase(Flash.OFF, Exposure.MIN, WhiteBalance.AUTO, SceneMode.AUTO,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: Max / WB: Auto
+ * Scene: Action / Pic: Small / Geo: off
+ */
+ public void testCameraPairwiseScenario22() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.ACTION,
+ PictureSize.SMALL, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: On / Exposure: Max / WB: Auto
+ * Scene: Night / Pic: Medium / Geo: on
+ */
+ public void testCameraPairwiseScenario23() throws Exception {
+ genericPairwiseTestCase(Flash.ON, Exposure.MAX, WhiteBalance.AUTO, SceneMode.NIGHT,
+ PictureSize.MEDIUM, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: None / WB: Fluorescent
+ * Scene: Auto / Pic: Small / Geo: on
+ */
+ public void testCameraPairwiseScenario24() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.NONE, WhiteBalance.FLUORESCENT,
+ SceneMode.AUTO, PictureSize.SMALL, Geotagging.ON);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Max / WB: Daylight
+ * Scene: Auto / Pic: Medium / Geo: off
+ */
+ public void testCameraPairwiseScenario25() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.DAYLIGHT, SceneMode.AUTO,
+ PictureSize.MEDIUM, Geotagging.OFF);
+ }
+
+ /**
+ * Flash: Auto / Exposure: Max / WB: Auto
+ * Scene: Party / Pic: Medium / Geo: on
+ */
+ public void testCameraPairwiseScenario26() throws Exception {
+ genericPairwiseTestCase(Flash.AUTO, Exposure.MAX, WhiteBalance.AUTO, SceneMode.PARTY,
+ PictureSize.MEDIUM, Geotagging.ON);
+ }
+
+ /**
+ * Generic pairwise test method
+ */
+ private void genericPairwiseTestCase(Flash flash, Exposure exposure, WhiteBalance whitebalance,
+ SceneMode scenemode, PictureSize picturesize, Geotagging geotagging) throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Camera.Parameters params = mCameraTestHelper.getCameraParameters();
+
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+
+ // Configure flash setting
+ switch (flash) {
+ case ON:
+ params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
+ break;
+ case OFF:
+ params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ break;
+ case AUTO:
+ params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
+ break;
+ }
+
+ // Configure exposure setting
+ switch (exposure) {
+ case MIN:
+ params.setExposureCompensation(params.getMinExposureCompensation());
+ break;
+ case MAX:
+ params.setExposureCompensation(params.getMaxExposureCompensation());
+ break;
+ case NONE:
+ params.setExposureCompensation(0);
+ break;
+ }
+
+ // Configure white balance setting
+ switch (whitebalance) {
+ case DAYLIGHT:
+ params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_DAYLIGHT);
+ break;
+ case FLUORESCENT:
+ params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_FLUORESCENT);
+ break;
+ case INCANDESCENT:
+ params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_INCANDESCENT);
+ break;
+ case CLOUDY:
+ params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT);
+ break;
+ case AUTO:
+ params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
+ break;
+ }
+
+ // Configure scene mode setting
+ switch (scenemode) {
+ case SUNSET:
+ params.setSceneMode(Camera.Parameters.SCENE_MODE_SUNSET);
+ break;
+ case ACTION:
+ params.setSceneMode(Camera.Parameters.SCENE_MODE_ACTION);
+ break;
+ case PARTY:
+ params.setSceneMode(Camera.Parameters.SCENE_MODE_PARTY);
+ break;
+ case NIGHT:
+ params.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT);
+ break;
+ case AUTO:
+ params.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
+ break;
+ }
+
+ // Configure picture size setting
+ List<Camera.Size> supportedPictureSizes = params.getSupportedPictureSizes();
+ int mid = (int) Math.floor(supportedPictureSizes.size() / 2);
+ int low = supportedPictureSizes.size() - 1;
+ switch (picturesize) {
+ case SMALL:
+ params.setPictureSize(supportedPictureSizes.get(low).width,
+ supportedPictureSizes.get(low).height);
+ break;
+ case MEDIUM:
+ params.setPictureSize(supportedPictureSizes.get(mid).width,
+ supportedPictureSizes.get(mid).height);
+ break;
+ case LARGE:
+ params.setPictureSize(supportedPictureSizes.get(0).width,
+ supportedPictureSizes.get(mid).height);
+ break;
+ }
+
+ // Configure geotagging setting
+ switch (geotagging) {
+ case ON:
+ params.setGpsLatitude(MOCK_LATITUDE);
+ params.setGpsLongitude(MOCK_LONGITUDE);
+ break;
+ case OFF:
+ break;
+ }
+
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Test case failed");
+ }
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
index ed1d8fc..a112c73 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java
@@ -17,13 +17,11 @@
package com.android.mediaframeworktest.stress;
import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.CameraTestHelper;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FilenameFilter;
import java.io.FileWriter;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.Semaphore;
@@ -31,8 +29,7 @@
import java.util.List;
import android.hardware.Camera;
-import android.hardware.Camera.PictureCallback;
-import android.hardware.Camera.ShutterCallback;
+import android.hardware.Camera.Parameters;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
@@ -45,32 +42,28 @@
import junit.framework.Assert;
/**
- * Junit / Instrumentation test case for the camera zoom and scene mode APIs
+ * Junit / Instrumentation test case for the following camera APIs:
+ * - camera zoom
+ * - scene mode
*
* adb shell am instrument
* -e class com.android.mediaframeworktest.stress.CameraStressTest
* -w com.android.mediaframeworktest/.CameraStressTestRunner
*/
public class CameraStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
- private String TAG = "CameraStressTest";
- private Camera mCamera;
- private static final int CAMERA_ID = 0;
- private static final int NUMBER_OF_ZOOM_LOOPS = 100;
private static final int NUMBER_OF_SCENE_MODE_LOOPS = 10;
- private static final long WAIT_GENERIC = 3 * 1000; // 3 seconds
+ private static final int NUMBER_OF_ZOOM_LOOPS = 100;
private static final long WAIT_TIMEOUT = 10 * 1000; // 10 seconds
- private static final long WAIT_ZOOM_ANIMATION = 5 * 1000; // 5 seconds
- private static final String CAMERA_STRESS_IMAGES_DIRECTORY = "cameraStressImages";
- private static final String CAMERA_STRESS_IMAGES_PREFIX = "camera-stress-test";
private static final String CAMERA_STRESS_OUTPUT = "cameraStressOutput.txt";
- private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
- private Thread mLooperThread;
+ private CameraTestHelper mCameraTestHelper;
private Handler mHandler;
-
+ private Thread mLooperThread;
private Writer mOutput;
+ private String TAG = "CameraStressTest";
+
public CameraStressTest() {
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
}
@@ -95,19 +88,11 @@
getActivity();
super.setUp();
- File sdcard = Environment.getExternalStorageDirectory();
-
- // Create the test images directory if it doesn't exist
- File stressImagesDirectory = new File(String.format("%s/%s", sdcard,
- CAMERA_STRESS_IMAGES_DIRECTORY));
- if (!stressImagesDirectory.exists()) {
- stressImagesDirectory.mkdir();
- }
-
- // Start writing output file
- File stressOutFile = new File(String.format("%s/%s",sdcard, CAMERA_STRESS_OUTPUT));
+ mCameraTestHelper = new CameraTestHelper();
+ File stressOutFile = new File(String.format("%s/%s",
+ Environment.getExternalStorageDirectory(), CAMERA_STRESS_OUTPUT));
mOutput = new BufferedWriter(new FileWriter(stressOutFile, true));
- mOutput.write(this.getName() + ":\n");
+ mOutput.write(this.getName() + "\n");
}
@Override
@@ -123,10 +108,8 @@
}
mLooperThread = null;
}
-
mOutput.write("\n\n");
mOutput.close();
-
super.tearDown();
}
@@ -147,182 +130,14 @@
}
}
- private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
- public void onError(int error, android.hardware.Camera camera) {
- fail(String.format("Camera error, code: %d", error));
- }
- }
-
- private ShutterCallback shutterCallback = new ShutterCallback() {
- @Override
- public void onShutter() {
- Log.v(TAG, "Shutter");
- }
- };
-
- private PictureCallback rawCallback = new PictureCallback() {
- @Override
- public void onPictureTaken(byte[] data, Camera camera) {
- Log.v(TAG, "Raw picture taken");
- }
- };
-
- private PictureCallback jpegCallback = new PictureCallback() {
- @Override
- public void onPictureTaken(byte[] data, Camera camera) {
- FileOutputStream fos = null;
-
- try {
- Log.v(TAG, "JPEG picture taken");
- fos = new FileOutputStream(String.format("%s/%s/%s-%d.jpg",
- Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY,
- CAMERA_STRESS_IMAGES_PREFIX, System.currentTimeMillis()));
- fos.write(data);
- } catch (FileNotFoundException e) {
- Log.e(TAG, "File not found: " + e.toString());
- } catch (IOException e) {
- Log.e(TAG, "Error accessing file: " + e.toString());
- } finally {
- try {
- if (fos != null) {
- fos.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "Error closing file: " + e.toString());
- }
- }
- }
- };
-
- // Helper method for cleaning up pics taken during testStressCameraZoom
- private void cleanupStressTestImages() {
- try {
- File stressImagesDirectory = new File(String.format("%s/%s",
- Environment.getExternalStorageDirectory(), CAMERA_STRESS_IMAGES_DIRECTORY));
- File[] zoomImages = null;
-
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(CAMERA_STRESS_IMAGES_PREFIX);
- }
- };
-
- zoomImages = stressImagesDirectory.listFiles(filter);
-
- for (File f : zoomImages) {
- f.delete();
- }
- } catch (SecurityException e) {
- Log.e(TAG, "Security manager access violation: " + e.toString());
- }
- }
-
- // Helper method for starting up the camera preview
- private void startCameraPreview(SurfaceHolder surfaceHolder) {
- try {
- mCamera.setErrorCallback(mCameraErrorCallback);
- mCamera.setPreviewDisplay(surfaceHolder);
- mCamera.startPreview();
- Thread.sleep(WAIT_GENERIC);
- } catch (IOException e) {
- Log.e(TAG, "Error setting preview display: " + e.toString());
- } catch (InterruptedException e) {
- Log.e(TAG, "Error waiting for preview to come up: " + e.toString());
- } catch (Exception e) {
- Log.e(TAG, "Error starting up camera preview: " + e.toString());
- }
- }
-
- // Helper method for taking a photo
- private void capturePhoto() {
- try {
- mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
- Thread.sleep(WAIT_GENERIC);
- mCamera.stopPreview();
- mCamera.release();
- } catch (InterruptedException e) {
- Log.e(TAG, "Error waiting for photo to be taken: " + e.toString());
- } catch (Exception e) {
- Log.e(TAG, "Error capturing photo: " + e.toString());
- }
- }
-
- // Test case for stressing the camera zoom in/out feature
- @LargeTest
- public void testStressCameraZoom() throws Exception {
- SurfaceHolder mSurfaceHolder;
- mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
- mOutput.write("Total number of loops: " + NUMBER_OF_ZOOM_LOOPS + "\n");
-
- try {
- Log.v(TAG, "Start preview");
- mOutput.write("No of loop: ");
-
- mCamera = Camera.open(CAMERA_ID);
- Camera.Parameters params = mCamera.getParameters();
- mCamera.release();
-
- if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
- Log.v(TAG, "Device camera does not support zoom");
- fail("Camera zoom stress test failed");
- } else {
- Log.v(TAG, "Device camera does support zoom");
-
- int nextZoomLevel = 0;
-
- for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) {
- runOnLooper(new Runnable() {
- @Override
- public void run() {
- mCamera = Camera.open(CAMERA_ID);
- }
- });
-
- startCameraPreview(mSurfaceHolder);
- params = mCamera.getParameters();
- int currentZoomLevel = params.getZoom();
-
- if (nextZoomLevel >= params.getMaxZoom()) {
- nextZoomLevel = 0;
- }
- ++nextZoomLevel;
-
- if (params.isSmoothZoomSupported()) {
- mCamera.startSmoothZoom(nextZoomLevel);
- } else {
- params.setZoom(nextZoomLevel);
- mCamera.setParameters(params);
- }
- Log.v(TAG, "Zooming from " + currentZoomLevel + " to " + nextZoomLevel);
-
- // sleep allows for zoom animation to finish
- Thread.sleep(WAIT_ZOOM_ANIMATION);
- capturePhoto();
-
- if (i == 0) {
- mOutput.write(Integer.toString(i));
- } else {
- mOutput.write(", " + i);
- }
- }
- }
- cleanupStressTestImages();
- } catch (Exception e) {
- Log.e(TAG, e.toString());
- fail("Camera zoom stress test Exception");
- }
- }
-
- // Test case for stressing the camera scene mode feature
+ /**
+ * Stress test iterating on the various scene modes (action, night, party, etc.)
+ */
@LargeTest
public void testStressCameraSceneModes() throws Exception {
- SurfaceHolder mSurfaceHolder;
- mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
-
try {
- mCamera = Camera.open(CAMERA_ID);
- Camera.Parameters params = mCamera.getParameters();
- mCamera.release();
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
List<String> supportedSceneModes = params.getSupportedSceneModes();
assertNotNull("No scene modes supported", supportedSceneModes);
@@ -336,27 +151,85 @@
runOnLooper(new Runnable() {
@Override
public void run() {
- mCamera = Camera.open(CAMERA_ID);
+ mCameraTestHelper.setupCameraTest();
}
});
-
- startCameraPreview(mSurfaceHolder);
- Log.v(TAG, "Setting mode to " + supportedSceneModes.get(i));
+ Log.v(TAG, "Setting scene mode to " + supportedSceneModes.get(i));
params.setSceneMode(supportedSceneModes.get(i));
- mCamera.setParameters(params);
- capturePhoto();
+ mCameraTestHelper.setParameters(params);
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ mCameraTestHelper.capturePhoto();
- if ((i == 0) && (j == 0)) {
+ if (i == 0 && j == 0) {
mOutput.write(Integer.toString(j + i * NUMBER_OF_SCENE_MODE_LOOPS));
} else {
mOutput.write(", " + (j + i * NUMBER_OF_SCENE_MODE_LOOPS));
}
}
}
- cleanupStressTestImages();
+ mCameraTestHelper.cleanupTestImages();
} catch (Exception e) {
Log.e(TAG, e.toString());
fail("Camera scene mode test Exception");
}
}
+
+ /**
+ * Stress test iterating on the range of supported camera zoom levels
+ */
+ @LargeTest
+ public void testStressCameraZoom() throws Exception {
+ try {
+ SurfaceHolder surfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Parameters params = mCameraTestHelper.getCameraParameters();
+
+ if (!params.isSmoothZoomSupported() && !params.isZoomSupported()) {
+ Log.v(TAG, "Device camera does not support zoom");
+ fail("Camera zoom stress test failed due to unsupported feature");
+ } else {
+ Log.v(TAG, "Device camera does support zoom");
+ Log.v(TAG, "Start preview");
+ mOutput.write("Total number of loops: " + NUMBER_OF_ZOOM_LOOPS + "\n");
+ mOutput.write("No of loops: ");
+
+ int nextZoomLevel = 0;
+
+ for (int i = 0; i < NUMBER_OF_ZOOM_LOOPS; i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCameraTestHelper.setupCameraTest();
+ }
+ });
+
+ mCameraTestHelper.startCameraPreview(surfaceHolder);
+ params = mCameraTestHelper.mCamera.getParameters();
+ int currentZoomLevel = params.getZoom();
+
+ if (nextZoomLevel >= params.getMaxZoom()) {
+ nextZoomLevel = 0;
+ }
+ ++nextZoomLevel;
+
+ if (params.isSmoothZoomSupported()) {
+ mCameraTestHelper.mCamera.startSmoothZoom(nextZoomLevel);
+ } else {
+ params.setZoom(nextZoomLevel);
+ mCameraTestHelper.setParameters(params);
+ }
+ mCameraTestHelper.capturePhoto();
+
+ if (i == 0) {
+ mOutput.write(Integer.toString(i));
+ } else {
+ mOutput.write(", " + i);
+ }
+ }
+ }
+ mCameraTestHelper.cleanupTestImages();
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ fail("Camera zoom stress test Exception");
+ }
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 41da158..0970248 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -117,7 +117,6 @@
private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
- protected int mPlaybackState;
protected int mClientGeneration;
/*package*/ interface UserSwitcherCallback {
@@ -204,10 +203,9 @@
.getCachedDisplayClientState();
mTransportState = (dcs.clearing ? TRANSPORT_GONE :
(isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
- mPlaybackState = dcs.playbackState;
if (DEBUG) Log.v(TAG, "Initial transport state: "
- + mTransportState + ", pbstate=" + mPlaybackState);
+ + mTransportState + ", pbstate=" + dcs.playbackState);
}
private void cleanupAppWidgetIds() {
@@ -273,18 +271,27 @@
Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration);
}
mClientGeneration = clientGeneration;
- mTransportState = (clearing ? TRANSPORT_GONE : TRANSPORT_INVISIBLE);
- KeyguardHostView.this.post(mSwitchPageRunnable);
+ final int newState = (clearing ? TRANSPORT_GONE
+ : (mTransportState == TRANSPORT_VISIBLE ?
+ TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
+ if (newState != mTransportState) {
+ mTransportState = newState;
+ if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
+ KeyguardHostView.this.post(mSwitchPageRunnable);
+ }
}
@Override
public void onMusicPlaybackStateChanged(int playbackState, long eventTime) {
- mPlaybackState = playbackState;
if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState);
if (mTransportState != TRANSPORT_GONE) {
- mTransportState = (isMusicPlaying(mPlaybackState) ?
+ final int newState = (isMusicPlaying(playbackState) ?
TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE);
+ if (newState != mTransportState) {
+ mTransportState = newState;
+ if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
+ KeyguardHostView.this.post(mSwitchPageRunnable);
+ }
}
- KeyguardHostView.this.post(mSwitchPageRunnable);
}
};
diff --git a/packages/SystemUI/res/layout/universe.xml b/packages/SystemUI/res/layout/universe.xml
deleted file mode 100644
index 390c467..0000000
--- a/packages/SystemUI/res/layout/universe.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent" android:layout_height="match_parent">
- <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:layout_centerHorizontal="true" android:layout_alignParentTop="true"
- android:src="@drawable/bugdroid" android:scaleType="center" />
-
- <Button android:id="@+id/close"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:layout_alignParentTop="true" android:layout_alignParentEnd="true"
- android:text="@string/close_universe" />
-
- <TextView android:id="@+id/title"
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_below="@id/close" android:layout_centerHorizontal="true"
- android:paddingBottom="16dp"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:gravity="center" />
-
- <ImageView android:id="@+id/bottom"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:layout_below="@id/title" android:layout_centerHorizontal="true"
- android:layout_marginTop="16dp" />
-</RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 89a8dd7..3cc52f3 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programinligting"</string>
- <string name="close_universe" msgid="3736513750241754348">"Maak toe"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Kennisgewings af"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tik hier om kennisgewings weer aan te skakel."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Kennisgewings verskyn hier"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Verkry enige tyd toegang tot hulle deur af te sleep."\n"Sleep weer af vir stelselkontroles."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Sleep op vanaf onderkant van skerm om stelselbalk te wys"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Sleep onderkant van skerm om balk te wys"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Sleep van regterkant van skerm af om stelselbalk te wys"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e6dad88..326f478 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"የመተግበሪያ መረጃ"</string>
- <string name="close_universe" msgid="3736513750241754348">"ዝጋ"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"ማሳወቂያዎች ጠፍተዋል"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"ማስታወቅያዎችን መልሶ ለማብራት እዚህ ጋር መታ አድርግ።"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"ማሳወቂያዎች እዚህ ላይ ይታያሉ"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"ወደ ታች በማንሸራተት በማንኛውም ጊዜ ይድረሱባቸው።"\n"Swipe የስርዓት መቆጣጠሪያዎችን ለማምጣት እንደገና ወደ ታች ያንሸራትቱ።"</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"የስርዓት አሞሌውን ለማሳየት ከማያ ገጹ ታችኛው ክፍል ጀምረው ወደላይ ያንሸራትቱ"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"አሞሌውን ለማሳየት የማያ ገጹ ታችኛው ክፍል ያንሸራትቱ"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"አሞሌውን ለማሳየት ከማያ ገጹ ቀኝ ክፍል ጀምረው ያንሸራትቱ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 110ebc0..6609e37 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"معلومات التطبيق"</string>
- <string name="close_universe" msgid="3736513750241754348">"إغلاق"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"التنبيهات معطّلة"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"انقر هنا لإعادة تشغيل الإشعارات."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"سيتم تدوير الشاشة تلقائيًا."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"تظهر الإشعارات هنا"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"يمكنك الدخول إليها في أي وقت بالتمرير السريع إلى أسفل."\n"يمكنك التمرير السريع إلى أسفل مرة أخرى للوصول إلى عناصر تحكم النظام."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"مرر سريعًا من أسفل الشاشة لإظهار شريط النظام"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"مرر سريعًا أسفل الشاشة لإظهار الشريط"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"مرر سريعًا من يمين الشاشة لإظهار شريط النظام"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index c66e912..5367d03 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інфармацыя пра прыкладанне"</string>
- <string name="close_universe" msgid="3736513750241754348">"Закрыць"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Паведамленні адключаны"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Націсніце тут, каб зноў уключыць апавяшчэнні."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран паварочваецца аўтаматычна."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Апавяшчэнні з\'яўляюцца тут"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Атрымлівайце доступ да іх у любы час, праводзячы пальцам уніз."\n"Правядзіце пальцам уніз яшчэ раз, каб атрымаць доступ да сродкаў кіравання сістэмай."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Правядзіце па экрану знізу ўверх, каб адлюстраваць сістэмны радок"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Правядзіце па ніжняй частцы экрану, каб адлюстраваць радок"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Правядзіце ад правага краю экрану, каб адлюстраваць сістэмны радок"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e3f7dc1..06321af 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Информация за приложението"</string>
- <string name="close_universe" msgid="3736513750241754348">"Затваряне"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Известията са изключени"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Докоснете тук, за да включите отново известията."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Известията се показват тук"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Осъществявайте достъп до тях по всяко време, като прекарате пръст надолу."\n"Направете го отново за системните контроли."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Прекарайте пръст нагоре от долната част на екрана, за да се покаже системната лента"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Прекарайте пръст от долната част на екрана, за да се покаже лентата"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Прекарайте пръст отдясно на екрана, за да се покаже системната лента"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 580bfe7..0801f69 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informació de l\'aplicació"</string>
- <string name="close_universe" msgid="3736513750241754348">"Tanca"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificacions desactivades"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Pica aquí per tornar a activar les notificacions."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Les notificacions apareixen aquí"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Accedeix-hi en qualsevol moment: només has de fer lliscar el dit cap avall."\n"Torna a fer lliscar el dit cap avall per fer que es mostrin els controls del sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Fes lliscar el dit des de la part inferior de la pantalla perquè es mostri la barra del sistema"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Fes lliscar el dit des de la part inferior de la pantalla perquè es mostri la barra"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Fes lliscar el dit des de la dreta de la pantalla perquè es mostri la barra del sistema"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index a623612..ca7cac0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informace o aplikaci"</string>
- <string name="close_universe" msgid="3736513750241754348">"Zavřít"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Oznámení jsou vypnuta"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Chcete-li oznámení znovu zapnout, klepněte sem."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka se automaticky otočí."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Zde se zobrazují oznámení"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Můžete je kdykoli zobrazit tím, že přejedete prstem dolů."\n"Přejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Systémový panel zobrazíte přejetím ze spodní části obrazovky nahoru"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Panel zobrazíte přejetím zdola nahoru"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Systémový panel zobrazíte přejetím z pravé strany obrazovky"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7f7a51c..a37a8f6 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Oplysninger om appen"</string>
- <string name="close_universe" msgid="3736513750241754348">"Luk"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Underretninger slået fra"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tryk her for at slå underretninger til igen."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Underretninger vises her"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Få adgang til dem når som helst ved at stryge ned."\n"Stryg ned igen for at komme til systemindstillingerne."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Stryg op fra bunden af skærmen for at vise systembjælken."</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Stryg bunden af skærmen for at vise bjælken"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Stryg fra skærmens højre side for at vise systembjælken"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2b226b6..a6104ba 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-Details"</string>
- <string name="close_universe" msgid="3736513750241754348">"Schließen"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Benachrichtigungen aus"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tippen Sie hier, um die Benachrichtigungen wieder zu aktivieren."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Benachrichtigungen erscheinen hier"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Greifen Sie jederzeit auf sie zu, indem Sie nach unten wischen."\n"Wischen Sie für Systemeinstellungen erneut nach unten."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Zum Einblenden der Systemleiste auf dem Display von unten nach oben wischen"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Zum Einblenden der Leiste nach oben wischen"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Zum Einblenden der Systemleiste auf dem Display von rechts nach links wischen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dae50a3..9c6a513 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Πληροφορίες εφαρμογής"</string>
- <string name="close_universe" msgid="3736513750241754348">"Κλείσιμο"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Ειδοποιήσεις ανενεργές"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Πατήστε εδώ για να ενεργοποιήσετε ξανά τις ειδοποιήσεις."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Οι ειδοποιήσεις εμφανίζονται εδώ"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Μεταβείτε σε αυτές ανά πάσα στιγμή σύροντας προς τα κάτω."\n"Σύρετε ξανά προς τα κάτω για τα στοιχεία ελέγχου συστήματος."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Σύρετε προς τα επάνω από το κάτω μέρος της οθόνης για να εμφανίσετε τη γραμμή συστήματος"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Σύρετε από το κάτω μέρος της οθόνης για να εμφανίσετε τη γραμμή"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Σύρετε από τη δεξιά πλευρά της οθόνης για να εμφανίσετε τη γραμμή συστήματος"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 7e74e40..6ef894d 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App info"</string>
- <string name="close_universe" msgid="3736513750241754348">"Close"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notifications off"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tap here to turn notifications back on."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Notifications appear here"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Access them any time by swiping down."\n"Swipe down again for system controls."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Swipe up from bottom of screen to reveal system bar"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Swipe bottom of screen to reveal bar"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Swipe from right of screen to reveal system bar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 1fe4d46..3b36e13 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
- <string name="close_universe" msgid="3736513750241754348">"Cerrar"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí."</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido."\n"Vuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Desliza el dedo hacia arriba desde la parte inferior de la pantalla para mostrar la barra del sistema."</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Desliza el dedo desde la parte inferior de la pantalla para mostrar la barra."</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Desliza el dedo desde la parte derecha de la pantalla para mostrar la barra del sistema."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 19de9b6..acef755 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
- <string name="close_universe" msgid="3736513750241754348">"Cerrar"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido."\n"Vuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Desliza la pantalla hacia arriba desde la parte inferior para mostrar la barra del sistema"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Desliza la parte inferior de la pantalla para mostrar la barra"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Desliza la pantalla desde la derecha para mostrar la barra del sistema"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 5339006..f091640 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Rakenduse teave"</string>
- <string name="close_universe" msgid="3736513750241754348">"Sule"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Teatised väljas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Teatiste uuesti sisselülitamiseks puudutage siin."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekraani pööramine toimub automaatselt."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Märguanded ilmuvad siia"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Juurdepääs igal ajal sõrmega alla pühkides."\n"Süsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Süsteemiriba kuvamiseks pühkige ekraani allosast üles"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Riba kuvamiseks pühkige ekraani allosas"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Süsteemiriba kuvamiseks pühkige ekraani paremast servast"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e766df8..5abcc05 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"اطلاعات برنامه"</string>
- <string name="close_universe" msgid="3736513750241754348">"بستن"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"اعلانها خاموش"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"برای روشن کردن مجدد اعلانها، اینجا را ضربه بزنید."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"صفحه به صورت خودکار میچرخد."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"اعلانها در اینجا نمایش داده میشوند"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"با کشیدن انگشت به طرف پایین به آنها دسترسی پیدا کنید."\n"برای کنترلهای سیستم دوباره انگشت خود را به سمت پایین بکشید."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"برای آشکارسازی نوار سیستم انگشت خود را از پایین صفحه به بالا بکشید"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"برای آشکارسازی نوار انگشت خود را روی پایین صفحه بکشید"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"برای آشکارسازی نوار سیستم انگشت خود را از سمت راست صفحه بکشید"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 8e80016..26a355e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Sovelluksen tiedot"</string>
- <string name="close_universe" msgid="3736513750241754348">"Sulje"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Ilmoitukset pois käytöstä"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Ota ilmoitukset uudelleen käyttöön napauttamalla tätä."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Ilmoitukset näkyvät tässä"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Näet ilmoitukset liu\'uttamalla sormea alas ruudulla."\n"Voit palauttaa järjestelmän ohjaimet näkyviin liu\'uttamalla sormea alas uudelleen."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Tuo järjestelmäpalkki näkyviin liu\'uttamalla ruudun alalaidasta ylöspäin"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Tuo palkki näkyviin liu\'uttamalla ruudun alaosasta"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Tuo järjestelmäpalkki näkyviin liu\'uttamalla ruudun oikeasta laidasta vasemmalle"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 294c0ee..4fd43d6 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informations sur l\'application"</string>
- <string name="close_universe" msgid="3736513750241754348">"Fermer"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notifications désactivées"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Appuyez ici pour réactiver les notifications."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Les notifications s’affichent ici"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Accédez-y à tout moment en faisant glisser le doigt vers le bas."\n"Répétez l\'opération pour accéder aux commandes du système."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Faites glisser votre doigt de bas en haut sur l\'écran pour afficher la barre système."</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Faites glisser votre doigt au bas de l\'écran pour afficher la barre."</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Faites glisser votre doigt de droite à gauche sur l\'écran pour afficher la barre système."</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index cdcda79..ed9654f1 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्थान"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"एप्लिकेशन जानकारी"</string>
- <string name="close_universe" msgid="3736513750241754348">"बंद करें"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"सूचनाएं बंद"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"सूचनाओं को पुन: चालू करने के लिए यहां टैप करें."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वचालित रूप से घूमेगी."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"सूचनाएं यहां दिखाई देती हैं"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"नीचे स्वाइप करके उन तक कभी भी पहुंचें."\n"सिस्टम नियंत्रणों के लिए पुन: नीचे स्वाइप करें."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"सिस्टम बार दिखाने के लिए स्क्रीन के नीचे से ऊपर की ओर स्वाइप करें"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"बार दिखाने के लिए स्क्रीन के नीचे स्वाइप करें"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"सिस्टम बार दिखाने के लिए स्क्रीन की दाईं ओर से स्वाइप करें"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 93e03d1..777c048 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informacije o aplikaciji"</string>
- <string name="close_universe" msgid="3736513750241754348">"Zatvori"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Obavijesti isključene"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite ovdje da biste ponovo uključili obavijesti."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Obavijesti se prikazuju ovdje"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Pristupite im u bilo kojem trenutku tako da prstom trznete prema dolje. "\n"Ponovo prstom trznite prema dolje za kontrole sustava."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Prijeđite prstom od dna zaslona prema gore da bi se prikazala traka sustava"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Prijeđite prstom po dnu zaslona da bi se prikazala traka"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Prijeđite prstom od desne strane zaslona da bi se prikazala traka sustava"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 27bf2f5..b354024 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"A GPS beállította a helyet"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Alkalmazásinformáció"</string>
- <string name="close_universe" msgid="3736513750241754348">"Bezárás"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Értesítések kikapcsolva"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Itt érintse meg az értesítések bekapcsolásához."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A képernyő automatikusan forogni fog."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Az értesítések itt jelennek meg."</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Bármikor elérheti őket, ha lefelé húzza az ujját."\n"Húzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Csúsztassa ujját a képernyő aljától felfelé a rendszersáv megjelenítéséhez"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Csúsztassa ujját a képernyő alján a sáv megjelenítéséhez"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Csúsztassa ujját a képernyő jobb oldalától a rendszersáv megjelenítéséhez"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 581c56c..68d3796 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info aplikasi"</string>
- <string name="close_universe" msgid="3736513750241754348">"Tutup"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan mati"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Ketuk di sini untuk menyalakan pemberitahuan lagi."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan muncul di sini"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Akses kapan saja dengan menggesek ke bawah."\n"Gesek ke bawah sekali lagi untuk kontrol sistem."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Gesek ke atas dari bagian bawah layar untuk membuka bilah sistem"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Gesek bagian bawah layar untuk membuka bilah"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Gesek dari bagian kanan layar untuk membuka bilah sistem"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 3d7cb76..398650e9 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informazioni applicazione"</string>
- <string name="close_universe" msgid="3736513750241754348">"Chiudi"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notifiche disattivate"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tocca qui per riattivare le notifiche."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Le notifiche vengono visualizzate qui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Puoi accedervi in qualsiasi momento scorrendo verso il basso."\n"Fai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Fai scorrere il dito verso l\'alto dalla parte inferiore dello schermo per visualizzare la barra di sistema"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Fai scorrere parte inferiore dello schermo per visualizzare la barra"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Fai scorrere il dito dalla parte destra dello schermo per visualizzare la barra di sistema"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8dd00d1..96f8a4a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"פרטי יישום"</string>
- <string name="close_universe" msgid="3736513750241754348">"סגור"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"מצב התראות כבוי"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"הקש כאן כדי להפעיל מחדש את ההתראות."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"הודעות מופיעות כאן"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"גש אליהם בכל עת על ידי החלקה למטה."\n"החלק למטה שוב למעבר למרכז הבקרה של המערכת."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"החלק מעלה מתחתית המסך כדי להציג את סרגל המערכת"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"החלק מתחתית המסך כדי להציג את הסרגל"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"החלק מצד ימין של המסך כדי להציג את סרגל המערכת"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b64d73e..eff450d 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"アプリ情報"</string>
- <string name="close_universe" msgid="3736513750241754348">"閉じる"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"通知OFF"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"通知を再度ONにするにはここをタップします。"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"ここに通知が表示されます"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"下にスワイプすると、いつでも通知を表示できます。"\n"システムを管理するにはもう一度下にスワイプしてください。"</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"システムバーを表示するには、画面下部から上方向にスワイプします"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"バーを表示するには、画面下部からスワイプします"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"システムバーを表示するには、画面右からスワイプします"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 3f7c520..0bcc626 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"앱 정보"</string>
- <string name="close_universe" msgid="3736513750241754348">"닫기"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"알림 사용 안함"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"알림을 다시 사용하려면 여기를 터치하세요."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"알림이 여기에 표시됨"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"아래로 스와이프하여 언제든 액세스하세요."\n"한 번 더 아래로 스와이프하면 시스템 관리로 이동합니다."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"화면 하단에서 위로 스와이프하여 시스템 표시줄 표시"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"화면 하단에서 스와이프하여 표시줄 표시"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"화면 오른쪽에서 스와이프하여 시스템 표시줄 표시"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 02d0c5b..03de3c5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programos informacija"</string>
- <string name="close_universe" msgid="3736513750241754348">"Uždaryti"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Pranešimai išjungti"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Jei norite vėl įjungti pranešimus, palieskite čia."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Pranešimai rodomi čia"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Perbraukę žemyn bet kuriuo metu pasieksite pranešimus."\n"Jei norite naudoti sistemos valdiklius, perbraukite žemyn dar kartą."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Jei norite, kad būtų rodoma sistemos juosta, perbraukite aukštyn iš ekrano apačios"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Jei norite, kad būtų rodoma juosta, perbraukite ekrano apačioje"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Jei norite, kad būtų rodoma sistemos juosta, perbraukite iš ekrano dešinės"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 372389f..2f4e9c2 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informācija par lietotni"</string>
- <string name="close_universe" msgid="3736513750241754348">"Aizvērt"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Paziņojumi ir izslēgti"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Pieskarieties šeit, lai atkal ieslēgtu paziņojumus."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrāns tiks pagriezts automātiski."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Šeit tiek rādīti paziņojumi"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Piekļūstiet tiem jebkurā laikā, velkot uz leju."\n"Vēlreiz velciet, lai tiktu parādītas sistēmas vadīklas."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Velciet augšup no ekrāna apakšdaļas, lai tiktu parādīta sistēmas josla."</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Velciet no ekrāna apakšdaļas, lai tiktu parādīta josla."</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Velciet no ekrāna labās malas, lai tiktu parādīta sistēmas josla."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 8505377..1e4f98e 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Maklumat apl"</string>
- <string name="close_universe" msgid="3736513750241754348">"Tutup"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan dimatikan"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Ketik di sini untuk menghidupkan kembali pemberitahuan."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan dipaparkan di sini"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Akses panel pada bila-bila masa dengan meleret ke bawah."\n"Leret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Leret ke atas dari bahagian bawah skrin untuk mendedahkan bar sistem"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Leret ke bahagian bawah skrin untuk mendedahkan bar"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Leret dari kanan skrin untuk mendedahkan bar sistem"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7a7c5a5..e0df440 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om app"</string>
- <string name="close_universe" msgid="3736513750241754348">"Lukk"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Varsler er deaktivert"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Trykk her for å aktivere varsler på nytt."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjermen roterer automatisk."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Varslene vises her"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Bruk dem når som helst ved å sveipe nedover."\n"Sveip nedover igjen for å gå til systemkontrollene."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Sveip opp fra bunnen av skjermen for å få frem systemfeltet"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Sveip på bunnen av skjermen for å få frem feltet"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Sveip fra høyre på skjermen for å få frem systemfeltet"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3a3c820..9457da2 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-info"</string>
- <string name="close_universe" msgid="3736513750241754348">"Sluiten"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Meldingen uit"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tik hier om meldingen weer in te schakelen."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Scherm wordt automatisch geroteerd."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Meldingen worden hier weergegeven"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"U kunt de meldingen op elk gewenst moment openen door met uw vinger omlaag te vegen."\n"Veeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Veeg omhoog vanaf de onderkant van het scherm om de systeembalk weer te geven"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Veeg onderkant van scherm om balk weer te geven"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Veeg vanaf de rechterkant van het scherm om de systeembalk weer te geven"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index fff1aa0..947bd4e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
- <string name="close_universe" msgid="3736513750241754348">"Zamknij"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Powiadomienia wyłączone"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Kliknij tutaj, by przywrócić powiadomienia."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Tutaj pokazują się powiadomienia"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Możesz je otworzyć w dowolnej chwili, przesuwając w dół."\n"Przesuń jeszcze raz w dół, by otworzyć ustawienia systemowe."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Przesuń palcem od dołu ekranu, by odkryć pasek systemu"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Przesuń palcem dół ekranu, by odkryć pasek"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Przesuń palcem od prawej strony ekranu, by odkryć pasek systemu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 5976e0e..f54034d 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações da aplicação"</string>
- <string name="close_universe" msgid="3736513750241754348">"Fechar"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificações desativadas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Toque aqui para voltar a ativar as notificações."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"As notificações são apresentadas aqui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Pode aceder em qualquer altura, deslizando rapidamente para baixo com o dedo."\n"Deslize novamente para baixo para aceder aos controlos do sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Deslize p/ cima a partir da parte inferior do ecrã p/ revelar a barra do sistema"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Deslize da parte inferior do ecrã p/ revelar a barra"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Deslize da direita do ecrã p/ revelar a barra do sistema"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0cfd805..4ee6554 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações do aplicativo"</string>
- <string name="close_universe" msgid="3736513750241754348">"Fechar"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificações desativadas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Toque aqui para ativar as notificações novamente."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"As notificações aparecem aqui"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Acesse a qualquer momento deslizando para baixo."\n"Deslize para baixo novamente para acessar os controles do sistema."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Deslize de cima para baixo na tela para ver a barra do sistema"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Deslize para baixo para ver a barra"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Deslize da direita para a esquerda na tela para ver a barra do sistema"</string>
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 606160b..1265b64 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -304,8 +304,6 @@
<skip />
<!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
<skip />
- <!-- no translation found for close_universe (3736513750241754348) -->
- <skip />
<!-- no translation found for notifications_off_title (8936620513608443224) -->
<skip />
<!-- no translation found for notifications_off_text (2529001315769385273) -->
@@ -376,4 +374,10 @@
<skip />
<!-- no translation found for status_bar_help_text (7874607155052076323) -->
<skip />
+ <!-- no translation found for hideybar_confirmation_message_bottom (4678097945183429216) -->
+ <skip />
+ <!-- no translation found for hideybar_confirmation_message_bottom_short (4014207345313478943) -->
+ <skip />
+ <!-- no translation found for hideybar_confirmation_message_right (5359586491708388067) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 44b4b4e..97d81e8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeţi toate notificările."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informaţii despre aplicaţie"</string>
- <string name="close_universe" msgid="3736513750241754348">"Închideţi"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificările sunt dezactivate"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Apăsaţi aici pentru a reactiva notificările."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Notificările se afişează aici"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Accesaţi-le oricând glisând în jos."\n"Glisaţi în jos din nou pentru comenzile sistemului."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Glisați în sus din partea inferioară a ecranului pentru a afișa bara de sistem"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Glisați dinspre partea inferioară a ecranului pentru a afișa bara"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Glisați din partea dreaptă a ecranului pentru a afișa bara de sistem"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9fabb39..b26ef9d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Координаты по GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"О приложении"</string>
- <string name="close_universe" msgid="3736513750241754348">"Закрыть"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Уведомления отключены"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Нажмите здесь, чтобы снова включить уведомления."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
@@ -207,4 +206,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Это панель уведомлений"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Ее можно открыть, пролистнув экран вниз."\n"Чтобы открыть настройки, проведите пальцем вниз ещё раз."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Чтобы увидеть строку состояния, проведите пальцем от нижней части экрана вверх"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Чтобы увидеть строку состояния, проведите по экрану снизу вверх"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Чтобы увидеть строку состояния, проведите пальцем по экрану справа налево"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c5143dd..92ff8c9 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informácie o aplikácii"</string>
- <string name="close_universe" msgid="3736513750241754348">"Zavrieť"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Upozornenia sú vypnuté"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Klepnutím sem upozornenia znova povolíte."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Tu sa zobrazujú upozornenia"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Môžete ich kedykoľvek zobraziť tak, že posuniete prstom nadol."\n"Ak posuniete prstom nadol ešte raz, zobrazia sa ovládacie prvky systému."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Systémový panel zobrazíte posunutím z dolnej časti obrazovky smerom nahor"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Panel zobrazíte posunutím zdola nahor"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Systémový panel zobrazíte posunutím z pravej strany obrazovky"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 48f0893..4c36308 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Podatki o aplikaciji"</string>
- <string name="close_universe" msgid="3736513750241754348">"Zapri"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Obvestila so izklopljena"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da ponovno vklopite obvestila."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Obvestila so prikazana tukaj"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Do njih lahko kadar koli dostopate tako, da povlečete navzdol."\n"Za prikaz sistemskih kontrolnikov znova povlecite navzdol."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Povlecite navzgor z dna zaslona, da prikažete sistemsko vrstico"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Prikažite vrstico tako, da povlečete na dnu zaslona"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Sistemsko vrstico prikažete tako, da povlečete z desne strani zaslona"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 42ab38a..00a92a9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Информације о апликацији"</string>
- <string name="close_universe" msgid="3736513750241754348">"Затвори"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Обавештења су искључена"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Додирните овде да бисте поново укључили обавештења."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран ће се аутоматски ротирати."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Обавештења се појављују овде"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Приступите им у било ком тренутку листањем надоле."\n"Поново листајте надоле да би се приказале системске контроле."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Превуците нагоре од доњег дела екрана да би се приказала системска трака"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Превуците од доњег дела екрана да би се приказала трака"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Превуците од десне стране екрана да би се приказала системска трака"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 4ddcb84..38689e4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om appen"</string>
- <string name="close_universe" msgid="3736513750241754348">"Stäng"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Meddelanden inaktiverade"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Knacka lätt här om du vill aktivera meddelanden igen."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Du kommer åt dem när som helst genom att dra nedåt."\n"Dra nedåt igen om du vill visa systemkontroller."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Dra uppåt från skärmens nederkant om du vill visa systemfältet"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Dra uppåt på skärmen om du vill visa fältet"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Dra från högersidan av skärmen om du vill visa systemfältet"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index d5c8282..ee6fabc6 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -165,7 +165,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Taarifa ya programu"</string>
- <string name="close_universe" msgid="3736513750241754348">"Funga"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Arifa zimelemazwa"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Gonga hapa ili kuwezesha tena arifa."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
@@ -201,4 +200,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Arifa zitaonekana hapa"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Wafikie wakati wowote kwa kupapasa chini."\n"Papasa chini tena kupata vidhibiti vya mfumo."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Papasa kwenda juu kutoka chini ya skrini ili kuonyesha upau wa mfumo"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Papasa chini ya skrini ili kuonyesha upau"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Papasa kutoka kulia kwa skrini ili kuonyesha upau wa mfumo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 20d165f..e7f93ed 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ข้อมูลแอป"</string>
- <string name="close_universe" msgid="3736513750241754348">"ปิด"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"การแจ้งเตือนปิดอยู่"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"แตะที่นี่เพื่อเปิดการแจ้งเตือนอีกครั้ง"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"หน้าจอจะหมุนโดยอัตโนมัติ"</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"การแจ้งเตือนจะแสดงขึ้นที่นี่"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"เข้าถึงได้ทุกเมื่อด้วยการกวาดนิ้วลง"\n"กวาดนิ้วลงอีกครั้งสำหรับการควบคุมระบบ"</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"กวาดขึ้นจากด้านล่างของหน้าจอเพื่อแสดงแถบระบบ"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"กวาดด้านล่างของหน้าจอเพื่อแสดงแถบ"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"กวาดจากด้านขวาของหน้าจอเพื่อแสดงแถบระบบ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 48dca2d..4579b43 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Impormasyon ng app"</string>
- <string name="close_universe" msgid="3736513750241754348">"Isara"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Naka-off ang mga notification"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Tumapik dito upang muling i-on ang mga notification."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Dito lumalabas ang mga notification"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"I-access ang mga ito anumang oras sa pamamagitan ng pag-swipe pababa."\n"Muling mag-swipe pababa para sa mga kontrol ng system."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Mag-swipe pataas mula sa ibaba ng screen upang ipakita ang system bar"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Mag-swipe sa ibaba ng screen upang ipakita ang bar"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Mag-swipe mula sa kanan ng screen upang ipakita ang system bar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5d64286..9bccbb9 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Uygulama bilgileri"</string>
- <string name="close_universe" msgid="3736513750241754348">"Kapat"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Bildirimler kapalı"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Bildirimleri tekrar açmak için buraya hafifçe vurun."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Bildirimler burada görünür"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Aşağıya hızlıca kaydırarak bunlara istediğiniz zaman erişebilirsiniz."\n"Sistem denetimleri için tekrar hızlıca aşağı kaydırın."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Sistem çubuğunu görüntülemek için ekranın altında yukarı doğru hızlıca kaydırın"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Çubuğu görüntülemek için ekranın altından hızlıca kaydırın"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Sistem çubuğunu görüntülemek için ekranın sağından hızlıca kaydırın"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index f862365..1df9c28 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інформація про програму"</string>
- <string name="close_universe" msgid="3736513750241754348">"Закрити"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Сповіщення вимкнено"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Торкніться тут, щоб знову ввімкнути сповіщення."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран обертатиметься автоматично."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Сповіщення з’являються тут"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Отримуйте до них доступ будь-коли, провівши пальцем униз."\n"Знову проведіть униз, щоб відкрити елементи керування системи."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Проведіть пальцем угору від низу екрана, щоб з’явився системний рядок"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Проведіть від низу екрана, щоб з’явився рядок"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Проведіть пальцем справа наліво на екрані, щоб з’явився системний рядок"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index d5a64b0..f37fa47 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
- <string name="close_universe" msgid="3736513750241754348">"Đóng"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Tắt thông báo"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Chạm vào đây để bật lại thông báo."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Thông báo xuất hiện tại đây"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Truy cập vào chúng bất kỳ lúc nào bằng cách vuốt xuống."\n"Vuốt lại xuống để hiển thị các điều khiển hệ thống."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Vuốt lên từ cuối màn hình để hiển thị thanh hệ thống"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Vuốt cuối màn hình để hiển thị thanh"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Vuốt từ bên phải màn hình để hiển thị thanh hệ thống"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 3d2f2e1..57c93cc 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -40,7 +40,7 @@
<string name="invalid_charger" msgid="4549105996740522523">"不支持 USB 充电功能。"\n"只能使用随附的充电器充电。"</string>
<string name="battery_low_why" msgid="7279169609518386372">"电量使用情况"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"设置"</string>
- <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"飞行模式"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"自动旋转屏幕"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"静音"</string>
@@ -100,12 +100,12 @@
<string name="accessibility_data_two_bars" msgid="6166018492360432091">"数据信号强度为两格。"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"数据信号强度为三格。"</string>
<string name="accessibility_data_signal_full" msgid="2708384608124519369">"数据信号满格。"</string>
- <string name="accessibility_wifi_off" msgid="3177380296697933627">"已关闭 Wi-Fi。"</string>
- <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wi-Fi 连接已断开。"</string>
- <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wi-Fi 信号强度为一格。"</string>
- <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wi-Fi 信号强度为两格。"</string>
- <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wi-Fi 信号强度为三格。"</string>
- <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wi-Fi 信号满格。"</string>
+ <string name="accessibility_wifi_off" msgid="3177380296697933627">"已关闭 WLAN。"</string>
+ <string name="accessibility_no_wifi" msgid="1425476551827924474">"WLAN 连接已断开。"</string>
+ <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"WLAN 信号强度为一格。"</string>
+ <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"WLAN 信号强度为两格。"</string>
+ <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WLAN 信号强度为三格。"</string>
+ <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"WLAN 信号满格。"</string>
<string name="accessibility_no_wimax" msgid="4329180129727630368">"无 WiMAX 信号。"</string>
<string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX 信号强度为一格。"</string>
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX 信号强度为两格。"</string>
@@ -130,7 +130,7 @@
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"漫游中"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
- <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+ <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WLAN"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"无 SIM 卡。"</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"蓝牙共享网络。"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"飞行模式。"</string>
@@ -164,12 +164,11 @@
<string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已达到指定的数据流量上限。"\n\n"如果您重新启用数据,运营商可能会收取相应的费用。"</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新启用数据连接"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"未连接互联网"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi 已连接"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN 已连接"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜索 GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"已通过 GPS 确定位置"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"应用信息"</string>
- <string name="close_universe" msgid="3736513750241754348">"关闭"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"通知功能已停用"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"点按此处可重新启用通知功能。"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
@@ -195,14 +194,17 @@
<string name="quick_settings_settings_label" msgid="5326556592578065401">"设置"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"时间"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"我"</string>
- <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+ <string name="quick_settings_wifi_label" msgid="9135344704899546041">"WLAN"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"未连接"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"无网络"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 已关闭"</string>
- <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi 显示"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN 已关闭"</string>
+ <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"WLAN 显示"</string>
<string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"无线显示"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"通知会显示在这里"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"向下滑动可随时查看通知。"\n"再次向下滑动可使用系统控制功能。"</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"从屏幕底部向上滑动即可显示系统栏"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"从底部向上滑可显示系统栏"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"从屏幕右侧向左滑动即可显示系统栏"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d7ecc3f..d57e82e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -169,7 +169,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"應用程式資訊"</string>
- <string name="close_universe" msgid="3736513750241754348">"關閉"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"關閉通知"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"輕按這裡即可重新開啟通知。"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
@@ -205,4 +204,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"系統會在這裡顯示通知"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"向下滑動即可隨時存取通知。"\n"再次向下滑動即可使用系統控制項。"</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"從螢幕底部向上滑動即可顯示系統列"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"從螢幕底部滑動即可顯示系統列"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"從螢幕右側滑動即可顯示系統列"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index fc3c625..710225d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -167,7 +167,6 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
- <string name="close_universe" msgid="3736513750241754348">"Vala"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Izaziso zivaliwe"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Thepha lapha ukuvula futhi izaziso."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
@@ -203,4 +202,7 @@
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Izaziso zivela lapha"</string>
<string name="status_bar_help_text" msgid="7874607155052076323">"Kufinyelele noma kunini ngokuswayiphela phansi."\n"Swayiphela phansi futhi ngezilawuli zesistimu."</string>
+ <string name="hideybar_confirmation_message_bottom" msgid="4678097945183429216">"Swayipha kusukela ngaphansi kwesikrini ukuze uveze ibha yesistimu"</string>
+ <string name="hideybar_confirmation_message_bottom_short" msgid="4014207345313478943">"Swayipha ngaphansi kwesikrini ukuze uveze ibha"</string>
+ <string name="hideybar_confirmation_message_right" msgid="5359586491708388067">"Swayipha kusukela ngakwesokudla ukuze uveze ibha yesistimu"</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d003a09..5e232f3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -433,9 +433,6 @@
application -->
<string name="status_bar_notification_inspect_item_title">App info</string>
- <!-- [CHAR LIMIT=NONE] -->
- <string name="close_universe">Close</string>
-
<!-- Title for the pseudo-notification shown when notifications are disabled (do-not-disturb
mode) -->
<string name="notifications_off_title">Notifications off</string>
diff --git a/packages/SystemUI/src/com/android/systemui/BootReceiver.java b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
index d3ce30d..8e24eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/BootReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
@@ -21,7 +21,7 @@
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
/**
* Performs a number of miscellaneous, non-system-critical actions
@@ -40,7 +40,7 @@
context.startService(loadavg);
}
} catch (Exception e) {
- Slog.e(TAG, "Can't start load average service", e);
+ Log.e(TAG, "Can't start load average service", e);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index edfaf49..0019c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -23,7 +23,7 @@
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Vibrator;
-import android.util.Slog;
+import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
@@ -113,7 +113,7 @@
= new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
- if (DEBUG_SCALE) Slog.v(TAG, "onscalebegin()");
+ if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()");
float focusX = detector.getFocusX();
float focusY = detector.getFocusY();
@@ -126,7 +126,7 @@
@Override
public boolean onScale(ScaleGestureDetector detector) {
- if (DEBUG_SCALE) Slog.v(TAG, "onscale() on " + mCurrView);
+ if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mCurrView);
return true;
}
@@ -143,7 +143,7 @@
mView = v;
}
public void setHeight(float h) {
- if (DEBUG_SCALE) Slog.v(TAG, "SetHeight: setting to " + h);
+ if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h);
ViewGroup.LayoutParams lp = mView.getLayoutParams();
lp.height = (int)h;
mView.setLayoutParams(lp);
@@ -158,7 +158,7 @@
}
public int getNaturalHeight(int maximum) {
ViewGroup.LayoutParams lp = mView.getLayoutParams();
- if (DEBUG_SCALE) Slog.v(TAG, "Inspecting a child of type: " +
+ if (DEBUG_SCALE) Log.v(TAG, "Inspecting a child of type: " +
mView.getClass().getName());
int oldHeight = lp.height;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -230,7 +230,7 @@
}
private void updateExpansion() {
- if (DEBUG_SCALE) Slog.v(TAG, "updateExpansion()");
+ if (DEBUG_SCALE) Log.v(TAG, "updateExpansion()");
// are we scaling or dragging?
float span = mSGD.getCurrentSpan() - mInitialTouchSpan;
span *= USE_SPAN ? 1f : 0f;
@@ -270,10 +270,10 @@
}
private boolean isInside(View v, float x, float y) {
- if (DEBUG) Slog.d(TAG, "isinside (" + x + ", " + y + ")");
+ if (DEBUG) Log.d(TAG, "isinside (" + x + ", " + y + ")");
if (v == null) {
- if (DEBUG) Slog.d(TAG, "isinside null subject");
+ if (DEBUG) Log.d(TAG, "isinside null subject");
return false;
}
if (mEventSource != null) {
@@ -281,14 +281,14 @@
mEventSource.getLocationOnScreen(location);
x += location[0];
y += location[1];
- if (DEBUG) Slog.d(TAG, " to global (" + x + ", " + y + ")");
+ if (DEBUG) Log.d(TAG, " to global (" + x + ", " + y + ")");
}
int[] location = new int[2];
v.getLocationOnScreen(location);
x -= location[0];
y -= location[1];
- if (DEBUG) Slog.d(TAG, " to local (" + x + ", " + y + ")");
- if (DEBUG) Slog.d(TAG, " inside (" + v.getWidth() + ", " + v.getHeight() + ")");
+ if (DEBUG) Log.d(TAG, " to local (" + x + ", " + y + ")");
+ if (DEBUG) Log.d(TAG, " inside (" + v.getWidth() + ", " + v.getHeight() + ")");
boolean inside = (x > 0f && y > 0f && x < v.getWidth() & y < v.getHeight());
return inside;
}
@@ -307,10 +307,10 @@
private float calculateGlow(float target, float actual) {
// glow if overscale
- if (DEBUG_GLOW) Slog.d(TAG, "target: " + target + " actual: " + actual);
+ if (DEBUG_GLOW) Log.d(TAG, "target: " + target + " actual: " + actual);
float stretch = Math.abs((target - actual) / mMaximumStretch);
float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
- if (DEBUG_GLOW) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
+ if (DEBUG_GLOW) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
return (GLOW_BASE + strength * (1f - GLOW_BASE));
}
@@ -348,7 +348,7 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
- if (DEBUG_SCALE) Slog.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
+ if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
" expanding=" + mExpanding +
(0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
(0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
@@ -362,7 +362,7 @@
mInitialTouchSpan = mSGD.getCurrentSpan();
mLastFocusY = mInitialTouchFocusY;
mLastSpanY = mInitialTouchSpan;
- if (DEBUG_SCALE) Slog.d(TAG, "set initial span: " + mInitialTouchSpan);
+ if (DEBUG_SCALE) Log.d(TAG, "set initial span: " + mInitialTouchSpan);
if (mExpanding) {
return true;
@@ -376,7 +376,7 @@
xspan > mPullGestureMinXSpan &&
xspan > mSGD.getCurrentSpanY())) {
// detect a vertical pulling gesture with fingers somewhat separated
- if (DEBUG_SCALE) Slog.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
+ if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
final View underFocus = findView(x, y);
if (underFocus != null) {
@@ -393,7 +393,7 @@
if (mWatchingForPull) {
final int yDiff = y - mLastMotionY;
if (yDiff > mTouchSlop) {
- if (DEBUG) Slog.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
+ if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
mLastMotionY = y;
final View underFocus = findView(x, y);
if (underFocus != null) {
@@ -413,7 +413,7 @@
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (DEBUG) Slog.d(TAG, "up/cancel");
+ if (DEBUG) Log.d(TAG, "up/cancel");
finishExpanding(false);
clearView();
break;
@@ -425,7 +425,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
- if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
+ if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
" expanding=" + mExpanding +
(0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
(0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
@@ -484,14 +484,14 @@
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN:
- if (DEBUG) Slog.d(TAG, "pointer change");
+ if (DEBUG) Log.d(TAG, "pointer change");
mInitialTouchY += mSGD.getFocusY() - mLastFocusY;
mInitialTouchSpan += mSGD.getCurrentSpan() - mLastSpanY;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (DEBUG) Slog.d(TAG, "up/cancel");
+ if (DEBUG) Log.d(TAG, "up/cancel");
finishExpanding(false);
clearView();
break;
@@ -505,20 +505,20 @@
return;
}
mExpanding = true;
- if (DEBUG) Slog.d(TAG, "scale type " + expandType + " beginning on view: " + v);
+ if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v);
mCallback.setUserLockedChild(v, true);
setView(v);
setGlow(GLOW_BASE);
mScaler.setView(v);
mOldHeight = mScaler.getHeight();
if (mCallback.canChildBeExpanded(v)) {
- if (DEBUG) Slog.d(TAG, "working on an expandable child");
+ if (DEBUG) Log.d(TAG, "working on an expandable child");
mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
} else {
- if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
+ if (DEBUG) Log.d(TAG, "working on a non-expandable child");
mNaturalHeight = mOldHeight;
}
- if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
+ if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
" mNaturalHeight: " + mNaturalHeight);
v.getParent().requestDisallowInterceptTouchEvent(true);
}
@@ -526,7 +526,7 @@
private void finishExpanding(boolean force) {
if (!mExpanding) return;
- if (DEBUG) Slog.d(TAG, "scale in finishing on view: " + mCurrView);
+ if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mCurrView);
float currentHeight = mScaler.getHeight();
float targetHeight = mSmallSize;
@@ -552,11 +552,11 @@
mExpanding = false;
mExpansionStyle = NONE;
- if (DEBUG) Slog.d(TAG, "wasClosed is: " + wasClosed);
- if (DEBUG) Slog.d(TAG, "currentHeight is: " + currentHeight);
- if (DEBUG) Slog.d(TAG, "mSmallSize is: " + mSmallSize);
- if (DEBUG) Slog.d(TAG, "targetHeight is: " + targetHeight);
- if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
+ if (DEBUG) Log.d(TAG, "wasClosed is: " + wasClosed);
+ if (DEBUG) Log.d(TAG, "currentHeight is: " + currentHeight);
+ if (DEBUG) Log.d(TAG, "mSmallSize is: " + mSmallSize);
+ if (DEBUG) Log.d(TAG, "targetHeight is: " + targetHeight);
+ if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
}
private void clearView() {
@@ -575,7 +575,7 @@
String debugLog = "Looking for glows: " +
(mCurrViewTopGlow != null ? "found top " : "didn't find top") +
(mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
- Slog.v(TAG, debugLog);
+ Log.v(TAG, debugLog);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 1f29990..ab11748 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -32,7 +32,7 @@
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.EventLog;
-import android.util.Slog;
+import android.util.Log;
import android.view.IWindowManager;
import android.view.MotionEvent;
import android.view.View;
@@ -120,7 +120,7 @@
mContext.startActivityAsUser(intent, opts.toBundle(),
new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
- Slog.w(TAG, "Activity not found for " + intent.getAction());
+ Log.w(TAG, "Activity not found for " + intent.getAction());
onAnimationStarted();
}
}
@@ -186,7 +186,7 @@
if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
ASSIST_ICON_METADATA_NAME,
com.android.internal.R.drawable.ic_action_assist_generic)) {
- if (DEBUG) Slog.v(TAG, "Couldn't grab icon for component " + component);
+ if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index e1aed82..ebd7fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -24,7 +24,7 @@
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.RemoteException;
-import android.util.Slog;
+import android.util.Log;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -70,14 +70,14 @@
? R.string.config_systemBarComponent
: R.string.config_statusBarComponent;
} catch (RemoteException e) {
- Slog.w(TAG, "Failing checking whether status bar can hide", e);
+ Log.w(TAG, "Failing checking whether status bar can hide", e);
}
final int N = SERVICES.length;
mServices = new SystemUI[N];
for (int i=0; i<N; i++) {
Class cl = chooseClass(SERVICES[i]);
- Slog.d(TAG, "loading: " + cl);
+ Log.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
@@ -86,7 +86,7 @@
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
- Slog.d(TAG, "running: " + mServices[i]);
+ Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java b/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
deleted file mode 100644
index f859880..0000000
--- a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Matrix;
-import android.graphics.PixelFormat;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Slog;
-import android.view.Choreographer;
-import android.view.Display;
-import android.view.IWindowSession;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.animation.Transformation;
-import android.widget.FrameLayout;
-
-public class UniverseBackground extends FrameLayout {
- static final String TAG = "UniverseBackground";
- static final boolean SPEW = false;
- static final boolean CHATTY = false;
-
- final IWindowSession mSession;
- final View mContent;
- final View mBottomAnchor;
-
- final Runnable mAnimationCallback = new Runnable() {
- @Override
- public void run() {
- doAnimation(mChoreographer.getFrameTimeNanos());
- }
- };
-
- // fling gesture tuning parameters, scaled to display density
- private float mSelfExpandVelocityPx; // classic value: 2000px/s
- private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
- private float mFlingExpandMinVelocityPx; // classic value: 200px/s
- private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
- private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
- private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
- private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
-
- private float mExpandAccelPx; // classic value: 2000px/s/s
- private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
-
- static final int STATE_CLOSED = 0;
- static final int STATE_OPENING = 1;
- static final int STATE_OPEN = 2;
- private int mState = STATE_CLOSED;
-
- private float mDragStartX, mDragStartY;
- private float mAverageX, mAverageY;
-
- // position
- private int[] mPositionTmp = new int[2];
- private boolean mExpanded;
- private boolean mExpandedVisible;
-
- private boolean mTracking;
- private VelocityTracker mVelocityTracker;
-
- private Choreographer mChoreographer;
- private boolean mAnimating;
- private boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
- private float mAnimY;
- private float mAnimVel;
- private float mAnimAccel;
- private long mAnimLastTimeNanos;
- private boolean mAnimatingReveal = false;
-
- private int mYDelta = 0;
- private Transformation mUniverseTransform = new Transformation();
- private final float[] mTmpFloats = new float[9];
-
- public UniverseBackground(Context context) {
- super(context);
- setBackgroundColor(0xff000000);
- mSession = WindowManagerGlobal.getWindowSession();
- mContent = View.inflate(context, R.layout.universe, null);
- addView(mContent);
- mContent.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
- @Override public void onClick(View v) {
- animateCollapse();
- }
- });
- mBottomAnchor = mContent.findViewById(R.id.bottom);
- mChoreographer = Choreographer.getInstance();
- loadDimens();
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- loadDimens();
- }
-
- private void loadDimens() {
- final Resources res = getContext().getResources();
- mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
- mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
- mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
- mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
-
- mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
- mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
-
- mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
- mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
-
- mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
- }
-
- private void computeAveragePos(MotionEvent event) {
- final int num = event.getPointerCount();
- float x = 0, y = 0;
- for (int i=0; i<num; i++) {
- x += event.getX(i);
- y += event.getY(i);
- }
- mAverageX = x / num;
- mAverageY = y / num;
- }
-
- private void sendUniverseTransform() {
- if (getWindowToken() != null) {
- mUniverseTransform.getMatrix().getValues(mTmpFloats);
- try {
- mSession.setUniverseTransform(getWindowToken(), mUniverseTransform.getAlpha(),
- mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y],
- mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
- mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
- } catch (RemoteException e) {
- }
- }
- }
-
- public WindowManager.LayoutParams getLayoutParams() {
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND,
- 0
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
- PixelFormat.OPAQUE);
- // this will allow the window to run in an overlay on devices that support this
- if (ActivityManager.isHighEndGfx()) {
- lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
- }
- lp.setTitle("UniverseBackground");
- lp.windowAnimations = 0;
- return lp;
- }
-
- private int getExpandedViewMaxHeight() {
- return mBottomAnchor.getTop();
- }
-
- public void animateCollapse() {
- animateCollapse(1.0f);
- }
-
- public void animateCollapse(float velocityMultiplier) {
- if (SPEW) {
- Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
- + " mExpandedVisible=" + mExpandedVisible
- + " mExpanded=" + mExpanded
- + " mAnimating=" + mAnimating
- + " mAnimY=" + mAnimY
- + " mAnimVel=" + mAnimVel);
- }
-
- mState = STATE_CLOSED;
- if (!mExpandedVisible) {
- return;
- }
-
- int y;
- if (mAnimating) {
- y = (int)mAnimY;
- } else {
- y = getExpandedViewMaxHeight()-1;
- }
- // Let the fling think that we're open so it goes in the right direction
- // and doesn't try to re-open the windowshade.
- mExpanded = true;
- prepareTracking(y, false);
- performFling(y, -mSelfCollapseVelocityPx*velocityMultiplier, true);
- }
-
- private void updateUniverseScale() {
- if (mYDelta > 0) {
- int w = getWidth();
- int h = getHeight();
- float scale = (h-mYDelta+.5f) / (float)h;
- mUniverseTransform.getMatrix().setScale(scale, scale, w/2, h);
- if (CHATTY) Log.i(TAG, "w=" + w + " h=" + h + " scale=" + scale
- + ": " + mUniverseTransform);
- sendUniverseTransform();
- if (getVisibility() != VISIBLE) {
- setVisibility(VISIBLE);
- }
- } else {
- if (CHATTY) Log.i(TAG, "mYDelta=" + mYDelta);
- mUniverseTransform.clear();
- sendUniverseTransform();
- if (getVisibility() == VISIBLE) {
- setVisibility(GONE);
- }
- }
- }
-
- void resetLastAnimTime() {
- mAnimLastTimeNanos = System.nanoTime();
- if (SPEW) {
- Throwable t = new Throwable();
- t.fillInStackTrace();
- Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t);
- }
- }
-
- void doAnimation(long frameTimeNanos) {
- if (mAnimating) {
- if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos));
- if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
- incrementAnim(frameTimeNanos);
- if (SPEW) {
- Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY);
- }
-
- if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) {
- if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
- mAnimating = false;
- mYDelta = getExpandedViewMaxHeight();
- updateUniverseScale();
- mExpanded = true;
- mState = STATE_OPEN;
- return;
- }
-
- if (mAnimY <= 0 && mClosing) {
- if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
- mAnimating = false;
- mYDelta = 0;
- updateUniverseScale();
- mExpanded = false;
- mState = STATE_CLOSED;
- return;
- }
-
- mYDelta = (int)mAnimY;
- updateUniverseScale();
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,
- mAnimationCallback, null);
- }
- }
-
- void stopTracking() {
- mTracking = false;
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
-
- void incrementAnim(long frameTimeNanos) {
- final long deltaNanos = Math.max(frameTimeNanos - mAnimLastTimeNanos, 0);
- final float t = deltaNanos * 0.000000001f; // ns -> s
- final float y = mAnimY;
- final float v = mAnimVel; // px/s
- final float a = mAnimAccel; // px/s/s
- mAnimY = y + (v*t) + (0.5f*a*t*t); // px
- mAnimVel = v + (a*t); // px/s
- mAnimLastTimeNanos = frameTimeNanos; // ns
- //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
- // + " mAnimAccel=" + mAnimAccel);
- }
-
- void prepareTracking(int y, boolean opening) {
- if (CHATTY) {
- Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
- }
-
- mTracking = true;
- mVelocityTracker = VelocityTracker.obtain();
- if (opening) {
- mAnimAccel = mExpandAccelPx;
- mAnimVel = mFlingExpandMinVelocityPx;
- mAnimY = y;
- mAnimating = true;
- mAnimatingReveal = true;
- resetLastAnimTime();
- mExpandedVisible = true;
- }
- if (mAnimating) {
- mAnimating = false;
- mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
- mAnimationCallback, null);
- }
- }
-
- void performFling(int y, float vel, boolean always) {
- if (CHATTY) {
- Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel);
- }
-
- mAnimatingReveal = false;
-
- mAnimY = y;
- mAnimVel = vel;
-
- //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
-
- if (mExpanded) {
- if (!always && (
- vel > mFlingCollapseMinVelocityPx
- || (y > (getExpandedViewMaxHeight()*(1f-mCollapseMinDisplayFraction)) &&
- vel > -mFlingExpandMinVelocityPx))) {
- // We are expanded, but they didn't move sufficiently to cause
- // us to retract. Animate back to the expanded position.
- mAnimAccel = mExpandAccelPx;
- if (vel < 0) {
- mAnimVel = 0;
- }
- }
- else {
- // We are expanded and are now going to animate away.
- mAnimAccel = -mCollapseAccelPx;
- if (vel > 0) {
- mAnimVel = 0;
- }
- }
- } else {
- if (always || (
- vel > mFlingExpandMinVelocityPx
- || (y > (getExpandedViewMaxHeight()*(1f-mExpandMinDisplayFraction)) &&
- vel > -mFlingCollapseMinVelocityPx))) {
- // We are collapsed, and they moved enough to allow us to
- // expand. Animate in the notifications.
- mAnimAccel = mExpandAccelPx;
- if (vel < 0) {
- mAnimVel = 0;
- }
- }
- else {
- // We are collapsed, but they didn't move sufficiently to cause
- // us to retract. Animate back to the collapsed position.
- mAnimAccel = -mCollapseAccelPx;
- if (vel > 0) {
- mAnimVel = 0;
- }
- }
- }
- //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
- // + " mAnimAccel=" + mAnimAccel);
-
- resetLastAnimTime();
- mAnimating = true;
- mClosing = mAnimAccel < 0;
- mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
- mAnimationCallback, null);
- mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,
- mAnimationCallback, null);
-
- stopTracking();
- }
-
- private void trackMovement(MotionEvent event) {
- mVelocityTracker.addMovement(event);
- }
-
- public boolean consumeEvent(MotionEvent event) {
- if (mState == STATE_CLOSED) {
- if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- // Second finger down, time to start opening!
- computeAveragePos(event);
- mDragStartX = mAverageX;
- mDragStartY = mAverageY;
- mYDelta = 0;
- mUniverseTransform.clear();
- sendUniverseTransform();
- setVisibility(VISIBLE);
- mState = STATE_OPENING;
- prepareTracking((int)mDragStartY, true);
- mVelocityTracker.clear();
- trackMovement(event);
- return true;
- }
- return false;
- }
-
- if (mState == STATE_OPENING) {
- if (event.getActionMasked() == MotionEvent.ACTION_UP
- || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
- mVelocityTracker.computeCurrentVelocity(1000);
- computeAveragePos(event);
-
- float yVel = mVelocityTracker.getYVelocity();
- boolean negative = yVel < 0;
-
- float xVel = mVelocityTracker.getXVelocity();
- if (xVel < 0) {
- xVel = -xVel;
- }
- if (xVel > mFlingGestureMaxXVelocityPx) {
- xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
- }
-
- float vel = (float)Math.hypot(yVel, xVel);
- if (negative) {
- vel = -vel;
- }
-
- if (CHATTY) {
- Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
- mVelocityTracker.getXVelocity(),
- mVelocityTracker.getYVelocity(),
- xVel, yVel,
- vel));
- }
-
- performFling((int)mAverageY, vel, false);
- mState = STATE_OPEN;
- return true;
- }
-
- computeAveragePos(event);
- mYDelta = (int)(mAverageY - mDragStartY);
- if (mYDelta > getExpandedViewMaxHeight()) {
- mYDelta = getExpandedViewMaxHeight();
- }
- updateUniverseScale();
- return true;
- }
-
- return false;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 0c6e59c..5b4bb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -28,10 +28,9 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
-import android.util.Slog;
+import android.util.Log;
import com.android.systemui.SystemUI;
-import com.google.android.collect.Maps;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -50,7 +49,7 @@
private IAudioService mAudioService;
private final NotificationPlayer mAsyncPlayer = new NotificationPlayer(TAG);
- private final HashMap<IBinder, Client> mClients = Maps.newHashMap();
+ private final HashMap<IBinder, Client> mClients = new HashMap<IBinder, Client>();
@Override
public void start() {
@@ -61,7 +60,7 @@
try {
mAudioService.setRingtonePlayer(mCallback);
} catch (RemoteException e) {
- Slog.e(TAG, "Problem registering RingtonePlayer: " + e);
+ Log.e(TAG, "Problem registering RingtonePlayer: " + e);
}
}
@@ -82,7 +81,7 @@
@Override
public void binderDied() {
- if (LOGD) Slog.d(TAG, "binderDied() token=" + mToken);
+ if (LOGD) Log.d(TAG, "binderDied() token=" + mToken);
synchronized (mClients) {
mClients.remove(mToken);
}
@@ -94,7 +93,7 @@
@Override
public void play(IBinder token, Uri uri, int streamType) throws RemoteException {
if (LOGD) {
- Slog.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+ Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+ Binder.getCallingUid() + ")");
}
Client client;
@@ -112,7 +111,7 @@
@Override
public void stop(IBinder token) {
- if (LOGD) Slog.d(TAG, "stop(token=" + token + ")");
+ if (LOGD) Log.d(TAG, "stop(token=" + token + ")");
Client client;
synchronized (mClients) {
client = mClients.remove(token);
@@ -125,7 +124,7 @@
@Override
public boolean isPlaying(IBinder token) {
- if (LOGD) Slog.d(TAG, "isPlaying(token=" + token + ")");
+ if (LOGD) Log.d(TAG, "isPlaying(token=" + token + ")");
Client client;
synchronized (mClients) {
client = mClients.get(token);
@@ -139,7 +138,7 @@
@Override
public void playAsync(Uri uri, UserHandle user, boolean looping, int streamType) {
- if (LOGD) Slog.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
+ if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Async playback only available from system UID.");
}
@@ -149,7 +148,7 @@
@Override
public void stopAsync() {
- if (LOGD) Slog.d(TAG, "stopAsync()");
+ if (LOGD) Log.d(TAG, "stopAsync()");
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Async playback only available from system UID.");
}
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index 888b76e..1ac8295 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -32,7 +32,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.Slog;
+import android.util.Log;
import android.view.WindowManager;
import com.android.systemui.R;
@@ -79,7 +79,7 @@
try {
policyService.snoozeLimit(template);
} catch (RemoteException e) {
- Slog.w(TAG, "problem snoozing network policy", e);
+ Log.w(TAG, "problem snoozing network policy", e);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index ccb711a..0d26c57 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -35,7 +35,7 @@
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
@@ -126,19 +126,19 @@
int bucket = findBatteryLevelBucket(mBatteryLevel);
if (DEBUG) {
- Slog.d(TAG, "buckets ....." + mLowBatteryAlertCloseLevel
+ Log.d(TAG, "buckets ....." + mLowBatteryAlertCloseLevel
+ " .. " + mLowBatteryReminderLevels[0]
+ " .. " + mLowBatteryReminderLevels[1]);
- Slog.d(TAG, "level " + oldBatteryLevel + " --> " + mBatteryLevel);
- Slog.d(TAG, "status " + oldBatteryStatus + " --> " + mBatteryStatus);
- Slog.d(TAG, "plugType " + oldPlugType + " --> " + mPlugType);
- Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
- Slog.d(TAG, "bucket " + oldBucket + " --> " + bucket);
- Slog.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
+ Log.d(TAG, "level " + oldBatteryLevel + " --> " + mBatteryLevel);
+ Log.d(TAG, "status " + oldBatteryStatus + " --> " + mBatteryStatus);
+ Log.d(TAG, "plugType " + oldPlugType + " --> " + mPlugType);
+ Log.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
+ Log.d(TAG, "bucket " + oldBucket + " --> " + bucket);
+ Log.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
}
if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
- Slog.d(TAG, "showing invalid charger warning");
+ Log.d(TAG, "showing invalid charger warning");
showInvalidChargerDialog();
return;
} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
@@ -164,20 +164,20 @@
showLowBatteryWarning();
}
} else {
- Slog.w(TAG, "unknown intent: " + intent);
+ Log.w(TAG, "unknown intent: " + intent);
}
}
};
void dismissLowBatteryWarning() {
if (mLowBatteryDialog != null) {
- Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
+ Log.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
mLowBatteryDialog.dismiss();
}
}
void showLowBatteryWarning() {
- Slog.i(TAG,
+ Log.i(TAG,
((mBatteryLevelTextView == null) ? "showing" : "updating")
+ " low battery warning: level=" + mBatteryLevel
+ " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
@@ -234,7 +234,7 @@
void playLowBatterySound() {
if (DEBUG) {
- Slog.i(TAG, "playing low battery sound. WOMP-WOMP!");
+ Log.i(TAG, "playing low battery sound. WOMP-WOMP!");
}
final ContentResolver cr = mContext.getContentResolver();
@@ -261,7 +261,7 @@
}
void showInvalidChargerDialog() {
- Slog.d(TAG, "showing invalid charger dialog");
+ Log.d(TAG, "showing invalid charger dialog");
dismissLowBatteryWarning();
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index fdeead1..f5471e5 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -30,7 +30,6 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
-import android.util.Slog;
import android.view.IWindowManager;
import android.widget.CompoundButton;
import android.widget.ImageView;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
index 1075a73..3ab2d9b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
@@ -26,7 +26,7 @@
import android.content.IntentFilter;
import android.os.Handler;
import android.os.UserHandle;
-import android.util.Slog;
+import android.util.Log;
import com.android.systemui.SystemUI;
@@ -42,7 +42,7 @@
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG)) {
- if (DEBUG) Slog.d(TAG, "showing brightness dialog");
+ if (DEBUG) Log.d(TAG, "showing brightness dialog");
if (mBrightnessDialog == null) {
mBrightnessDialog = new BrightnessDialog(mContext);
@@ -59,7 +59,7 @@
}
} else {
- Slog.w(TAG, "unknown intent: " + intent);
+ Log.w(TAG, "unknown intent: " + intent);
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
index c7c361c..e0aefca 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
@@ -21,7 +21,6 @@
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ProgressBar;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index 78226c5..9839fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -20,7 +20,6 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.widget.ImageView;
import android.widget.RemoteViews.RemoteView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index af72936..c96d9c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -62,7 +62,6 @@
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
-import android.util.Slog;
import android.view.Display;
import android.view.IWindowManager;
import android.view.LayoutInflater;
@@ -168,7 +167,7 @@
@Override
public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
if (DEBUG) {
- Slog.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
+ Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
}
final boolean isActivity = pendingIntent.isActivity();
if (isActivity) {
@@ -259,7 +258,7 @@
}
if (DEBUG) {
- Slog.d(TAG, String.format(
+ Log.d(TAG, String.format(
"init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
iconList.size(),
switches[0],
@@ -279,7 +278,7 @@
String action = intent.getAction();
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- if (true) Slog.v(TAG, "userId " + mCurrentUserId + " is in the house");
+ if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
userSwitched(mCurrentUserId);
}
}}, filter);
@@ -295,7 +294,7 @@
final int thisUserId = mCurrentUserId;
final int notificationUserId = n.getUserId();
if (DEBUG && MULTIUSER_DEBUG) {
- Slog.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
+ Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
n, thisUserId, notificationUserId));
}
return notificationUserId == UserHandle.USER_ALL
@@ -348,7 +347,7 @@
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(sbn.getPackageName(), 0);
version = info.targetSdkVersion;
} catch (NameNotFoundException ex) {
- Slog.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
+ Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
}
if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
@@ -643,7 +642,7 @@
};
protected void preloadRecentTasksList() {
- if (DEBUG) Slog.d(TAG, "preloading recents");
+ if (DEBUG) Log.d(TAG, "preloading recents");
Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
intent.setClassName("com.android.systemui",
"com.android.systemui.recent.RecentsPreloadReceiver");
@@ -653,7 +652,7 @@
}
protected void cancelPreloadingRecentTasksList() {
- if (DEBUG) Slog.d(TAG, "cancel preloading recents");
+ if (DEBUG) Log.d(TAG, "cancel preloading recents");
Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
intent.setClassName("com.android.systemui",
"com.android.systemui.recent.RecentsPreloadReceiver");
@@ -667,11 +666,11 @@
Intent intent;
switch (m.what) {
case MSG_TOGGLE_RECENTS_PANEL:
- if (DEBUG) Slog.d(TAG, "toggle recents panel");
+ if (DEBUG) Log.d(TAG, "toggle recents panel");
toggleRecentsActivity();
break;
case MSG_CLOSE_RECENTS_PANEL:
- if (DEBUG) Slog.d(TAG, "closing recents panel");
+ if (DEBUG) Log.d(TAG, "closing recents panel");
intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
intent.setPackage("com.android.systemui");
mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
@@ -683,13 +682,13 @@
cancelPreloadingRecentTasksList();
break;
case MSG_OPEN_SEARCH_PANEL:
- if (DEBUG) Slog.d(TAG, "opening search panel");
+ if (DEBUG) Log.d(TAG, "opening search panel");
if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) {
mSearchPanelView.show(true, true);
}
break;
case MSG_CLOSE_SEARCH_PANEL:
- if (DEBUG) Slog.d(TAG, "closing search panel");
+ if (DEBUG) Log.d(TAG, "closing search panel");
if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
mSearchPanelView.show(false, true);
}
@@ -776,7 +775,7 @@
}
catch (RuntimeException e) {
final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
- Slog.e(TAG, "couldn't inflate view for notification " + ident, e);
+ Log.e(TAG, "couldn't inflate view for notification " + ident, e);
return false;
}
@@ -855,7 +854,7 @@
mIntent.send(mContext, 0, overlay);
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here. Just log the exception message.
- Slog.w(TAG, "Sending contentIntent failed: " + e);
+ Log.w(TAG, "Sending contentIntent failed: " + e);
}
KeyguardManager kgm =
@@ -913,7 +912,7 @@
protected StatusBarNotification removeNotificationViews(IBinder key) {
NotificationData.Entry entry = mNotificationData.remove(key);
if (entry == null) {
- Slog.w(TAG, "removeNotification for unknown key: " + key);
+ Log.w(TAG, "removeNotification for unknown key: " + key);
return null;
}
// Remove the expanded view.
@@ -928,7 +927,7 @@
protected StatusBarIconView addNotificationViews(IBinder key,
StatusBarNotification notification) {
if (DEBUG) {
- Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
+ Log.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
}
// Construct the icon.
final StatusBarIconView iconView = new StatusBarIconView(mContext,
@@ -957,7 +956,7 @@
// Add the expanded view and icon.
int pos = mNotificationData.add(entry);
if (DEBUG) {
- Slog.d(TAG, "addNotificationViews: added at " + pos);
+ Log.d(TAG, "addNotificationViews: added at " + pos);
}
updateExpansionStates();
updateNotificationIcons();
@@ -970,10 +969,10 @@
mContext.getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
ViewGroup.LayoutParams lp = entry.row.getLayoutParams();
if (entry.expandable() && expand) {
- if (DEBUG) Slog.d(TAG, "setting expanded row height to WRAP_CONTENT");
+ if (DEBUG) Log.d(TAG, "setting expanded row height to WRAP_CONTENT");
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
} else {
- if (DEBUG) Slog.d(TAG, "setting collapsed row height to " + rowHeight);
+ if (DEBUG) Log.d(TAG, "setting collapsed row height to " + rowHeight);
lp.height = rowHeight;
}
entry.row.setLayoutParams(lp);
@@ -986,18 +985,18 @@
NotificationData.Entry entry = mNotificationData.get(i);
if (!entry.userLocked()) {
if (i == (N-1)) {
- if (DEBUG) Slog.d(TAG, "expanding top notification at " + i);
+ if (DEBUG) Log.d(TAG, "expanding top notification at " + i);
expandView(entry, true);
} else {
if (!entry.userExpanded()) {
- if (DEBUG) Slog.d(TAG, "collapsing notification at " + i);
+ if (DEBUG) Log.d(TAG, "collapsing notification at " + i);
expandView(entry, false);
} else {
- if (DEBUG) Slog.d(TAG, "ignoring user-modified notification at " + i);
+ if (DEBUG) Log.d(TAG, "ignoring user-modified notification at " + i);
}
}
} else {
- if (DEBUG) Slog.d(TAG, "ignoring notification being held by user at " + i);
+ if (DEBUG) Log.d(TAG, "ignoring notification being held by user at " + i);
}
}
}
@@ -1015,11 +1014,11 @@
}
public void updateNotification(IBinder key, StatusBarNotification notification) {
- if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
+ if (DEBUG) Log.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
if (oldEntry == null) {
- Slog.w(TAG, "updateNotification for unknown key: " + key);
+ Log.w(TAG, "updateNotification for unknown key: " + key);
return;
}
@@ -1032,13 +1031,13 @@
final RemoteViews bigContentView = notification.getNotification().bigContentView;
if (DEBUG) {
- Slog.d(TAG, "old notification: when=" + oldNotification.getNotification().when
+ Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
+ " ongoing=" + oldNotification.isOngoing()
+ " expanded=" + oldEntry.expanded
+ " contentView=" + oldContentView
+ " bigContentView=" + oldBigContentView
+ " rowParent=" + oldEntry.row.getParent());
- Slog.d(TAG, "new notification: when=" + notification.getNotification().when
+ Log.d(TAG, "new notification: when=" + notification.getNotification().when
+ " ongoing=" + oldNotification.isOngoing()
+ " contentView=" + contentView
+ " bigContentView=" + bigContentView);
@@ -1071,7 +1070,7 @@
oldEntry.notification.getNotification().tickerText);
boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) {
- if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
+ if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
oldEntry.notification = notification;
try {
// Reapply the RemoteViews
@@ -1102,15 +1101,15 @@
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
- Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
+ Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
removeNotificationViews(key);
addNotificationViews(key, notification);
}
} else {
- if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
- if (DEBUG) Slog.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Slog.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Slog.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
+ if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
+ if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
+ if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
+ if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
final boolean wasExpanded = oldEntry.userExpanded();
removeNotificationViews(key);
addNotificationViews(key, notification);
@@ -1127,7 +1126,7 @@
// Is this for you?
boolean isForCurrentUser = notificationIsForCurrentUser(notification);
- if (DEBUG) Slog.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
// Restart the ticker if it's still running
if (updateTicker && isForCurrentUser) {
@@ -1141,11 +1140,11 @@
// See if we need to update the intruder.
if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
- if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
+ if (DEBUG) Log.d(TAG, "updating the current intruder:" + notification);
// XXX: this is a hack for Alarms. The real implementation will need to *update*
// the intruder.
if (notification.getNotification().fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
- if (DEBUG) Slog.d(TAG, "no longer intrudes!");
+ if (DEBUG) Log.d(TAG, "no longer intrudes!");
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java b/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java
index 9e44e71..ce67abe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java
@@ -22,7 +22,6 @@
import android.content.SharedPreferences;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.util.Slog;
import com.android.systemui.statusbar.policy.Prefs;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
index 0f894a1..378061f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
@@ -27,7 +27,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
-import android.util.Slog;
+import android.util.Log;
import android.view.MotionEvent;
/**
@@ -46,7 +46,7 @@
public MotionEvent event;
public MotionEventRecord(long when, MotionEvent event) {
this.time = when;
- this.event = event.copy();
+ this.event = MotionEvent.obtain(event);
}
String actionName(int action) {
switch (action) {
@@ -101,7 +101,7 @@
mDownTime = ev.getDownTime();
} else {
if (mDownTime != ev.getDownTime()) {
- Slog.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
+ Log.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
+ev.getDownTime()+") does not match gesture downTime ("+mDownTime+")");
}
}
@@ -237,10 +237,10 @@
mGestures.add(mCurrentGesture);
}
if (DEBUG) {
- Slog.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile));
+ Log.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile));
}
} catch (IOException e) {
- Slog.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e);
+ Log.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e);
mLastSaveLen = -1;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java b/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
deleted file mode 100644
index 735ee25..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CompoundButton;
-
-import com.android.systemui.statusbar.policy.AutoRotateController;
-
-public class RotationToggle extends CompoundButton
- implements AutoRotateController.RotationLockCallbacks {
- private AutoRotateController mRotater;
-
- public RotationToggle(Context context) {
- super(context);
- }
-
- public RotationToggle(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public RotationToggle(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mRotater = new AutoRotateController(getContext(), this, this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mRotater != null) {
- mRotater.release();
- mRotater = null;
- }
- }
-
- @Override
- public void setRotationLockControlVisibility(boolean show) {
- setVisibility(show ? VISIBLE : GONE);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 46916f7..de7f189 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -18,7 +18,7 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
@@ -64,7 +64,7 @@
}
public void setNetworkController(NetworkController nc) {
- if (DEBUG) Slog.d(TAG, "NetworkController=" + nc);
+ if (DEBUG) Log.d(TAG, "NetworkController=" + nc);
mNC = nc;
}
@@ -185,7 +185,7 @@
mWifiGroup.setVisibility(View.GONE);
}
- if (DEBUG) Slog.d(TAG,
+ if (DEBUG) Log.d(TAG,
String.format("wifi: %s sig=%d act=%d",
(mWifiVisible ? "VISIBLE" : "GONE"),
mWifiStrengthId, mWifiActivityId));
@@ -214,7 +214,7 @@
mSpacer.setVisibility(View.GONE);
}
- if (DEBUG) Slog.d(TAG,
+ if (DEBUG) Log.d(TAG,
String.format("mobile: %s sig=%d act=%d typ=%d",
(mMobileVisible ? "VISIBLE" : "GONE"),
mMobileStrengthId, mMobileActivityId, mMobileTypeId));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 39d56a4..54c5e2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -27,7 +27,6 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Slog;
import android.util.Log;
import android.view.ViewDebug;
import android.view.accessibility.AccessibilityEvent;
@@ -151,7 +150,7 @@
private boolean updateDrawable(boolean withClear) {
Drawable drawable = getIcon(mIcon);
if (drawable == null) {
- Slog.w(TAG, "No icon for slot " + mSlot);
+ Log.w(TAG, "No icon for slot " + mSlot);
return false;
}
if (withClear) {
@@ -185,7 +184,7 @@
r = context.getPackageManager()
.getResourcesForApplicationAsUser(icon.iconPackage, userId);
} catch (PackageManager.NameNotFoundException ex) {
- Slog.e(TAG, "Icon package not found: " + icon.iconPackage);
+ Log.e(TAG, "Icon package not found: " + icon.iconPackage);
return null;
}
} else {
@@ -199,7 +198,7 @@
try {
return r.getDrawable(icon.iconId);
} catch (RuntimeException e) {
- Slog.w(TAG, "Icon not found in "
+ Log.w(TAG, "Icon not found in "
+ (icon.iconPackage != null ? icon.iconId : "<system>")
+ ": " + Integer.toHexString(icon.iconId));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
index 66494e4..5fa8126 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
@@ -22,7 +22,7 @@
import android.content.IntentFilter;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.widget.TextView;
@@ -90,7 +90,7 @@
void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
if (false) {
- Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+ Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+ " showPlmn=" + showPlmn + " plmn=" + plmn);
}
final String str;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index 0640282..eae4b7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.widget.LinearLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index fd36da6a..f5867ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -29,7 +29,7 @@
import android.os.Message;
import android.os.ServiceManager;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.animation.AccelerateInterpolator;
import android.view.Display;
import android.view.MotionEvent;
@@ -95,7 +95,7 @@
final int vh = mCurrentView.getHeight();
if (h != vh || w != vw) {
- Slog.w(TAG, String.format(
+ Log.w(TAG, String.format(
"*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
how, w, h, vw, vh));
if (WORKAROUND_INVALID_LAYOUT) {
@@ -318,7 +318,7 @@
mLowProfile = lightsOut;
- if (DEBUG) Slog.d(TAG, "setting lights " + (lightsOut?"out":"on"));
+ if (DEBUG) Log.d(TAG, "setting lights " + (lightsOut?"out":"on"));
final View navButtons = mCurrentView.findViewById(R.id.nav_buttons);
final View lowLights = mCurrentView.findViewById(R.id.lights_out);
@@ -361,7 +361,7 @@
if (hide == mHidden) return;
mHidden = hide;
- Slog.d(TAG,
+ Log.d(TAG,
(hide ? "HIDING" : "SHOWING") + " navigation bar");
// bring up the lights no matter what
@@ -402,7 +402,7 @@
setMenuVisibility(mShowMenu, true /* force */);
if (DEBUG) {
- Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
+ Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
}
setNavigationIconHints(mNavigationIconHints, true);
@@ -416,13 +416,13 @@
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (DEBUG) Slog.d(TAG, String.format(
+ if (DEBUG) Log.d(TAG, String.format(
"onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
final boolean newVertical = w > 0 && h > w;
if (newVertical != mVertical) {
mVertical = newVertical;
- //Slog.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
+ //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
reorient();
}
@@ -433,7 +433,7 @@
/*
@Override
protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- if (DEBUG) Slog.d(TAG, String.format(
+ if (DEBUG) Log.d(TAG, String.format(
"onLayout: %s (%d,%d,%d,%d)",
changed?"changed":"notchanged", left, top, right, bottom));
super.onLayout(changed, left, top, right, bottom);
@@ -443,7 +443,7 @@
// fails, any touch on the display will fix the layout.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DEBUG) Slog.d(TAG, "onInterceptTouchEvent: " + ev.toString());
+ if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
postCheckForInvalidLayout("touch");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index f33dc20..6be6d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -22,7 +22,6 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.EventLog;
-import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 565a3f2..91e1aa0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -20,7 +20,7 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
@@ -30,7 +30,7 @@
public static final String TAG = PanelBar.class.getSimpleName();
public static final void LOG(String fmt, Object... args) {
if (!DEBUG) return;
- Slog.v(TAG, String.format(fmt, args));
+ Log.v(TAG, String.format(fmt, args));
}
public static final int STATE_CLOSED = 0;
@@ -66,7 +66,7 @@
public void setPanelHolder(PanelHolder ph) {
if (ph == null) {
- Slog.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
+ Log.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
return;
}
ph.setBar(this);
@@ -98,7 +98,7 @@
// Allow subclasses to implement enable/disable semantics
if (!panelsEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- Slog.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
+ Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
(int) event.getX(), (int) event.getY()));
}
return false;
@@ -109,7 +109,7 @@
final PanelView panel = selectPanelForTouch(event);
if (panel == null) {
// panel is not there, so we'll eat the gesture
- Slog.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
+ Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
(int) event.getX(), (int) event.getY()));
mTouchingPanel = null;
return true;
@@ -119,7 +119,7 @@
(enabled ? "" : " (disabled)"));
if (!enabled) {
// panel is disabled, so we'll eat the gesture
- Slog.v(TAG, String.format(
+ Log.v(TAG, String.format(
"onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)",
panel, (int) event.getX(), (int) event.getY()));
mTouchingPanel = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index e351429..70cb94a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -27,7 +27,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
@@ -42,7 +42,7 @@
public final void LOG(String fmt, Object... args) {
if (!DEBUG) return;
- Slog.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
+ Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
}
public static final boolean BRAKES = false;
@@ -112,7 +112,7 @@
}
public void computeCurrentVelocity(long timebase) {
if (FlingTracker.DEBUG) {
- Slog.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events");
+ Log.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events");
}
mVX = mVY = 0;
MotionEventCopy last = null;
@@ -127,7 +127,7 @@
final float dx = (event.x - last.x);
final float dy = (event.y - last.y);
if (FlingTracker.DEBUG) {
- Slog.v("FlingTracker", String.format(" [%d] dx=%.1f dy=%.1f dt=%.0f vx=%.1f vy=%.1f",
+ Log.v("FlingTracker", String.format(" [%d] dx=%.1f dy=%.1f dt=%.0f vx=%.1f vy=%.1f",
i,
dx, dy, dt,
(dx/dt),
@@ -147,7 +147,7 @@
mVY /= totalweight;
} else {
if (DEBUG_NAN) {
- Slog.v("FlingTracker", "computeCurrentVelocity warning: totalweight=0",
+ Log.v("FlingTracker", "computeCurrentVelocity warning: totalweight=0",
new Throwable());
}
// so as not to contaminate the velocities with NaN
@@ -155,13 +155,13 @@
}
if (FlingTracker.DEBUG) {
- Slog.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY);
+ Log.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY);
}
}
public float getXVelocity() {
if (Float.isNaN(mVX)) {
if (DEBUG_NAN) {
- Slog.v("FlingTracker", "warning: vx=NaN");
+ Log.v("FlingTracker", "warning: vx=NaN");
}
mVX = 0;
}
@@ -170,7 +170,7 @@
public float getYVelocity() {
if (Float.isNaN(mVY)) {
if (DEBUG_NAN) {
- Slog.v("FlingTracker", "warning: vx=NaN");
+ Log.v("FlingTracker", "warning: vx=NaN");
}
mVY = 0;
}
@@ -307,7 +307,7 @@
post(mStopAnimator);
}
} else {
- Slog.v(TAG, "animationTick called with dtms=" + dtms + "; nothing to do (h="
+ Log.v(TAG, "animationTick called with dtms=" + dtms + "; nothing to do (h="
+ mExpandedHeight + " v=" + mVel + ")");
}
}
@@ -547,7 +547,7 @@
if (Float.isNaN(h)) {
// If a NaN gets in here, it will freeze the Animators.
if (DEBUG_NAN) {
- Slog.v(TAG, "setExpandedHeightInternal: warning: h=NaN, using 0 instead",
+ Log.v(TAG, "setExpandedHeightInternal: warning: h=NaN, using 0 instead",
new Throwable());
}
h = 0;
@@ -586,7 +586,7 @@
if (Float.isNaN(frac)) {
// If a NaN gets in here, it will freeze the Animators.
if (DEBUG_NAN) {
- Slog.v(TAG, "setExpandedFraction: frac=NaN, using 0 instead",
+ Log.v(TAG, "setExpandedFraction: frac=NaN, using 0 instead",
new Throwable());
}
frac = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6b30b2c..97c7b98a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -55,7 +55,6 @@
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
-import android.util.Slog;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -88,6 +87,7 @@
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.DateView;
@@ -161,6 +161,7 @@
BatteryController mBatteryController;
LocationController mLocationController;
NetworkController mNetworkController;
+ RotationLockController mRotationLockController;
int mNaturalBarHeight = -1;
int mIconSize = -1;
@@ -278,7 +279,7 @@
public void onAnimationEnd(Animator animation) {
// double-check to avoid races
if (mStatusBarContents.getAlpha() == 0) {
- if (DEBUG) Slog.d(TAG, "makeIconsInvisible");
+ if (DEBUG) Log.d(TAG, "makeIconsInvisible");
mStatusBarContents.setVisibility(View.INVISIBLE);
}
}
@@ -294,7 +295,7 @@
Settings.Secure.USER_SETUP_COMPLETE,
0 /*default */,
mCurrentUserId);
- if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
+ if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
"selfChange=%s userSetup=%s mUserSetup=%s",
selfChange, userSetup, mUserSetup));
if (mSettingsButton != null && mHasFlipSettings) {
@@ -437,7 +438,7 @@
try {
boolean showNav = mWindowManagerService.hasNavigationBar();
- if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
+ if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
@@ -537,6 +538,7 @@
mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
mNetworkController = new NetworkController(mContext);
mBluetoothController = new BluetoothController(mContext);
+ mRotationLockController = new RotationLockController(mContext);
final SignalClusterView signalCluster =
(SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
@@ -563,7 +565,7 @@
mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
mShowCarrierInPanel = (mCarrierLabel != null);
- if (DEBUG) Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
+ if (DEBUG) Log.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
if (mShowCarrierInPanel) {
mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
@@ -629,7 +631,7 @@
mQS.setService(this);
mQS.setBar(mStatusBarView);
mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
- mLocationController);
+ mLocationController, mRotationLockController);
} else {
mQS = null; // fly away, be free
}
@@ -815,7 +817,7 @@
// For small-screen devices (read: phones) that lack hardware navigation buttons
private void addNavigationBar() {
- if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
+ if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
@@ -894,7 +896,7 @@
}
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
- if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " icon=" + icon);
StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
@@ -903,19 +905,19 @@
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon) {
- if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " old=" + old + " icon=" + icon);
StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
view.set(icon);
}
public void removeIcon(String slot, int index, int viewIndex) {
- if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
+ if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
mStatusIcons.removeViewAt(viewIndex);
}
public void addNotification(IBinder key, StatusBarNotification notification) {
- if (DEBUG) Slog.d(TAG, "addNotification score=" + notification.getScore());
+ if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
StatusBarIconView iconView = addNotificationViews(key, notification);
if (iconView == null) return;
@@ -923,7 +925,7 @@
try {
immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
if (DEBUG) {
- Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
+ Log.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
}
} catch (RemoteException ex) {
}
@@ -933,12 +935,12 @@
if (ENABLE_INTRUDERS && (
// TODO(dsandler): Only if the screen is on
notification.notification.intruderView != null)) {
- Slog.d(TAG, "Presenting high-priority notification");
+ Log.d(TAG, "Presenting high-priority notification");
// special new transient ticker mode
// 1. Populate mIntruderAlertView
if (notification.notification.intruderView == null) {
- Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
+ Log.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
return;
}
@@ -970,7 +972,7 @@
awakenDreams();
// not immersive & a full-screen alert should be shown
- if (DEBUG) Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
+ if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
try {
notification.getNotification().fullScreenIntent.send();
} catch (PendingIntent.CanceledException e) {
@@ -991,7 +993,7 @@
public void removeNotification(IBinder key) {
StatusBarNotification old = removeNotificationViews(key);
- if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
+ if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null) {
// Cancel the ticker if it's still running
@@ -1096,7 +1098,7 @@
int N = mNotificationData.size();
if (DEBUG) {
- Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
+ Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
}
ArrayList<View> toShow = new ArrayList<View>();
@@ -1136,7 +1138,7 @@
// The idea here is to only show the carrier label when there is enough room to see it,
// i.e. when there aren't enough notifications to fill the panel.
if (DEBUG) {
- Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
+ Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
}
@@ -1149,7 +1151,7 @@
if (force || mCarrierLabelVisible != makeVisible) {
mCarrierLabelVisible = makeVisible;
if (DEBUG) {
- Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
+ Log.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
}
mCarrierLabel.animate().cancel();
if (makeVisible) {
@@ -1180,7 +1182,7 @@
final boolean clearable = any && mNotificationData.hasClearableItems();
if (DEBUG) {
- Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
+ Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
+ " any=" + any + " clearable=" + clearable);
}
@@ -1257,7 +1259,7 @@
mDisabled = state;
if (DEBUG) {
- Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
+ Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
old, state, diff));
}
@@ -1284,7 +1286,7 @@
flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
flagdbg.append(((diff & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
flagdbg.append(">");
- Slog.d(TAG, flagdbg.toString());
+ Log.d(TAG, flagdbg.toString());
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
mSystemIconArea.animate().cancel();
@@ -1407,7 +1409,7 @@
};
void makeExpandedVisible(boolean revealAfterDraw) {
- if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
+ if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
if (mExpandedVisible) {
return;
}
@@ -1446,7 +1448,7 @@
public void animateCollapsePanels(int flags) {
if (SPEW) {
- Slog.d(TAG, "animateCollapse():"
+ Log.d(TAG, "animateCollapse():"
+ " mExpandedVisible=" + mExpandedVisible
+ " flags=" + flags);
}
@@ -1514,7 +1516,7 @@
@Override
public void animateExpandNotificationsPanel() {
- if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
+ if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
return ;
}
@@ -1569,7 +1571,7 @@
@Override
public void animateExpandSettingsPanel() {
- if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
+ if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
return;
}
@@ -1668,7 +1670,7 @@
}
void makeExpandedInvisible() {
- if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
+ if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
+ " mExpandedVisible=" + mExpandedVisible);
if (!mExpandedVisible) {
@@ -1839,11 +1841,11 @@
}
if (SPEW) {
- Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
+ Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
+ mDisabled + " mTracking=" + mTracking);
} else if (CHATTY) {
if (event.getAction() != MotionEvent.ACTION_MOVE) {
- Slog.d(TAG, String.format(
+ Log.d(TAG, String.format(
"panel: %s at (%f, %f) mDisabled=0x%08x",
MotionEvent.actionToString(event.getAction()),
event.getRawX(), event.getRawY(), mDisabled));
@@ -1893,7 +1895,7 @@
final int oldVal = mSystemUiVisibility;
final int newVal = (oldVal&~mask) | (vis&mask);
final int diff = newVal ^ oldVal;
- if (DEBUG) Slog.d(TAG, String.format(
+ if (DEBUG) Log.d(TAG, String.format(
"setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
Integer.toHexString(vis), Integer.toHexString(mask),
Integer.toHexString(oldVal), Integer.toHexString(newVal),
@@ -1956,7 +1958,7 @@
}
private void setHideybarConfirmationVisible(boolean visible) {
- if (DEBUG) Slog.d(TAG, "setHideybarConfirmationVisible " + visible);
+ if (DEBUG) Log.d(TAG, "setHideybarConfirmationVisible " + visible);
if (visible && mHideybarConfirmation == null && !mHideybarConfirmationDismissed) {
// create the confirmation toast bar with the correct message for this config
float widthDp = mCurrentDisplaySize.x /
@@ -2013,7 +2015,7 @@
private void setTransparent(View view, boolean transparent) {
float alpha = transparent ? TRANSPARENT_ALPHA : 1;
- if (DEBUG) Slog.d(TAG, "Setting " + (view == mStatusBarView ? "status bar" :
+ if (DEBUG) Log.d(TAG, "Setting " + (view == mStatusBarView ? "status bar" :
view == mNavigationBarView ? "navigation bar" : "view") + " alpha to " + alpha);
view.setAlpha(alpha);
}
@@ -2081,7 +2083,7 @@
public void topAppWindowChanged(boolean showMenu) {
if (DEBUG) {
- Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
+ Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
}
if (mNavigationBarView != null) {
mNavigationBarView.setMenuVisibility(showMenu);
@@ -2244,7 +2246,7 @@
mHandler.post(new Runnable() {
public void run() {
mStatusBarView.getLocationOnScreen(mAbsPos);
- Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+ Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+ ") " + mStatusBarView.getWidth() + "x"
+ getStatusBarHeight());
mStatusBarView.debug();
@@ -2316,7 +2318,7 @@
@Override
public void updateExpandedViewPos(int thingy) {
- if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
+ if (DEBUG) Log.v(TAG, "updateExpandedViewPos");
// on larger devices, the notification panel is propped open a bit
mNotificationPanel.setMinimumHeight(
@@ -2384,7 +2386,7 @@
@Override
public void run() {
if (DEBUG) {
- Slog.v(TAG, "running post-collapse cleanup");
+ Log.v(TAG, "running post-collapse cleanup");
}
try {
mPile.setViewRemoval(true);
@@ -2462,7 +2464,7 @@
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
- if (DEBUG) Slog.v(TAG, "onReceive: " + intent);
+ if (DEBUG) Log.v(TAG, "onReceive: " + intent);
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
int flags = CommandQueue.FLAG_EXCLUDE_NONE;
@@ -2481,7 +2483,7 @@
}
else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
if (DEBUG) {
- Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
+ Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
}
mDisplay.getSize(mCurrentDisplaySize);
@@ -2518,7 +2520,7 @@
private void setIntruderAlertVisibility(boolean vis) {
if (!ENABLE_INTRUDERS) return;
if (DEBUG) {
- Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
+ Log.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
}
mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
}
@@ -2569,7 +2571,7 @@
R.dimen.status_bar_icon_padding);
if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
-// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
+// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
mIconHPadding = newIconHPadding;
mIconSize = newIconSize;
//reloadAllNotificationIcons(); // reload the tray
@@ -2614,7 +2616,7 @@
mNotificationPanelMinHeightFrac = 0f;
}
- if (false) Slog.v(TAG, "updateResources");
+ if (false) Log.v(TAG, "updateResources");
}
//
@@ -2635,7 +2637,7 @@
public void run() {
vibrate();
SystemClock.sleep(250);
- Slog.d(TAG, "startTracing");
+ Log.d(TAG, "startTracing");
android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
mHandler.postDelayed(mStopTracing, 10000);
}
@@ -2644,7 +2646,7 @@
Runnable mStopTracing = new Runnable() {
public void run() {
android.os.Debug.stopMethodTracing();
- Slog.d(TAG, "stopTracing");
+ Log.d(TAG, "stopTracing");
vibrate();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 9b8bd22..80734ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -36,7 +36,7 @@
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccCardConstants;
@@ -284,17 +284,17 @@
final String action = intent.getAction();
final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
- if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
+ if (false) Log.v(TAG, "updateTTY: enabled: " + enabled);
if (enabled) {
// TTY is on
- if (false) Slog.v(TAG, "updateTTY: set TTY on");
+ if (false) Log.v(TAG, "updateTTY: set TTY on");
mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0,
mContext.getString(R.string.accessibility_tty_enabled));
mService.setIconVisibility("tty", true);
} else {
// TTY is off
- if (false) Slog.v(TAG, "updateTTY: set TTY off");
+ if (false) Log.v(TAG, "updateTTY: set TTY off");
mService.setIconVisibility("tty", false);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index de9f750..2a65381 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -23,7 +23,7 @@
import android.content.res.Resources.NotFoundException;
import android.util.AttributeSet;
import android.util.EventLog;
-import android.util.Slog;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
@@ -128,7 +128,7 @@
float region = (w * mSettingsPanelDragzoneFrac);
if (DEBUG) {
- Slog.v(TAG, String.format(
+ Log.v(TAG, String.format(
"w=%.1f frac=%.3f region=%.1f min=%.1f x=%.1f w-x=%.1f",
w, mSettingsPanelDragzoneFrac, region, mSettingsPanelDragzoneMin, x, (w-x)));
}
@@ -152,7 +152,7 @@
// which is kind of tricky to determine
mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded());
if (DEBUG) {
- Slog.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
+ Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
}
mFadingPanel = panel;
}
@@ -202,7 +202,7 @@
super.panelExpansionChanged(panel, frac);
if (DEBUG) {
- Slog.v(TAG, "panelExpansionChanged: f=" + frac);
+ Log.v(TAG, "panelExpansionChanged: f=" + frac);
}
if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 85bcd8b..b20a8bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.phone;
-import com.android.internal.view.RotationPolicy;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
@@ -28,6 +27,7 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RotationLockController;
import android.app.ActivityManagerNative;
import android.app.AlertDialog;
@@ -73,7 +73,6 @@
import java.util.ArrayList;
-
/**
*
*/
@@ -97,6 +96,7 @@
private WifiManager mWifiManager;
private BluetoothController mBluetoothController;
+ private RotationLockController mRotationLockController;
private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
@@ -113,14 +113,6 @@
private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
new ArrayList<QuickSettingsTileView>();
- private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
- new RotationPolicy.RotationPolicyListener() {
- @Override
- public void onChange() {
- mModel.onRotationLockChanged();
- }
- };
-
public QuickSettings(Context context, QuickSettingsContainerView container) {
mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
mContext = context;
@@ -170,8 +162,10 @@
}
void setup(NetworkController networkController, BluetoothController bluetoothController,
- BatteryController batteryController, LocationController locationController) {
+ BatteryController batteryController, LocationController locationController,
+ RotationLockController rotationLockController) {
mBluetoothController = bluetoothController;
+ mRotationLockController = rotationLockController;
setupQuickSettings();
updateWifiDisplayStatus();
@@ -181,8 +175,7 @@
bluetoothController.addStateChangedCallback(mModel);
batteryController.addStateChangedCallback(mModel);
locationController.addStateChangedCallback(mModel);
- RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener,
- UserHandle.USER_ALL);
+ rotationLockController.addRotationLockControllerCallback(mModel);
}
private void queryForUserInformation() {
@@ -471,13 +464,29 @@
= new QuickSettingsBasicTile(mContext);
rotationLockTile.setOnClickListener(new View.OnClickListener() {
@Override
- public void onClick(View v) {
- boolean locked = RotationPolicy.isRotationLocked(mContext);
- RotationPolicy.setRotationLock(mContext, !locked);
+ public void onClick(View view) {
+ final boolean locked = mRotationLockController.isRotationLocked();
+ mRotationLockController.setRotationLocked(!locked);
}
});
- mModel.addRotationLockTile(rotationLockTile,
- new QuickSettingsModel.BasicRefreshCallback(rotationLockTile));
+ mModel.addRotationLockTile(rotationLockTile, mRotationLockController,
+ new QuickSettingsModel.RefreshCallback() {
+ @Override
+ public void refreshView(QuickSettingsTileView view, State state) {
+ QuickSettingsModel.RotationLockState rotationLockState =
+ (QuickSettingsModel.RotationLockState) state;
+ view.setVisibility(rotationLockState.visible
+ ? View.VISIBLE : View.GONE);
+ if (state.iconId != 0) {
+ // needed to flush any cached IDs
+ rotationLockTile.setImageDrawable(null);
+ rotationLockTile.setImageResource(state.iconId);
+ }
+ if (state.label != null) {
+ rotationLockTile.setText(state.label);
+ }
+ }
+ });
parent.addView(rotationLockTile);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 38c46c4..cdfd52e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -39,22 +39,23 @@
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
-import com.android.internal.view.RotationPolicy;
import com.android.systemui.R;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.settings.BrightnessController.BrightnessStateChangeCallback;
+import com.android.systemui.statusbar.policy.RotationLockController;
+import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
import java.util.List;
-
class QuickSettingsModel implements BluetoothStateChangeCallback,
NetworkSignalChangedCallback,
BatteryStateChangeCallback,
LocationGpsStateChangeCallback,
- BrightnessStateChangeCallback {
+ BrightnessStateChangeCallback,
+ RotationLockControllerCallback {
// Sett InputMethoManagerService
private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
@@ -89,6 +90,9 @@
boolean connected = false;
String stateContentDescription;
}
+ public static class RotationLockState extends State {
+ boolean visible = false;
+ }
/** The callback to update a given tile. */
interface RefreshCallback {
@@ -245,7 +249,7 @@
private QuickSettingsTileView mRotationLockTile;
private RefreshCallback mRotationLockCallback;
- private State mRotationLockState = new State();
+ private RotationLockState mRotationLockState = new RotationLockState();
private QuickSettingsTileView mBrightnessTile;
private RefreshCallback mBrightnessCallback;
@@ -259,6 +263,8 @@
private RefreshCallback mSettingsCallback;
private State mSettingsState = new State();
+ private RotationLockController mRotationLockController;
+
public QuickSettingsModel(Context context) {
mContext = context;
mHandler = new Handler();
@@ -681,25 +687,29 @@
}
// Rotation lock
- void addRotationLockTile(QuickSettingsTileView view, RefreshCallback cb) {
+ void addRotationLockTile(QuickSettingsTileView view,
+ RotationLockController rotationLockController,
+ RefreshCallback cb) {
mRotationLockTile = view;
mRotationLockCallback = cb;
+ mRotationLockController = rotationLockController;
onRotationLockChanged();
}
void onRotationLockChanged() {
- boolean locked = RotationPolicy.isRotationLocked(mContext);
- mRotationLockState.enabled = locked;
- mRotationLockState.iconId = locked
+ onRotationLockStateChanged(mRotationLockController.isRotationLocked(),
+ mRotationLockController.isRotationLockAffordanceVisible());
+ }
+ @Override
+ public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
+ mRotationLockState.visible = affordanceVisible;
+ mRotationLockState.enabled = rotationLocked;
+ mRotationLockState.iconId = rotationLocked
? R.drawable.ic_qs_rotation_locked
: R.drawable.ic_qs_auto_rotate;
- mRotationLockState.label = locked
+ mRotationLockState.label = rotationLocked
? mContext.getString(R.string.quick_settings_rotation_locked_label)
: mContext.getString(R.string.quick_settings_rotation_unlocked_label);
-
- // may be called before addRotationLockTile due to RotationPolicyListener in QuickSettings
- if (mRotationLockTile != null && mRotationLockCallback != null) {
- mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
- }
+ mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
}
void refreshRotationLockTile() {
if (mRotationLockTile != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index 33335631..1897589 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -38,6 +38,7 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RotationLockController;
public class SettingsPanelView extends PanelView {
public static final boolean DEBUG_GESTURES = true;
@@ -85,10 +86,11 @@
}
public void setup(NetworkController networkController, BluetoothController bluetoothController,
- BatteryController batteryController, LocationController locationController) {
+ BatteryController batteryController, LocationController locationController,
+ RotationLockController rotationLockController) {
if (mQS != null) {
mQS.setup(networkController, bluetoothController, batteryController,
- locationController);
+ locationController, rotationLockController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index f3f6a80..b1ccd00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -33,7 +33,6 @@
import java.util.ArrayList;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.util.CharSequences;
import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -192,7 +191,7 @@
if (n.getPackageName().equals(seg.notification.getPackageName())
&& n.getNotification().icon == seg.notification.getNotification().icon
&& n.getNotification().iconLevel == seg.notification.getNotification().iconLevel
- && CharSequences.equals(seg.notification.getNotification().tickerText,
+ && charSequencesEqual(seg.notification.getNotification().tickerText,
n.getNotification().tickerText)) {
return;
}
@@ -232,6 +231,20 @@
}
}
+ private static boolean charSequencesEqual(CharSequence a, CharSequence b) {
+ if (a.length() != b.length()) {
+ return false;
+ }
+
+ int length = a.length();
+ for (int i = 0; i < length; i++) {
+ if (a.charAt(i) != b.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public void removeEntry(StatusBarNotification n) {
for (int i=mSegments.size()-1; i>=0; i--) {
Segment seg = mSegments.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
index d2ed5ff..f3cf65c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
index 3c8276d..71a7aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
@@ -26,7 +26,6 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.util.Slog;
import android.widget.CompoundButton;
public class AirplaneModeController extends BroadcastReceiver
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
deleted file mode 100644
index 7d58032..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.policy;
-
-import com.android.internal.view.RotationPolicy;
-
-import android.content.Context;
-import android.os.UserHandle;
-import android.widget.CompoundButton;
-
-public final class AutoRotateController implements CompoundButton.OnCheckedChangeListener {
- private final Context mContext;
- private final CompoundButton mCheckbox;
- private final RotationLockCallbacks mCallbacks;
-
- private boolean mAutoRotation;
-
- private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
- new RotationPolicy.RotationPolicyListener() {
- @Override
- public void onChange() {
- updateState();
- }
- };
-
- public AutoRotateController(Context context, CompoundButton checkbox,
- RotationLockCallbacks callbacks) {
- mContext = context;
- mCheckbox = checkbox;
- mCallbacks = callbacks;
-
- mCheckbox.setOnCheckedChangeListener(this);
-
- RotationPolicy.registerRotationPolicyListener(context, mRotationPolicyListener,
- UserHandle.USER_ALL);
- updateState();
- }
-
- public void onCheckedChanged(CompoundButton view, boolean checked) {
- if (checked != mAutoRotation) {
- mAutoRotation = checked;
- RotationPolicy.setRotationLock(mContext, !checked);
- }
- }
-
- public void release() {
- RotationPolicy.unregisterRotationPolicyListener(mContext,
- mRotationPolicyListener);
- }
-
- private void updateState() {
- mAutoRotation = !RotationPolicy.isRotationLocked(mContext);
- mCheckbox.setChecked(mAutoRotation);
-
- boolean visible = RotationPolicy.isRotationLockToggleVisible(mContext);
- mCallbacks.setRotationLockControlVisibility(visible);
- mCheckbox.setEnabled(visible);
- }
-
- public interface RotationLockCallbacks {
- void setRotationLockControlVisibility(boolean show);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 716341f..0f56ba6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -24,7 +24,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
-import android.util.Slog;
import android.widget.ImageView;
import android.widget.TextView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index bff6cda..91a1a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -34,7 +34,6 @@
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.widget.TextView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
index 2d951c2..3083e8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
@@ -21,7 +21,7 @@
import android.content.res.TypedArray;
import android.os.RemoteException;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -55,7 +55,7 @@
}
final boolean vis = (mode != ActivityManager.COMPAT_MODE_NEVER
&& mode != ActivityManager.COMPAT_MODE_ALWAYS);
- if (DEBUG) Slog.d(TAG, "compat mode is " + mode + "; icon will " + (vis ? "show" : "hide"));
+ if (DEBUG) Log.d(TAG, "compat mode is " + mode + "; icon will " + (vis ? "show" : "hide"));
setVisibility(vis ? View.VISIBLE : View.GONE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 6eb88be..dca5e41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -22,7 +22,7 @@
import android.graphics.Canvas;
import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -75,7 +75,7 @@
mVertical = (index == VERTICAL);
if (DEBUG)
- Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+ Log.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+ (mVertical ? " vertical" : " horizontal"));
setFlashOnTouchCapture(context.getResources().getBoolean(R.bool.config_dead_zone_flash));
@@ -106,7 +106,7 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
if (DEBUG) {
- Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
+ Log.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
}
final int action = event.getAction();
@@ -114,12 +114,12 @@
poke(event);
} else if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG) {
- Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
+ Log.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
}
int size = (int) getSize(event.getEventTime());
if ((mVertical && event.getX() < size) || event.getY() < size) {
if (CHATTY) {
- Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
+ Log.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
}
if (mShouldFlash) {
post(mDebugFlash);
@@ -134,7 +134,7 @@
public void poke(MotionEvent event) {
mLastPokeTime = event.getEventTime();
if (DEBUG)
- Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
+ Log.v(TAG, "poked! size=" + getSize(mLastPokeTime));
if (mShouldFlash) postInvalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java
index 94c8aa5..d45a94f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java
@@ -22,7 +22,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
import android.view.IWindowManager;
import android.widget.CompoundButton;
@@ -52,7 +52,7 @@
// The checkbox is ON for notifications coming in and OFF for Do not disturb, so we
// don't have a double negative.
public void onCheckedChanged(CompoundButton view, boolean checked) {
- //Slog.d(TAG, "onCheckedChanged checked=" + checked + " mDoNotDisturb=" + mDoNotDisturb);
+ //Log.d(TAG, "onCheckedChanged checked=" + checked + " mDoNotDisturb=" + mDoNotDisturb);
final boolean value = !checked;
if (value != mDoNotDisturb) {
SharedPreferences.Editor editor = Prefs.edit(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
index 47e758c..4de4241 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
@@ -25,7 +25,6 @@
import android.os.SystemClock;
import android.os.ServiceManager;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
import android.view.InputDevice;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
index 0e8095c..3751399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
@@ -20,7 +20,6 @@
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
-import android.util.Slog;
public class FixedSizeDrawable extends Drawable {
Drawable mDrawable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
index ee5c863..9b96384 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
@@ -28,7 +28,6 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
-import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
@@ -102,7 +101,7 @@
}
public void onChildDismissed(View v) {
- Slog.v(TAG, "User swiped intruder to dismiss");
+ Log.v(TAG, "User swiped intruder to dismiss");
mBar.dismissIntruder();
}
@@ -134,7 +133,7 @@
public void onDraw(android.graphics.Canvas c) {
super.onDraw(c);
if (DEBUG) {
- //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+ //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
// + getMeasuredHeight() + "px");
c.save();
c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
@@ -146,7 +145,7 @@
public void applyIntruderContent(RemoteViews intruderView, OnClickListener listener) {
if (DEBUG) {
- Slog.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
+ Log.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
}
mIntruderRemoteViews = intruderView;
mOnClickListener = listener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 82d6a99..db0e4c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -61,7 +61,7 @@
Runnable mCheckLongPress = new Runnable() {
public void run() {
if (isPressed()) {
- // Slog.d("KeyButtonView", "longpressed: " + this);
+ // Log.d("KeyButtonView", "longpressed: " + this);
if (mCode != 0) {
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
@@ -213,7 +213,7 @@
switch (action) {
case MotionEvent.ACTION_DOWN:
- //Slog.d("KeyButtonView", "press");
+ //Log.d("KeyButtonView", "press");
mDownTime = SystemClock.uptimeMillis();
setPressed(true);
if (mCode != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 3619587..57c347b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -37,7 +37,7 @@
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -429,7 +429,7 @@
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
if (DEBUG) {
- Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
+ Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
}
mSignalStrength = signalStrength;
@@ -440,7 +440,7 @@
@Override
public void onServiceStateChanged(ServiceState state) {
if (DEBUG) {
- Slog.d(TAG, "onServiceStateChanged state=" + state.getState());
+ Log.d(TAG, "onServiceStateChanged state=" + state.getState());
}
mServiceState = state;
updateTelephonySignalStrength();
@@ -452,7 +452,7 @@
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (DEBUG) {
- Slog.d(TAG, "onCallStateChanged state=" + state);
+ Log.d(TAG, "onCallStateChanged state=" + state);
}
// In cdma, if a voice call is made, RSSI should switch to 1x.
if (isCdma()) {
@@ -464,7 +464,7 @@
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
if (DEBUG) {
- Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
+ Log.d(TAG, "onDataConnectionStateChanged: state=" + state
+ " type=" + networkType);
}
mDataState = state;
@@ -477,7 +477,7 @@
@Override
public void onDataActivity(int direction) {
if (DEBUG) {
- Slog.d(TAG, "onDataActivity: direction=" + direction);
+ Log.d(TAG, "onDataActivity: direction=" + direction);
}
mDataActivity = direction;
updateDataIcon();
@@ -539,13 +539,13 @@
private final void updateTelephonySignalStrength() {
if (!hasService()) {
- if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: !hasService()");
+ if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
mDataSignalIconId = R.drawable.stat_sys_signal_null;
} else {
if (mSignalStrength == null) {
- if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
+ if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
mDataSignalIconId = R.drawable.stat_sys_signal_null;
@@ -556,7 +556,7 @@
int[] iconList;
if (isCdma() && mAlwaysShowCdmaRssi) {
mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
- if(DEBUG) Slog.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+ if(DEBUG) Log.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+ " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
+ " instead of level=" + mSignalStrength.getLevel());
} else {
@@ -798,7 +798,7 @@
void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
if (false) {
- Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+ Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+ " showPlmn=" + showPlmn + " plmn=" + plmn);
}
StringBuilder str = new StringBuilder();
@@ -832,7 +832,7 @@
mWifiChannel.sendMessage(Message.obtain(this,
AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
} else {
- Slog.e(TAG, "Failed to connect to wifi");
+ Log.e(TAG, "Failed to connect to wifi");
}
break;
case WifiManager.DATA_ACTIVITY_NOTIFICATION:
@@ -964,7 +964,7 @@
private void updateConnectivity(Intent intent) {
if (CHATTY) {
- Slog.d(TAG, "updateConnectivity: intent=" + intent);
+ Log.d(TAG, "updateConnectivity: intent=" + intent);
}
final ConnectivityManager connManager = (ConnectivityManager) mContext
@@ -984,8 +984,8 @@
int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
if (CHATTY) {
- Slog.d(TAG, "updateConnectivity: networkInfo=" + info);
- Slog.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
+ Log.d(TAG, "updateConnectivity: networkInfo=" + info);
+ Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
}
mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
@@ -1173,7 +1173,7 @@
}
if (DEBUG) {
- Slog.d(TAG, "refreshViews connected={"
+ Log.d(TAG, "refreshViews connected={"
+ (mWifiConnected?" wifi":"")
+ (mDataConnected?" data":"")
+ " } level="
@@ -1312,7 +1312,7 @@
// the data direction overlay
if (mLastDataDirectionOverlayIconId != combinedActivityIconId) {
if (DEBUG) {
- Slog.d(TAG, "changing data overlay icon id to " + combinedActivityIconId);
+ Log.d(TAG, "changing data overlay icon id to " + combinedActivityIconId);
}
mLastDataDirectionOverlayIconId = combinedActivityIconId;
N = mDataDirectionOverlayIconViews.size();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 89eed1b..9bf1c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -27,7 +27,6 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
-import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -87,11 +86,11 @@
setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View parent, View child) {
- Slog.d(TAG, "view added: " + child + "; new count: " + getChildCount());
+ Log.d(TAG, "view added: " + child + "; new count: " + getChildCount());
}
@Override
public void onChildViewRemoved(View parent, View child) {
- Slog.d(TAG, "view removed: " + child + "; new count: " + (getChildCount() - 1));
+ Log.d(TAG, "view removed: " + child + "; new count: " + (getChildCount() - 1));
}
});
@@ -167,7 +166,7 @@
}
public void onChildDismissed(View v) {
- if (DEBUG) Slog.v(TAG, "onChildDismissed: " + v + " mRemoveViews=" + mRemoveViews);
+ if (DEBUG) Log.v(TAG, "onChildDismissed: " + v + " mRemoveViews=" + mRemoveViews);
final View veto = v.findViewById(R.id.veto);
if (veto != null && veto.getVisibility() != View.GONE && mRemoveViews) {
veto.performClick();
@@ -231,7 +230,7 @@
* get removed properly.
*/
public void setViewRemoval(boolean removeViews) {
- if (DEBUG) Slog.v(TAG, "setViewRemoval: " + removeViews);
+ if (DEBUG) Log.v(TAG, "setViewRemoval: " + removeViews);
mRemoveViews = removeViews;
}
@@ -266,7 +265,7 @@
super.onDraw(c);
if (DEBUG) logLayoutTransition();
if (DEBUG) {
- //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+ //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
// + getMeasuredHeight() + "px");
c.save();
c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
new file mode 100644
index 0000000..6f61ec8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.internal.view.RotationPolicy;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public final class RotationLockController {
+ private final Context mContext;
+ private final CopyOnWriteArrayList<RotationLockControllerCallback> mCallbacks =
+ new CopyOnWriteArrayList<RotationLockControllerCallback>();
+
+ private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
+ new RotationPolicy.RotationPolicyListener() {
+ @Override
+ public void onChange() {
+ notifyChanged();
+ }
+ };
+
+ public interface RotationLockControllerCallback {
+ public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible);
+ }
+
+ public RotationLockController(Context context) {
+ mContext = context;
+ notifyChanged();
+ if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+ RotationPolicy.registerRotationPolicyListener(mContext,
+ mRotationPolicyListener, UserHandle.USER_ALL);
+ }
+ }
+
+ public void addRotationLockControllerCallback(RotationLockControllerCallback callback) {
+ mCallbacks.add(callback);
+ }
+
+ public boolean isRotationLocked() {
+ if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+ return RotationPolicy.isRotationLocked(mContext);
+ }
+ return false;
+ }
+
+ public void setRotationLocked(boolean locked) {
+ if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+ RotationPolicy.setRotationLock(mContext, locked);
+ }
+ }
+
+ public boolean isRotationLockAffordanceVisible() {
+ if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+ return RotationPolicy.isRotationLockToggleVisible(mContext);
+ }
+ return false;
+ }
+
+ public void release() {
+ if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+ RotationPolicy.unregisterRotationPolicyListener(mContext,
+ mRotationPolicyListener);
+ }
+ }
+
+ private void notifyChanged() {
+ for (RotationLockControllerCallback callback : mCallbacks) {
+ callback.onRotationLockStateChanged(RotationPolicy.isRotationLocked(mContext),
+ RotationPolicy.isRotationLockToggleVisible(mContext));
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
index 70f9ac8..3e138d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -23,7 +23,6 @@
import android.os.Vibrator;
import android.media.AudioManager;
import android.provider.Settings;
-import android.util.Slog;
import android.view.IWindowManager;
import android.widget.CompoundButton;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
index 8c4ae19..080cbd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
@@ -21,7 +21,6 @@
import android.content.res.TypedArray;
import android.os.RemoteException;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java
index 3d6c1a2..4f3c4d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java
@@ -20,7 +20,6 @@
import android.content.res.Resources;
import android.os.Handler;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
index 9ecb2e4..51980dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
@@ -26,7 +26,6 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 87fc6fc..585c067 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -23,7 +23,7 @@
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -224,7 +224,7 @@
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- if (DEBUG) Slog.d(TAG, String.format("PANEL: onLayout: (%d, %d, %d, %d)", l, t, r, b));
+ if (DEBUG) Log.d(TAG, String.format("PANEL: onLayout: (%d, %d, %d, %d)", l, t, r, b));
}
@Override
@@ -232,7 +232,7 @@
super.onSizeChanged(w, h, oldw, oldh);
if (DEBUG) {
- Slog.d(TAG, String.format("PANEL: onSizeChanged: (%d -> %d, %d -> %d)",
+ Log.d(TAG, String.format("PANEL: onSizeChanged: (%d -> %d, %d -> %d)",
oldw, w, oldh, h));
}
}
@@ -390,7 +390,7 @@
}
void startAnimation(boolean appearing) {
- if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")");
+ if (DEBUG) Log.d(TAG, "startAnimation(appearing=" + appearing + ")");
createAnimation(appearing);
mContentAnim.start();
@@ -402,11 +402,11 @@
}
public void onAnimationCancel(Animator animation) {
- if (DEBUG) Slog.d(TAG, "onAnimationCancel");
+ if (DEBUG) Log.d(TAG, "onAnimationCancel");
}
public void onAnimationEnd(Animator animation) {
- if (DEBUG) Slog.d(TAG, "onAnimationEnd");
+ if (DEBUG) Log.d(TAG, "onAnimationEnd");
if (! mVisible) {
setVisibility(View.GONE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
index e0dcbcd..a55cc9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
@@ -22,26 +22,23 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.Slog;
-import android.widget.LinearLayout;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
-import android.widget.TextView;
+import android.widget.LinearLayout;
import com.android.systemui.R;
import com.android.systemui.settings.BrightnessController;
import com.android.systemui.settings.ToggleSlider;
import com.android.systemui.statusbar.policy.AirplaneModeController;
-import com.android.systemui.statusbar.policy.AutoRotateController;
import com.android.systemui.statusbar.policy.DoNotDisturbController;
-import com.android.systemui.statusbar.policy.VolumeController;
+import com.android.systemui.statusbar.policy.RotationLockController;
public class SettingsView extends LinearLayout implements View.OnClickListener {
static final String TAG = "SettingsView";
AirplaneModeController mAirplane;
- AutoRotateController mRotate;
+ RotationLockController mRotationController;
BrightnessController mBrightness;
DoNotDisturbController mDoNotDisturb;
View mRotationLockContainer;
@@ -67,15 +64,25 @@
mRotationLockContainer = findViewById(R.id.rotate);
mRotationLockSeparator = findViewById(R.id.rotate_separator);
- mRotate = new AutoRotateController(context,
- (CompoundButton)findViewById(R.id.rotate_checkbox),
- new AutoRotateController.RotationLockCallbacks() {
+ mRotationController = new RotationLockController(context);
+ mRotationController.addRotationLockControllerCallback(
+ new RotationLockController.RotationLockControllerCallback() {
@Override
- public void setRotationLockControlVisibility(boolean show) {
- mRotationLockContainer.setVisibility(show ? View.VISIBLE : View.GONE);
- mRotationLockSeparator.setVisibility(show ? View.VISIBLE : View.GONE);
+ public void onRotationLockStateChanged(boolean locked, boolean visible) {
+ mRotationLockContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mRotationLockSeparator.setVisibility(visible ? View.VISIBLE : View.GONE);
}
});
+ CompoundButton rotateCheckbox = (CompoundButton) findViewById(R.id.rotate_checkbox);
+ rotateCheckbox.setChecked(!mRotationController.isRotationLocked());
+ rotateCheckbox.setVisibility(mRotationController.isRotationLockAffordanceVisible()
+ ? View.VISIBLE : View.GONE);
+ rotateCheckbox.setOnCheckedChangeListener(new CompoundButton. OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ mRotationController.setRotationLocked(!buttonView.isChecked());
+ }
+ });
mBrightness = new BrightnessController(context,
(ImageView)findViewById(R.id.brightness_icon),
@@ -90,7 +97,7 @@
super.onDetachedFromWindow();
mAirplane.release();
mDoNotDisturb.release();
- mRotate.release();
+ mRotationController.release();
}
public void onClick(View v) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index 2924cc9..48486b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -28,7 +28,7 @@
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -96,21 +96,21 @@
@Override
public boolean onDragEvent(DragEvent event) {
- if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
+ if (DEBUG) Log.d(TAG, "onDragEvent: " + event);
switch (event.getAction()) {
// We want to appear whenever a potential drag takes off from anywhere in the UI.
case DragEvent.ACTION_DRAG_STARTED:
show(true);
break;
case DragEvent.ACTION_DRAG_ENTERED:
- if (DEBUG) Slog.d(TAG, "entered!");
+ if (DEBUG) Log.d(TAG, "entered!");
// XXX: TODO
break;
case DragEvent.ACTION_DRAG_EXITED:
- if (DEBUG) Slog.d(TAG, "exited!");
+ if (DEBUG) Log.d(TAG, "exited!");
break;
case DragEvent.ACTION_DROP:
- if (DEBUG) Slog.d(TAG, "dropped!");
+ if (DEBUG) Log.d(TAG, "dropped!");
mPocket.stash(event.getClipData());
break;
case DragEvent.ACTION_DRAG_ENDED:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index bfa1b63..c2054d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -40,7 +40,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.text.TextUtils;
-import android.util.Slog;
+import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -427,7 +427,7 @@
}
if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
-// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
+// Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
mIconHPadding = newIconHPadding;
mIconSize = newIconSize;
reloadAllNotificationIcons(); // reload the tray
@@ -436,7 +436,7 @@
final int numIcons = res.getInteger(R.integer.config_maxNotificationIcons);
if (numIcons != mMaxNotificationIcons) {
mMaxNotificationIcons = numIcons;
- if (DEBUG) Slog.d(TAG, "max notification icons: " + mMaxNotificationIcons);
+ if (DEBUG) Log.d(TAG, "max notification icons: " + mMaxNotificationIcons);
reloadAllNotificationIcons();
}
}
@@ -461,7 +461,7 @@
// Sanity-check that someone hasn't set up the config wrong and asked for a navigation
// bar on a tablet that has only the system bar
if (mWindowManagerService.hasNavigationBar()) {
- Slog.e(TAG, "Tablet device cannot show navigation bar and system bar");
+ Log.e(TAG, "Tablet device cannot show navigation bar and system bar");
}
} catch (RemoteException ex) {
}
@@ -711,7 +711,7 @@
super.handleMessage(m);
switch (m.what) {
case MSG_OPEN_NOTIFICATION_PEEK:
- if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
+ if (DEBUG) Log.d(TAG, "opening notification peek window; arg=" + m.arg1);
if (m.arg1 >= 0) {
final int N = mNotificationData.size();
@@ -727,7 +727,7 @@
final int peekIndex = m.arg1;
if (peekIndex < N) {
- //Slog.d(TAG, "loading peek: " + peekIndex);
+ //Log.d(TAG, "loading peek: " + peekIndex);
NotificationData.Entry entry =
mNotificationDNDMode
? mNotificationDNDDummyEntry
@@ -769,7 +769,7 @@
}
break;
case MSG_CLOSE_NOTIFICATION_PEEK:
- if (DEBUG) Slog.d(TAG, "closing notification peek window");
+ if (DEBUG) Log.d(TAG, "closing notification peek window");
mNotificationPeekWindow.setVisibility(View.GONE);
mNotificationPeekRow.removeAllViews();
@@ -786,7 +786,7 @@
mNotificationPeekKey = null;
break;
case MSG_OPEN_NOTIFICATION_PANEL:
- if (DEBUG) Slog.d(TAG, "opening notifications panel");
+ if (DEBUG) Log.d(TAG, "opening notifications panel");
if (!mNotificationPanel.isShowing()) {
mNotificationPanel.show(true, true);
mNotificationArea.setVisibility(View.INVISIBLE);
@@ -794,37 +794,37 @@
}
break;
case MSG_CLOSE_NOTIFICATION_PANEL:
- if (DEBUG) Slog.d(TAG, "closing notifications panel");
+ if (DEBUG) Log.d(TAG, "closing notifications panel");
if (mNotificationPanel.isShowing()) {
mNotificationPanel.show(false, true);
mNotificationArea.setVisibility(View.VISIBLE);
}
break;
case MSG_OPEN_INPUT_METHODS_PANEL:
- if (DEBUG) Slog.d(TAG, "opening input methods panel");
+ if (DEBUG) Log.d(TAG, "opening input methods panel");
if (mInputMethodsPanel != null) mInputMethodsPanel.openPanel();
break;
case MSG_CLOSE_INPUT_METHODS_PANEL:
- if (DEBUG) Slog.d(TAG, "closing input methods panel");
+ if (DEBUG) Log.d(TAG, "closing input methods panel");
if (mInputMethodsPanel != null) mInputMethodsPanel.closePanel(false);
break;
case MSG_OPEN_COMPAT_MODE_PANEL:
- if (DEBUG) Slog.d(TAG, "opening compat panel");
+ if (DEBUG) Log.d(TAG, "opening compat panel");
if (mCompatModePanel != null) mCompatModePanel.openPanel();
break;
case MSG_CLOSE_COMPAT_MODE_PANEL:
- if (DEBUG) Slog.d(TAG, "closing compat panel");
+ if (DEBUG) Log.d(TAG, "closing compat panel");
if (mCompatModePanel != null) mCompatModePanel.closePanel();
break;
case MSG_SHOW_CHROME:
- if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
+ if (DEBUG) Log.d(TAG, "hiding shadows (lights on)");
mBarContents.setVisibility(View.VISIBLE);
mShadow.setVisibility(View.GONE);
mSystemUiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
notifyUiVisibilityChanged();
break;
case MSG_HIDE_CHROME:
- if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
+ if (DEBUG) Log.d(TAG, "showing shadows (lights out)");
animateCollapsePanels();
visibilityChanged(false);
mBarContents.setVisibility(View.GONE);
@@ -840,20 +840,20 @@
}
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
- if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
+ if (DEBUG) Log.d(TAG, "addIcon(" + slot + ") -> " + icon);
}
public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon) {
- if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
+ if (DEBUG) Log.d(TAG, "updateIcon(" + slot + ") -> " + icon);
}
public void removeIcon(String slot, int index, int viewIndex) {
- if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
+ if (DEBUG) Log.d(TAG, "removeIcon(" + slot + ")");
}
public void addNotification(IBinder key, StatusBarNotification notification) {
- if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
+ if (DEBUG) Log.d(TAG, "addNotification(" + key + " -> " + notification + ")");
addNotificationViews(key, notification);
final boolean immersive = isImmersive();
@@ -861,7 +861,7 @@
// TODO: immersive mode popups for tablet
} else if (notification.getNotification().fullScreenIntent != null) {
// not immersive & a full-screen alert should be shown
- Slog.w(TAG, "Notification has fullScreenIntent and activity is not immersive;"
+ Log.w(TAG, "Notification has fullScreenIntent and activity is not immersive;"
+ " sending fullScreenIntent");
try {
notification.getNotification().fullScreenIntent.send();
@@ -875,7 +875,7 @@
}
public void removeNotification(IBinder key) {
- if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")");
+ if (DEBUG) Log.d(TAG, "removeNotification(" + key + ")");
removeNotificationViews(key);
mTicker.remove(key);
setAreThereNotifications();
@@ -900,17 +900,17 @@
// act accordingly
if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
- Slog.i(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
+ Log.i(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
showClock(show);
}
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
boolean show = (state & StatusBarManager.DISABLE_SYSTEM_INFO) == 0;
- Slog.i(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes"));
+ Log.i(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes"));
mNotificationTrigger.setVisibility(show ? View.VISIBLE : View.GONE);
}
if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
- Slog.i(TAG, "DISABLE_EXPAND: yes");
+ Log.i(TAG, "DISABLE_EXPAND: yes");
animateCollapsePanels();
visibilityChanged(false);
}
@@ -920,10 +920,10 @@
.getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
- Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes" + (mNotificationDNDMode?" (DND)":""));
+ Log.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes" + (mNotificationDNDMode?" (DND)":""));
mTicker.halt();
} else {
- Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no" + (mNotificationDNDMode?" (DND)":""));
+ Log.i(TAG, "DISABLE_NOTIFICATION_ICONS: no" + (mNotificationDNDMode?" (DND)":""));
}
// refresh icons to show either notifications or the DND message
@@ -1089,7 +1089,7 @@
on = true;
}
- Slog.v(TAG, "setLightsOn(" + on + ")");
+ Log.v(TAG, "setLightsOn(" + on + ")");
if (on) {
setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
} else {
@@ -1099,7 +1099,7 @@
public void topAppWindowChanged(boolean showMenu) {
if (DEBUG) {
- Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
+ Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
}
mMenuButton.setVisibility(showMenu ? View.VISIBLE : View.GONE);
@@ -1182,7 +1182,7 @@
@Override
public void setHardKeyboardStatus(boolean available, boolean enabled) {
if (DEBUG) {
- Slog.d(TAG, "Set hard keyboard status: available=" + available
+ Log.d(TAG, "Set hard keyboard status: available=" + available
+ ", enabled=" + enabled);
}
mInputMethodSwitchButton.setHardKeyboardStatus(available);
@@ -1201,7 +1201,7 @@
private boolean isImmersive() {
try {
return ActivityManagerNative.getDefault().isTopActivityImmersive();
- //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
+ //Log.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
} catch (RemoteException ex) {
// the end is nigh
return false;
@@ -1228,14 +1228,14 @@
};
public void onClickRecentButton() {
- if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
+ if (DEBUG) Log.d(TAG, "clicked recent apps; disabled=" + mDisabled);
if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
toggleRecentApps();
}
}
public void onClickInputMethodSwitchButton() {
- if (DEBUG) Slog.d(TAG, "clicked input methods panel; disabled=" + mDisabled);
+ if (DEBUG) Log.d(TAG, "clicked input methods panel; disabled=" + mDisabled);
int msg = (mInputMethodsPanel.getVisibility() == View.GONE) ?
MSG_OPEN_INPUT_METHODS_PANEL : MSG_CLOSE_INPUT_METHODS_PANEL;
mHandler.removeMessages(msg);
@@ -1272,7 +1272,7 @@
}
public boolean onTouch(View v, MotionEvent event) {
-// Slog.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)",
+// Log.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)",
// event.getX(),
// event.getY(),
// mInitialTouchX,
@@ -1333,7 +1333,7 @@
public void resetNotificationPeekFadeTimer() {
if (DEBUG) {
- Slog.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY
+ Log.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY
+ "ms from now");
}
mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
@@ -1393,7 +1393,7 @@
int N = mNotificationData.size();
if (DEBUG) {
- Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
+ Log.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
}
ArrayList<View> toShow = new ArrayList<View>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index 30d49ca..cd1c942 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -23,7 +23,7 @@
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
import android.view.View;
import android.view.MotionEvent;
import android.widget.FrameLayout;
@@ -80,7 +80,7 @@
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (TabletStatusBar.DEBUG) {
- Slog.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev);
+ Log.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev);
}
// do not close the recents panel here- the intended behavior is that recents is dismissed
// on touch up when clicking on status bar buttons
@@ -96,7 +96,7 @@
if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) {
if (eventInside(mIgnoreChildren[i], ev)) {
if (TabletStatusBar.DEBUG) {
- Slog.d(TabletStatusBar.TAG,
+ Log.d(TabletStatusBar.TAG,
"TabletStatusBarView eating event for view: "
+ mIgnoreChildren[i]);
}
@@ -106,7 +106,7 @@
}
}
if (TabletStatusBar.DEBUG) {
- Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
+ Log.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
}
if (mDelegateHelper != null && mDelegateHelper.onInterceptTouchEvent(ev)) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 095c441..04e0e56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -29,7 +29,7 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
-import android.util.Slog;
+import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -89,7 +89,7 @@
public void add(IBinder key, StatusBarNotification notification) {
if (false) {
- Slog.d(TAG, "add 1 mCurrentNotification=" + mCurrentNotification
+ Log.d(TAG, "add 1 mCurrentNotification=" + mCurrentNotification
+ " mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
}
@@ -195,7 +195,7 @@
mCurrentKey = mKeys[0];
mCurrentNotification = mQueue[0];
if (false) {
- Slog.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
+ Log.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
}
final int N = mQueuePos;
for (int i=0; i<N; i++) {
@@ -276,7 +276,7 @@
if (expanded == null) {
final String ident = notification.getPackageName()
+ "/0x" + Integer.toHexString(notification.getId());
- Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
+ Log.e(TAG, "couldn't inflate view for notification " + ident, exception);
return null;
}
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 06696fe..a3eeb47 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -29,7 +29,7 @@
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
public class StorageNotification extends StorageEventListener {
private static final String TAG = "StorageNotification";
@@ -71,7 +71,7 @@
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
final boolean connected = mStorageManager.isUsbMassStorageConnected();
- if (DEBUG) Slog.d(TAG, String.format( "Startup with UMS connection %s (media state %s)",
+ if (DEBUG) Log.d(TAG, String.format( "Startup with UMS connection %s (media state %s)",
mUmsAvailable, Environment.getExternalStorageState()));
HandlerThread thr = new HandlerThread("SystemUI StorageNotification");
@@ -102,7 +102,7 @@
*/
String st = Environment.getExternalStorageState();
- if (DEBUG) Slog.i(TAG, String.format("UMS connection changed to %s (media state %s)",
+ if (DEBUG) Log.i(TAG, String.format("UMS connection changed to %s (media state %s)",
connected, st));
if (connected && (st.equals(
@@ -129,7 +129,7 @@
}
private void onStorageStateChangedAsync(String path, String oldState, String newState) {
- if (DEBUG) Slog.i(TAG, String.format(
+ if (DEBUG) Log.i(TAG, String.format(
"Media {%s} state changed from {%s} -> {%s}", path, oldState, newState));
if (newState.equals(Environment.MEDIA_SHARED)) {
/*
@@ -250,7 +250,7 @@
true, true, null);
updateUsbMassStorageNotification(false);
} else {
- Slog.w(TAG, String.format("Ignoring unknown state {%s}", newState));
+ Log.w(TAG, String.format("Ignoring unknown state {%s}", newState));
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 6b28e8e..085134d 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -139,6 +139,12 @@
private ActionMenuPresenterCallback mActionMenuPresenterCallback;
private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
+ static final int FLAG_RESOURCE_SET_ICON = 1 << 0;
+ static final int FLAG_RESOURCE_SET_LOGO = 1 << 1;
+ int mResourcesSetFlags;
+ int mIconRes;
+ int mLogoRes;
+
private DrawableFeatureState[] mDrawables;
private PanelFeatureState[] mPanels;
@@ -1393,6 +1399,46 @@
}
}
+ @Override
+ public void setIcon(int resId) {
+ mIconRes = resId;
+ mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON;
+ if (mActionBar != null) {
+ mActionBar.setIcon(resId);
+ }
+ }
+
+ @Override
+ public void setDefaultIcon(int resId) {
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0) {
+ return;
+ }
+ mIconRes = resId;
+ if (mActionBar != null && !mActionBar.hasIcon()) {
+ mActionBar.setIcon(resId);
+ }
+ }
+
+ @Override
+ public void setLogo(int resId) {
+ mLogoRes = resId;
+ mResourcesSetFlags |= FLAG_RESOURCE_SET_LOGO;
+ if (mActionBar != null) {
+ mActionBar.setLogo(resId);
+ }
+ }
+
+ @Override
+ public void setDefaultLogo(int resId) {
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0) {
+ return;
+ }
+ mLogoRes = resId;
+ if (mActionBar != null && !mActionBar.hasLogo()) {
+ mActionBar.setLogo(resId);
+ }
+ }
+
/**
* Request that key events come to this activity. Use this if your activity
* has no views with focus, but the activity still wants a chance to process
@@ -2946,6 +2992,15 @@
"incompatible window decor! Ignoring request.");
}
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
+ (mIconRes != 0 && !mActionBar.hasIcon())) {
+ mActionBar.setIcon(mIconRes);
+ }
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
+ (mLogoRes != 0 && !mActionBar.hasLogo())) {
+ mActionBar.setLogo(mLogoRes);
+ }
+
// Post the panel invalidate for later; avoid application onCreateOptionsMenu
// being called in the middle of onCreate or similar.
mDecor.post(new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 79753a6..82db56d 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -898,20 +898,7 @@
com.android.internal.R.integer.config_lidNavigationAccessibility);
mLidControlsSleep = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_lidControlsSleep);
-
- mLongPressOnHomeBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_longPressOnHomeBehavior);
- if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
- mLongPressOnHomeBehavior > LONG_PRESS_HOME_ASSIST) {
- mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
- }
-
- mDoubleTapOnHomeBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
- if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING ||
- mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
- mDoubleTapOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
- }
+ readConfigurationDependentBehaviors();
// register for dock events
IntentFilter filter = new IntentFilter();
@@ -996,6 +983,27 @@
}
}
+ /**
+ * Read values from config.xml that may be overridden depending on
+ * the configuration of the device.
+ * eg. Disable long press on home goes to recents on sw600dp.
+ */
+ private void readConfigurationDependentBehaviors() {
+ mLongPressOnHomeBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnHomeBehavior);
+ if (mLongPressOnHomeBehavior < LONG_PRESS_HOME_NOTHING ||
+ mLongPressOnHomeBehavior > LONG_PRESS_HOME_ASSIST) {
+ mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
+ }
+
+ mDoubleTapOnHomeBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_doubleTapOnHomeBehavior);
+ if (mDoubleTapOnHomeBehavior < DOUBLE_TAP_HOME_NOTHING ||
+ mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
+ mDoubleTapOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
+ }
+ }
+
@Override
public void setInitialDisplaySize(Display display, int width, int height, int density) {
if (display.getDisplayId() != Display.DEFAULT_DISPLAY) {
@@ -1374,6 +1382,7 @@
int navigationPresence) {
mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0;
+ readConfigurationDependentBehaviors();
readLidState();
applyLidSwitchState();
@@ -1582,7 +1591,7 @@
@Override
public View addStartingWindow(IBinder appToken, String packageName, int theme,
CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
- int icon, int windowFlags) {
+ int icon, int logo, int windowFlags) {
if (!SHOW_STARTING_ANIMATIONS) {
return null;
}
@@ -1639,6 +1648,9 @@
win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
}
+ win.setDefaultIcon(icon);
+ win.setDefaultLogo(logo);
+
win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
@@ -3458,7 +3470,7 @@
}
}});
} else {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Policy preventing status bar from hiding");
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding");
}
} else {
if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen");
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index fa758a8..bc06561 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -351,12 +351,11 @@
}
// iterator over the list removing any it where the intent match
- Iterator<Alarm> it = alarmList.iterator();
-
- while (it.hasNext()) {
- Alarm alarm = it.next();
+ for (int i=0; i<alarmList.size(); i++) {
+ Alarm alarm = alarmList.get(i);
if (alarm.operation.equals(operation)) {
- it.remove();
+ alarmList.remove(i);
+ i--;
}
}
}
@@ -375,12 +374,11 @@
}
// iterator over the list removing any it where the intent match
- Iterator<Alarm> it = alarmList.iterator();
-
- while (it.hasNext()) {
- Alarm alarm = it.next();
+ for (int i=0; i<alarmList.size(); i++) {
+ Alarm alarm = alarmList.get(i);
if (alarm.operation.getTargetPackage().equals(packageName)) {
- it.remove();
+ alarmList.remove(i);
+ i--;
}
}
}
@@ -398,12 +396,11 @@
}
// iterator over the list removing any it where the intent match
- Iterator<Alarm> it = alarmList.iterator();
-
- while (it.hasNext()) {
- Alarm alarm = it.next();
+ for (int i=0; i<alarmList.size(); i++) {
+ Alarm alarm = alarmList.get(i);
if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) {
- it.remove();
+ alarmList.remove(i);
+ i--;
}
}
}
@@ -666,12 +663,10 @@
ArrayList<Alarm> triggerList,
long now)
{
- Iterator<Alarm> it = alarmList.iterator();
- ArrayList<Alarm> repeats = new ArrayList<Alarm>();
-
- while (it.hasNext())
- {
- Alarm alarm = it.next();
+ ArrayList<Alarm> repeats = null;
+
+ for (int i=0; i<alarmList.size(); i++) {
+ Alarm alarm = alarmList.get(i);
if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm);
@@ -702,20 +697,25 @@
triggerList.add(alarm);
// remove the alarm from the list
- it.remove();
-
+ alarmList.remove(i);
+ i--;
+
// if it repeats queue it up to be read-added to the list
if (alarm.repeatInterval > 0) {
+ if (repeats == null) {
+ repeats = new ArrayList<Alarm>();
+ }
repeats.add(alarm);
}
}
// reset any repeating alarms.
- it = repeats.iterator();
- while (it.hasNext()) {
- Alarm alarm = it.next();
- alarm.when += alarm.count * alarm.repeatInterval;
- addAlarmLocked(alarm);
+ if (repeats != null) {
+ for (int i=0; i<repeats.size(); i++) {
+ Alarm alarm = repeats.get(i);
+ alarm.when += alarm.count * alarm.repeatInterval;
+ addAlarmLocked(alarm);
+ }
}
if (alarmList.size() > 0) {
@@ -785,12 +785,14 @@
public void run()
{
+ ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
+
while (true)
{
int result = waitForAlarm(mDescriptor);
-
- ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
-
+
+ triggerList.clear();
+
if ((result & TIME_CHANGED_MASK) != 0) {
remove(mTimeTickSender);
mClockReceiver.scheduleTimeTickEvent();
@@ -820,9 +822,8 @@
triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED);
// now trigger the alarms
- Iterator<Alarm> it = triggerList.iterator();
- while (it.hasNext()) {
- Alarm alarm = it.next();
+ for (int i=0; i<triggerList.size(); i++) {
+ Alarm alarm = triggerList.get(i);
try {
if (localLOGV) Slog.v(TAG, "sending alarm " + alarm);
alarm.operation.send(mContext, 0,
@@ -913,10 +914,8 @@
}
// now trigger the alarms without the lock held
- Iterator<Alarm> it = triggerList.iterator();
- while (it.hasNext())
- {
- Alarm alarm = it.next();
+ for (int i=0; i<triggerList.size(); i++) {
+ Alarm alarm = triggerList.get(i);
try {
alarm.operation.send();
} catch (PendingIntent.CanceledException e) {
diff --git a/services/java/com/android/server/AssetAtlasService.java b/services/java/com/android/server/AssetAtlasService.java
index b18be1c..33f082c 100644
--- a/services/java/com/android/server/AssetAtlasService.java
+++ b/services/java/com/android/server/AssetAtlasService.java
@@ -370,6 +370,11 @@
private static native boolean nUploadAtlas(GraphicBuffer buffer, int bitmap);
@Override
+ public boolean isCompatible(int ppid) {
+ return ppid == android.os.Process.myPpid();
+ }
+
+ @Override
public GraphicBuffer getBuffer() throws RemoteException {
return mAtlasReady.get() ? mBuffer : null;
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 016a664..231cfe1 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -135,8 +135,8 @@
// --- fields below are final after systemReady() ---
private LocationFudger mLocationFudger;
private GeofenceManager mGeofenceManager;
- private PowerManager.WakeLock mWakeLock;
private PackageManager mPackageManager;
+ private PowerManager mPowerManager;
private GeocoderProxy mGeocodeProvider;
private IGpsStatusProvider mGpsStatusProvider;
private INetInitiatedListener mNetInitiatedListener;
@@ -144,9 +144,6 @@
private PassiveProvider mPassiveProvider; // track passive provider for special cases
private LocationBlacklist mBlacklist;
- // --- fields below are protected by mWakeLock ---
- private int mPendingBroadcasts;
-
// --- fields below are protected by mLock ---
// Set of providers that are explicitly enabled
private final Set<String> mEnabledProviders = new HashSet<String>();
@@ -209,10 +206,8 @@
// fetch package manager
mPackageManager = mContext.getPackageManager();
- // prepare wake lock
- PowerManager powerManager =
- (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+ // fetch power manager
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
// prepare worker thread
mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper());
@@ -466,6 +461,7 @@
final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
int mPendingBroadcasts;
+ PowerManager.WakeLock mWakeLock;
Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid,
String packageName) {
@@ -480,6 +476,10 @@
mUid = uid;
mPid = pid;
mPackageName = packageName;
+
+ // construct/configure wakelock
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+ mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName));
}
@Override
@@ -642,10 +642,7 @@
removeUpdatesLocked(this);
}
synchronized (this) {
- if (mPendingBroadcasts > 0) {
- LocationManagerService.this.decrementPendingBroadcasts();
- mPendingBroadcasts = 0;
- }
+ clearPendingBroadcastsLocked();
}
}
@@ -661,32 +658,45 @@
// containing the sending of the broadcaset
private void incrementPendingBroadcastsLocked() {
if (mPendingBroadcasts++ == 0) {
- LocationManagerService.this.incrementPendingBroadcasts();
+ mWakeLock.acquire();
}
}
private void decrementPendingBroadcastsLocked() {
if (--mPendingBroadcasts == 0) {
- LocationManagerService.this.decrementPendingBroadcasts();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+ }
+
+ public void clearPendingBroadcastsLocked() {
+ if (mPendingBroadcasts > 0) {
+ mPendingBroadcasts = 0;
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
}
}
}
@Override
public void locationCallbackFinished(ILocationListener listener) {
- //Do not use getReceiver here as that will add the ILocationListener to
+ //Do not use getReceiverLocked here as that will add the ILocationListener to
//the receiver list if it is not found. If it is not found then the
//LocationListener was removed when it had a pending broadcast and should
//not be added back.
- IBinder binder = listener.asBinder();
- Receiver receiver = mReceivers.get(binder);
- if (receiver != null) {
- synchronized (receiver) {
- // so wakelock calls will succeed
- long identity = Binder.clearCallingIdentity();
- receiver.decrementPendingBroadcastsLocked();
- Binder.restoreCallingIdentity(identity);
- }
+ synchronized (mLock) {
+ IBinder binder = listener.asBinder();
+ Receiver receiver = mReceivers.get(binder);
+ if (receiver != null) {
+ synchronized (receiver) {
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ receiver.decrementPendingBroadcastsLocked();
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
}
@@ -1168,7 +1178,8 @@
}
}
- private Receiver getReceiver(ILocationListener listener, int pid, int uid, String packageName) {
+ private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid,
+ String packageName) {
IBinder binder = listener.asBinder();
Receiver receiver = mReceivers.get(binder);
if (receiver == null) {
@@ -1185,7 +1196,7 @@
return receiver;
}
- private Receiver getReceiver(PendingIntent intent, int pid, int uid, String packageName) {
+ private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName) {
Receiver receiver = mReceivers.get(intent);
if (receiver == null) {
receiver = new Receiver(null, intent, pid, uid, packageName);
@@ -1249,7 +1260,7 @@
}
}
- private Receiver checkListenerOrIntent(ILocationListener listener, PendingIntent intent,
+ private Receiver checkListenerOrIntentLocked(ILocationListener listener, PendingIntent intent,
int pid, int uid, String packageName) {
if (intent == null && listener == null) {
throw new IllegalArgumentException("need either listener or intent");
@@ -1257,9 +1268,9 @@
throw new IllegalArgumentException("cannot register both listener and intent");
} else if (intent != null) {
checkPendingIntent(intent);
- return getReceiver(intent, pid, uid, packageName);
+ return getReceiverLocked(intent, pid, uid, packageName);
} else {
- return getReceiver(listener, pid, uid, packageName);
+ return getReceiverLocked(listener, pid, uid, packageName);
}
}
@@ -1281,9 +1292,10 @@
// We don't check for MODE_IGNORED here; we will do that when we go to deliver
// a location.
checkLocationAccess(uid, packageName, allowedResolutionLevel);
- Receiver recevier = checkListenerOrIntent(listener, intent, pid, uid, packageName);
synchronized (mLock) {
+ Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
+ packageName);
requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName);
}
} finally {
@@ -1330,16 +1342,17 @@
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
- Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName);
- // providers may use public location API's, need to clear identity
- long identity = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
+ synchronized (mLock) {
+ Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid, packageName);
+
+ // providers may use public location API's, need to clear identity
+ long identity = Binder.clearCallingIdentity();
+ try {
removeUpdatesLocked(receiver);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- } finally {
- Binder.restoreCallingIdentity(identity);
}
}
@@ -1349,10 +1362,7 @@
if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
synchronized (receiver) {
- if (receiver.mPendingBroadcasts > 0) {
- decrementPendingBroadcasts();
- receiver.mPendingBroadcasts = 0;
- }
+ receiver.clearPendingBroadcastsLocked();
}
}
@@ -1954,43 +1964,6 @@
}
};
- // Wake locks
-
- private void incrementPendingBroadcasts() {
- synchronized (mWakeLock) {
- if (mPendingBroadcasts++ == 0) {
- try {
- mWakeLock.acquire();
- log("Acquired wakelock");
- } catch (Exception e) {
- // This is to catch a runtime exception thrown when we try to release an
- // already released lock.
- Slog.e(TAG, "exception in acquireWakeLock()", e);
- }
- }
- }
- }
-
- private void decrementPendingBroadcasts() {
- synchronized (mWakeLock) {
- if (--mPendingBroadcasts == 0) {
- try {
- // Release wake lock
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- log("Released wakelock");
- } else {
- log("Can't release wakelock again!");
- }
- } catch (Exception e) {
- // This is to catch a runtime exception thrown when we try to release an
- // already released lock.
- Slog.e(TAG, "exception in releaseWakeLock()", e);
- }
- }
- }
- }
-
// Geocoder
@Override
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 10db70f..a77379e 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -574,30 +574,26 @@
b.binder = service;
b.requested = true;
b.received = true;
- if (r.connections.size() > 0) {
- Iterator<ArrayList<ConnectionRecord>> it
- = r.connections.values().iterator();
- while (it.hasNext()) {
- ArrayList<ConnectionRecord> clist = it.next();
- for (int i=0; i<clist.size(); i++) {
- ConnectionRecord c = clist.get(i);
- if (!filter.equals(c.binding.intent.intent)) {
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Not publishing to: " + c);
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Bound intent: " + c.binding.intent.intent);
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Published intent: " + intent);
- continue;
- }
- if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
- try {
- c.conn.connected(r.name, service);
- } catch (Exception e) {
- Slog.w(TAG, "Failure sending service " + r.name +
- " to connection " + c.conn.asBinder() +
- " (in " + c.binding.client.processName + ")", e);
- }
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
+ for (int i=0; i<clist.size(); i++) {
+ ConnectionRecord c = clist.get(i);
+ if (!filter.equals(c.binding.intent.intent)) {
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Not publishing to: " + c);
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Bound intent: " + c.binding.intent.intent);
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Published intent: " + intent);
+ continue;
+ }
+ if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
+ try {
+ c.conn.connected(r.name, service);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failure sending service " + r.name +
+ " to connection " + c.conn.asBinder() +
+ " (in " + c.binding.client.processName + ")", e);
}
}
}
@@ -1064,10 +1060,9 @@
}
private final void requestServiceBindingsLocked(ServiceRecord r) {
- Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
- while (bindings.hasNext()) {
- IntentBindRecord i = bindings.next();
- if (!requestServiceBindingLocked(r, i, false)) {
+ for (int i=r.bindings.size()-1; i>=0; i--) {
+ IntentBindRecord ibr = r.bindings.valueAt(i);
+ if (!requestServiceBindingLocked(r, ibr, false)) {
break;
}
}
@@ -1179,50 +1174,45 @@
if (!force && r.startRequested) {
return;
}
- if (r.connections.size() > 0) {
- if (!force) {
- // XXX should probably keep a count of the number of auto-create
- // connections directly in the service.
- Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
- while (it.hasNext()) {
- ArrayList<ConnectionRecord> cr = it.next();
- for (int i=0; i<cr.size(); i++) {
- if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
- return;
- }
- }
- }
- }
-
- // Report to all of the connections that the service is no longer
- // available.
- Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
- while (it.hasNext()) {
- ArrayList<ConnectionRecord> c = it.next();
- for (int i=0; i<c.size(); i++) {
- ConnectionRecord cr = c.get(i);
- // There is still a connection to the service that is
- // being brought down. Mark it as dead.
- cr.serviceDead = true;
- try {
- cr.conn.connected(r.name, null);
- } catch (Exception e) {
- Slog.w(TAG, "Failure disconnecting service " + r.name +
- " to connection " + c.get(i).conn.asBinder() +
- " (in " + c.get(i).binding.client.processName + ")", e);
+ if (!force) {
+ // XXX should probably keep a count of the number of auto-create
+ // connections directly in the service.
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> cr = r.connections.valueAt(conni);
+ for (int i=0; i<cr.size(); i++) {
+ if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
+ return;
}
}
}
}
+ // Report to all of the connections that the service is no longer
+ // available.
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
+ for (int i=0; i<c.size(); i++) {
+ ConnectionRecord cr = c.get(i);
+ // There is still a connection to the service that is
+ // being brought down. Mark it as dead.
+ cr.serviceDead = true;
+ try {
+ cr.conn.connected(r.name, null);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failure disconnecting service " + r.name +
+ " to connection " + c.get(i).conn.asBinder() +
+ " (in " + c.get(i).binding.client.processName + ")", e);
+ }
+ }
+ }
+
// Tell the service that it has been unbound.
- if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
- Iterator<IntentBindRecord> it = r.bindings.values().iterator();
- while (it.hasNext()) {
- IntentBindRecord ibr = it.next();
+ if (r.app != null && r.app.thread != null) {
+ for (int i=r.bindings.size()-1; i>=0; i--) {
+ IntentBindRecord ibr = r.bindings.valueAt(i);
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
+ ": hasBound=" + ibr.hasBound);
- if (r.app != null && r.app.thread != null && ibr.hasBound) {
+ if (ibr.hasBound) {
try {
bumpServiceExecutingLocked(r, "bring down unbind");
mAm.updateOomAdjLocked(r.app);
@@ -1595,22 +1585,18 @@
Iterator<ServiceRecord> it = app.services.iterator();
while (it.hasNext()) {
ServiceRecord r = it.next();
- if (r.connections.size() > 0) {
- Iterator<ArrayList<ConnectionRecord>> jt
- = r.connections.values().iterator();
- while (jt.hasNext()) {
- ArrayList<ConnectionRecord> cl = jt.next();
- for (int i=0; i<cl.size(); i++) {
- ConnectionRecord c = cl.get(i);
- if (c.binding.client != app) {
- try {
- //c.conn.connected(r.className, null);
- } catch (Exception e) {
- // todo: this should be asynchronous!
- Slog.w(TAG, "Exception thrown disconnected servce "
- + r.shortName
- + " from app " + app.processName, e);
- }
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
+ for (int i=0; i<cl.size(); i++) {
+ ConnectionRecord c = cl.get(i);
+ if (c.binding.client != app) {
+ try {
+ //c.conn.connected(r.className, null);
+ } catch (Exception e) {
+ // todo: this should be asynchronous!
+ Slog.w(TAG, "Exception thrown disconnected servce "
+ + r.shortName
+ + " from app " + app.processName, e);
}
}
}
@@ -1645,17 +1631,13 @@
if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
}
- boolean hasClients = sr.bindings.size() > 0;
- if (hasClients) {
- Iterator<IntentBindRecord> bindings
- = sr.bindings.values().iterator();
- while (bindings.hasNext()) {
- IntentBindRecord b = bindings.next();
- if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
- + ": shouldUnbind=" + b.hasBound);
- b.binder = null;
- b.requested = b.received = b.hasBound = false;
- }
+ final int numClients = sr.bindings.size();
+ for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
+ IntentBindRecord b = sr.bindings.valueAt(bindingi);
+ if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
+ + ": shouldUnbind=" + b.hasBound);
+ b.binder = null;
+ b.requested = b.received = b.hasBound = false;
}
if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
@@ -1676,7 +1658,7 @@
if (sr.startRequested && (sr.stopIfKilled || canceled)) {
if (sr.pendingStarts.size() == 0) {
sr.startRequested = false;
- if (!hasClients) {
+ if (numClients > 0) {
// Whoops, no reason to restart!
bringDownServiceLocked(sr, true);
}
@@ -1732,7 +1714,8 @@
info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
}
- for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
for (int i=0; i<connl.size(); i++) {
ConnectionRecord conn = connl.get(i);
if (conn.clientLabel != 0) {
@@ -1805,7 +1788,8 @@
int userId = UserHandle.getUserId(Binder.getCallingUid());
ServiceRecord r = mServiceMap.getServiceByName(name, userId);
if (r != null) {
- for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
+ for (int conni=r.connections.size()-1; conni>=0; conni--) {
+ ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
for (int i=0; i<conn.size(); i++) {
if (conn.get(i).clientIntent != null) {
return conn.get(i).clientIntent;
@@ -1856,9 +1840,10 @@
/**
* Prints a list of ServiceRecords (dumpsys activity services)
*/
- boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
boolean needSep = false;
+ boolean printedAnything = false;
ItemMatcher matcher = new ItemMatcher();
matcher.build(args, opti);
@@ -1881,6 +1866,7 @@
if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
continue;
}
+ printedAnything = true;
if (!printed) {
if (user != 0) {
pw.println();
@@ -1907,7 +1893,8 @@
pw.println(r.connections.size());
if (r.connections.size() > 0) {
pw.println(" Connections:");
- for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
+ for (int conni=0; conni<r.connections.size(); conni++) {
+ ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i = 0; i < clist.size(); i++) {
ConnectionRecord conn = clist.get(i);
pw.print(" ");
@@ -1943,11 +1930,11 @@
needSep = true;
}
}
- needSep = printed;
+ needSep |= printed;
}
}
} catch (Exception e) {
- Log.w(TAG, "Exception in dumpServicesLocked: " + e);
+ Log.w(TAG, "Exception in dumpServicesLocked", e);
}
if (mPendingServices.size() > 0) {
@@ -1960,8 +1947,9 @@
if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
continue;
}
+ printedAnything = true;
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Pending services:");
printed = true;
@@ -1982,8 +1970,9 @@
if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
continue;
}
+ printedAnything = true;
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Restarting services:");
printed = true;
@@ -2004,8 +1993,9 @@
if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
continue;
}
+ printedAnything = true;
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Stopping services:");
printed = true;
@@ -2032,8 +2022,9 @@
|| !dumpPackage.equals(cr.binding.client.info.packageName))) {
continue;
}
+ printedAnything = true;
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Connection bindings to services:");
printed = true;
@@ -2042,11 +2033,12 @@
cr.dump(pw, " ");
}
}
- needSep = true;
}
}
- return needSep;
+ if (!printedAnything) {
+ pw.println(" (nothing)");
+ }
}
/**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ed6dcce..bb20174 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6515,6 +6515,7 @@
int userId = app.userId;
if (providers != null) {
int N = providers.size();
+ app.pubProviders.ensureCapacity(N + app.pubProviders.size());
for (int i=0; i<N; i++) {
ProviderInfo cpi =
(ProviderInfo)providers.get(i);
@@ -6527,6 +6528,7 @@
// it runs in the process of the default user. Get rid of it.
providers.remove(i);
N--;
+ i--;
continue;
}
@@ -9487,39 +9489,28 @@
// No piece of data specified, dump everything.
synchronized (this) {
- boolean needSep;
- needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
- if (needSep) {
- pw.println(" ");
- }
+ dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+ pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
- if (needSep) {
- pw.println(" ");
- }
+ dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+ pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
- if (needSep) {
- pw.println(" ");
- }
+ dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+ pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
- if (needSep) {
- pw.println(" ");
- }
+ mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+ pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
- if (needSep) {
- pw.println(" ");
- }
+ dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+ pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
@@ -9528,21 +9519,32 @@
Binder.restoreCallingIdentity(origId);
}
- boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
- mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
+ boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
+ dumpPackage);
+ boolean needSep = printedAnything;
- pw.println(" ");
- pw.println(" mFocusedActivity: " + mFocusedActivity);
- pw.println(" ");
+ boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
+ dumpPackage, needSep, " mFocusedActivity: ");
+ if (printed) {
+ printedAnything = true;
+ needSep = false;
+ }
- mStackSupervisor.dump(pw, " ");
+ if (dumpPackage == null) {
+ if (needSep) {
+ pw.println();
+ }
+ needSep = true;
+ printedAnything = true;
+ mStackSupervisor.dump(pw, " ");
+ }
if (mRecentTasks.size() > 0) {
- pw.println();
- pw.println(" Recent tasks:");
+ boolean printedHeader = false;
final int N = mRecentTasks.size();
for (int i=0; i<N; i++) {
@@ -9553,6 +9555,14 @@
continue;
}
}
+ if (!printedHeader) {
+ if (needSep) {
+ pw.println();
+ }
+ pw.println(" Recent tasks:");
+ printedHeader = true;
+ printedAnything = true;
+ }
pw.print(" * Recent #"); pw.print(i); pw.print(": ");
pw.println(tr);
if (dumpAll) {
@@ -9561,12 +9571,15 @@
}
}
- return true;
+ if (!printedAnything) {
+ pw.println(" (nothing)");
+ }
}
- boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
boolean needSep = false;
+ boolean printedAnything = false;
int numPers = 0;
pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
@@ -9576,12 +9589,13 @@
final int NA = procs.size();
for (int ia=0; ia<NA; ia++) {
ProcessRecord r = procs.valueAt(ia);
- if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
continue;
}
if (!needSep) {
pw.println(" All known processes:");
needSep = true;
+ printedAnything = true;
}
pw.print(r.persistent ? " *PERS*" : " *APP*");
pw.print(" UID "); pw.print(procs.keyAt(ia));
@@ -9595,41 +9609,50 @@
}
if (mIsolatedProcesses.size() > 0) {
- if (needSep) pw.println(" ");
- needSep = true;
- pw.println(" Isolated process list (sorted by uid):");
+ boolean printed = false;
for (int i=0; i<mIsolatedProcesses.size(); i++) {
ProcessRecord r = mIsolatedProcesses.valueAt(i);
- if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
continue;
}
+ if (!printed) {
+ if (needSep) {
+ pw.println();
+ }
+ pw.println(" Isolated process list (sorted by uid):");
+ printedAnything = true;
+ printed = true;
+ needSep = true;
+ }
pw.println(String.format("%sIsolated #%2d: %s",
" ", i, r.toString()));
}
}
if (mLruProcesses.size() > 0) {
- if (needSep) pw.println(" ");
- needSep = true;
- pw.println(" Process LRU list (sorted by oom_adj):");
- dumpProcessOomList(pw, this, mLruProcesses, " ",
- "Proc", "PERS", false, dumpPackage);
- needSep = true;
+ boolean printed = dumpProcessOomList(pw, this, mLruProcesses, " ",
+ "Proc", "PERS", false, dumpPackage, needSep,
+ " Process LRU list (sorted by oom_adj):");
+ if (printed) {
+ needSep = true;
+ printedAnything = true;
+ }
}
- if (dumpAll) {
+ if (dumpAll || dumpPackage != null) {
synchronized (mPidsSelfLocked) {
boolean printed = false;
for (int i=0; i<mPidsSelfLocked.size(); i++) {
ProcessRecord r = mPidsSelfLocked.valueAt(i);
- if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" PID mappings:");
printed = true;
+ printedAnything = true;
}
pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
@@ -9644,14 +9667,15 @@
ProcessRecord r = mPidsSelfLocked.get(
mForegroundProcesses.valueAt(i).pid);
if (dumpPackage != null && (r == null
- || !dumpPackage.equals(r.info.packageName))) {
+ || !r.pkgList.contains(dumpPackage))) {
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Foreground Processes:");
printed = true;
+ printedAnything = true;
}
pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
@@ -9660,24 +9684,27 @@
}
if (mPersistentStartingProcesses.size() > 0) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
+ printedAnything = true;
pw.println(" Persisent processes that are starting:");
dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
"Starting Norm", "Restarting PERS", dumpPackage);
}
if (mRemovedProcesses.size() > 0) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
+ printedAnything = true;
pw.println(" Processes that are being removed:");
dumpProcessList(pw, this, mRemovedProcesses, " ",
"Removed Norm", "Removed PERS", dumpPackage);
}
if (mProcessesOnHold.size() > 0) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
+ printedAnything = true;
pw.println(" Processes that are on old until the system is ready:");
dumpProcessList(pw, this, mProcessesOnHold, " ",
"OnHold Norm", "OnHold PERS", dumpPackage);
@@ -9697,14 +9724,15 @@
int puid = uids.keyAt(i);
ProcessRecord r = mProcessNames.get(pname, puid);
if (dumpPackage != null && (r == null
- || !dumpPackage.equals(r.info.packageName))) {
+ || !r.pkgList.contains(dumpPackage))) {
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Time since processes crashed:");
printed = true;
+ printedAnything = true;
}
pw.print(" Process "); pw.print(pname);
pw.print(" uid "); pw.print(puid);
@@ -9726,13 +9754,14 @@
int puid = uids.keyAt(i);
ProcessRecord r = mProcessNames.get(pname, puid);
if (dumpPackage != null && (r == null
- || !dumpPackage.equals(r.info.packageName))) {
+ || !r.pkgList.contains(dumpPackage))) {
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Bad processes:");
+ printedAnything = true;
}
pw.print(" Bad process "); pw.print(pname);
pw.print(" uid "); pw.print(puid);
@@ -9742,40 +9771,64 @@
}
}
- pw.println();
- pw.println(" mStartedUsers:");
- for (int i=0; i<mStartedUsers.size(); i++) {
- UserStartedState uss = mStartedUsers.valueAt(i);
- pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
- pw.print(": "); uss.dump("", pw);
+ if (dumpPackage == null) {
+ pw.println();
+ needSep = false;
+ pw.println(" mStartedUsers:");
+ for (int i=0; i<mStartedUsers.size(); i++) {
+ UserStartedState uss = mStartedUsers.valueAt(i);
+ pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
+ pw.print(": "); uss.dump("", pw);
+ }
+ pw.print(" mStartedUserArray: [");
+ for (int i=0; i<mStartedUserArray.length; i++) {
+ if (i > 0) pw.print(", ");
+ pw.print(mStartedUserArray[i]);
+ }
+ pw.println("]");
+ pw.print(" mUserLru: [");
+ for (int i=0; i<mUserLru.size(); i++) {
+ if (i > 0) pw.print(", ");
+ pw.print(mUserLru.get(i));
+ }
+ pw.println("]");
+ if (dumpAll) {
+ pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
+ }
}
- pw.print(" mStartedUserArray: [");
- for (int i=0; i<mStartedUserArray.length; i++) {
- if (i > 0) pw.print(", ");
- pw.print(mStartedUserArray[i]);
+ if (mHomeProcess != null && (dumpPackage == null
+ || mHomeProcess.pkgList.contains(dumpPackage))) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mHomeProcess: " + mHomeProcess);
}
- pw.println("]");
- pw.print(" mUserLru: [");
- for (int i=0; i<mUserLru.size(); i++) {
- if (i > 0) pw.print(", ");
- pw.print(mUserLru.get(i));
+ if (mPreviousProcess != null && (dumpPackage == null
+ || mPreviousProcess.pkgList.contains(dumpPackage))) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mPreviousProcess: " + mPreviousProcess);
}
- pw.println("]");
- if (dumpAll) {
- pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
- }
- pw.println(" mHomeProcess: " + mHomeProcess);
- pw.println(" mPreviousProcess: " + mPreviousProcess);
if (dumpAll) {
StringBuilder sb = new StringBuilder(128);
sb.append(" mPreviousProcessVisibleTime: ");
TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
pw.println(sb);
}
- if (mHeavyWeightProcess != null) {
+ if (mHeavyWeightProcess != null && (dumpPackage == null
+ || mHeavyWeightProcess.pkgList.contains(dumpPackage))) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
}
- pw.println(" mConfiguration: " + mConfiguration);
+ if (dumpPackage == null) {
+ pw.println(" mConfiguration: " + mConfiguration);
+ }
if (dumpAll) {
pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
if (mCompatModePackages.getPackages().size() > 0) {
@@ -9796,57 +9849,82 @@
}
}
}
- if (mSleeping || mWentToSleep || mLockScreenShown) {
- pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
- + " mLockScreenShown " + mLockScreenShown);
- }
- if (mShuttingDown) {
- pw.println(" mShuttingDown=" + mShuttingDown);
+ if (dumpPackage == null) {
+ if (mSleeping || mWentToSleep || mLockScreenShown) {
+ pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
+ + " mLockScreenShown " + mLockScreenShown);
+ }
+ if (mShuttingDown) {
+ pw.println(" mShuttingDown=" + mShuttingDown);
+ }
}
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
- pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
- + " mDebugTransient=" + mDebugTransient
- + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
+ if (dumpPackage == null || dumpPackage.equals(mDebugApp)
+ || dumpPackage.equals(mOrigDebugApp)) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
+ + " mDebugTransient=" + mDebugTransient
+ + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
+ }
}
if (mOpenGlTraceApp != null) {
- pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
+ if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
+ }
}
if (mProfileApp != null || mProfileProc != null || mProfileFile != null
|| mProfileFd != null) {
- pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
- pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
- pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
- + mAutoStopProfiler);
+ if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
+ pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
+ pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
+ + mAutoStopProfiler);
+ }
}
- if (mAlwaysFinishActivities || mController != null) {
- pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
- + " mController=" + mController);
+ if (dumpPackage == null) {
+ if (mAlwaysFinishActivities || mController != null) {
+ pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
+ + " mController=" + mController);
+ }
+ if (dumpAll) {
+ pw.println(" Total persistent processes: " + numPers);
+ pw.println(" mStartRunning=" + mStartRunning
+ + " mProcessesReady=" + mProcessesReady
+ + " mSystemReady=" + mSystemReady);
+ pw.println(" mBooting=" + mBooting
+ + " mBooted=" + mBooted
+ + " mFactoryTest=" + mFactoryTest);
+ pw.print(" mLastPowerCheckRealtime=");
+ TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
+ pw.println("");
+ pw.print(" mLastPowerCheckUptime=");
+ TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
+ pw.println("");
+ pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
+ pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
+ pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
+ pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
+ + " mNumHiddenProcs=" + mNumHiddenProcs
+ + " mNumServiceProcs=" + mNumServiceProcs
+ + " mNewNumServiceProcs=" + mNewNumServiceProcs);
+ }
}
- if (dumpAll) {
- pw.println(" Total persistent processes: " + numPers);
- pw.println(" mStartRunning=" + mStartRunning
- + " mProcessesReady=" + mProcessesReady
- + " mSystemReady=" + mSystemReady);
- pw.println(" mBooting=" + mBooting
- + " mBooted=" + mBooted
- + " mFactoryTest=" + mFactoryTest);
- pw.print(" mLastPowerCheckRealtime=");
- TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
- pw.println("");
- pw.print(" mLastPowerCheckUptime=");
- TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
- pw.println("");
- pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
- pw.println(" mLaunchingActivity=" + getFocusedStack().mLaunchingActivity);
- pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
- pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
- + " mNumHiddenProcs=" + mNumHiddenProcs
- + " mNumServiceProcs=" + mNumServiceProcs
- + " mNewNumServiceProcs=" + mNewNumServiceProcs);
+
+ if (!printedAnything) {
+ pw.println(" (nothing)");
}
-
- return true;
}
boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
@@ -9860,7 +9938,7 @@
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Processes that are waiting to GC:");
printed = true;
@@ -9883,7 +9961,7 @@
boolean needSep = false;
if (mLruProcesses.size() > 0) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" OOM levels:");
pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
@@ -9900,11 +9978,11 @@
pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Process OOM control:");
dumpProcessOomList(pw, this, mLruProcesses, " ",
- "Proc", "PERS", true, null);
+ "Proc", "PERS", true, null, false, null);
needSep = true;
}
@@ -10096,10 +10174,11 @@
}
}
- boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
boolean needSep = false;
boolean onlyHistory = false;
+ boolean printedAnything = false;
if ("history".equals(dumpPackage)) {
if (opti < args.length && "-s".equals(args[opti])) {
@@ -10124,6 +10203,7 @@
pw.println(" Registered Receivers:");
needSep = true;
printed = true;
+ printedAnything = true;
}
pw.print(" * "); pw.println(r);
r.dump(pw, " ");
@@ -10134,11 +10214,13 @@
"\n Receiver Resolver Table:" : " Receiver Resolver Table:",
" ", dumpPackage, false)) {
needSep = true;
+ printedAnything = true;
}
}
for (BroadcastQueue q : mBroadcastQueues) {
needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
+ printedAnything |= needSep;
}
needSep = true;
@@ -10149,6 +10231,7 @@
pw.println();
}
needSep = true;
+ printedAnything = true;
pw.print(" Sticky broadcasts for user ");
pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
StringBuilder sb = new StringBuilder(128);
@@ -10186,21 +10269,26 @@
pw.println(" mHandler:");
mHandler.dump(new PrintWriterPrinter(pw), " ");
needSep = true;
+ printedAnything = true;
}
- return needSep;
+ if (!printedAnything) {
+ pw.println(" (nothing)");
+ }
}
- boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
- boolean needSep = true;
+ boolean needSep;
+ boolean printedAnything = false;
ItemMatcher matcher = new ItemMatcher();
matcher.build(args, opti);
pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
- mProviderMap.dumpProvidersLocked(pw, dumpAll);
+ needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
+ printedAnything |= needSep;
if (mLaunchingProviders.size() > 0) {
boolean printed = false;
@@ -10210,10 +10298,11 @@
continue;
}
if (!printed) {
- if (needSep) pw.println(" ");
+ if (needSep) pw.println();
needSep = true;
pw.println(" Launching content providers:");
printed = true;
+ printedAnything = true;
}
pw.print(" Launching #"); pw.print(i); pw.print(": ");
pw.println(r);
@@ -10221,13 +10310,29 @@
}
if (mGrantedUriPermissions.size() > 0) {
- if (needSep) pw.println();
- needSep = true;
- pw.println("Granted Uri Permissions:");
+ boolean printed = false;
+ int dumpUid = -2;
+ if (dumpPackage != null) {
+ try {
+ dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
+ } catch (NameNotFoundException e) {
+ dumpUid = -1;
+ }
+ }
for (int i=0; i<mGrantedUriPermissions.size(); i++) {
int uid = mGrantedUriPermissions.keyAt(i);
+ if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
+ continue;
+ }
HashMap<Uri, UriPermission> perms
= mGrantedUriPermissions.valueAt(i);
+ if (!printed) {
+ if (needSep) pw.println();
+ needSep = true;
+ pw.println(" Granted Uri Permissions:");
+ printed = true;
+ printedAnything = true;
+ }
pw.print(" * UID "); pw.print(uid);
pw.println(" holds:");
for (UriPermission perm : perms.values()) {
@@ -10237,18 +10342,20 @@
}
}
}
- needSep = true;
}
-
- return needSep;
+
+ if (!printedAnything) {
+ pw.println(" (nothing)");
+ }
}
- boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
- boolean needSep = false;
-
+ boolean printed = false;
+
+ pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
+
if (mIntentSenderRecords.size() > 0) {
- boolean printed = false;
Iterator<WeakReference<PendingIntentRecord>> it
= mIntentSenderRecords.values().iterator();
while (it.hasNext()) {
@@ -10258,11 +10365,7 @@
|| !dumpPackage.equals(rec.key.packageName))) {
continue;
}
- if (!printed) {
- pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
- printed = true;
- }
- needSep = true;
+ printed = true;
if (rec != null) {
pw.print(" * "); pw.println(rec);
if (dumpAll) {
@@ -10273,8 +10376,10 @@
}
}
}
-
- return needSep;
+
+ if (!printed) {
+ pw.println(" (nothing)");
+ }
}
private static String buildOomTag(String prefix, String space, int val, int base) {
@@ -10309,13 +10414,13 @@
private static final boolean dumpProcessOomList(PrintWriter pw,
ActivityManagerService service, List<ProcessRecord> origList,
String prefix, String normalLabel, String persistentLabel,
- boolean inclDetails, String dumpPackage) {
+ boolean inclDetails, String dumpPackage, boolean needSep, String header) {
ArrayList<Pair<ProcessRecord, Integer>> list
= new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
for (int i=0; i<origList.size(); i++) {
ProcessRecord r = origList.get(i);
- if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ if (dumpPackage != null && !r.pkgList.contains(dumpPackage)) {
continue;
}
list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
@@ -10324,7 +10429,14 @@
if (list.size() <= 0) {
return false;
}
-
+
+ if (header != null) {
+ if (needSep) {
+ pw.println();
+ }
+ pw.println(header);
+ }
+
Comparator<Pair<ProcessRecord, Integer>> comparator
= new Comparator<Pair<ProcessRecord, Integer>>() {
@Override
@@ -11024,24 +11136,20 @@
boolean restart = false;
// Remove published content providers.
- if (!app.pubProviders.isEmpty()) {
- Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
- while (it.hasNext()) {
- ContentProviderRecord cpr = it.next();
-
- final boolean always = app.bad || !allowRestart;
- if (removeDyingProviderLocked(app, cpr, always) || always) {
- // We left the provider in the launching list, need to
- // restart it.
- restart = true;
- }
-
- cpr.provider = null;
- cpr.proc = null;
+ for (int i=app.pubProviders.size()-1; i>=0; i--) {
+ ContentProviderRecord cpr = app.pubProviders.valueAt(i);
+ final boolean always = app.bad || !allowRestart;
+ if (removeDyingProviderLocked(app, cpr, always) || always) {
+ // We left the provider in the launching list, need to
+ // restart it.
+ restart = true;
}
- app.pubProviders.clear();
+
+ cpr.provider = null;
+ cpr.proc = null;
}
-
+ app.pubProviders.clear();
+
// Take care of any launching providers waiting for this process.
if (checkAppInLaunchingProvidersLocked(app, false)) {
restart = true;
@@ -13118,158 +13226,159 @@
// has said it is doing work.
app.keeping = true;
}
- if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
- Iterator<ArrayList<ConnectionRecord>> kt
- = s.connections.values().iterator();
- while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
- ArrayList<ConnectionRecord> clist = kt.next();
- for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
- // XXX should compute this based on the max of
- // all connected clients.
- ConnectionRecord cr = clist.get(i);
- if (cr.binding.client == app) {
- // Binding to ourself is not interesting.
- continue;
+ for (int conni = s.connections.size()-1;
+ conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+ || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ conni--) {
+ ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
+ for (int i = 0;
+ i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
+ || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ i++) {
+ // XXX should compute this based on the max of
+ // all connected clients.
+ ConnectionRecord cr = clist.get(i);
+ if (cr.binding.client == app) {
+ // Binding to ourself is not interesting.
+ continue;
+ }
+ if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
+ ProcessRecord client = cr.binding.client;
+ int clientAdj = adj;
+ int myHiddenAdj = hiddenAdj;
+ if (myHiddenAdj > client.hiddenAdj) {
+ if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myHiddenAdj = client.hiddenAdj;
+ } else {
+ myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
+ }
}
- if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
- ProcessRecord client = cr.binding.client;
- int clientAdj = adj;
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
- } else {
- myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
- }
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
}
- int myClientHiddenAdj = clientHiddenAdj;
- if (myClientHiddenAdj > client.clientHiddenAdj) {
- if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
- myClientHiddenAdj = client.clientHiddenAdj;
- } else {
- myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
- }
+ }
+ int myEmptyAdj = emptyAdj;
+ if (myEmptyAdj > client.emptyAdj) {
+ if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myEmptyAdj = client.emptyAdj;
+ } else {
+ myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
}
- int myEmptyAdj = emptyAdj;
- if (myEmptyAdj > client.emptyAdj) {
- if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
- myEmptyAdj = client.emptyAdj;
- } else {
- myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
- }
- }
- clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
- String adjType = null;
- if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
- // Not doing bind OOM management, so treat
- // this guy more like a started service.
- if (app.hasShownUi && app != mHomeProcess) {
- // If this process has shown some UI, let it immediately
- // go to the LRU list because it may be pretty heavy with
- // UI stuff. We'll tag it with a label just to help
- // debug and understand what is going on.
- if (adj > clientAdj) {
- adjType = "bound-bg-ui-services";
- }
- app.hidden = false;
- clientAdj = adj;
- } else {
- if (now >= (s.lastActivity
- + ActiveServices.MAX_SERVICE_INACTIVITY)) {
- // This service has not seen activity within
- // recent memory, so allow it to drop to the
- // LRU list if there is no other reason to keep
- // it around. We'll also tag it with a label just
- // to help debug and undertand what is going on.
- if (adj > clientAdj) {
- adjType = "bound-bg-services";
- }
- clientAdj = adj;
- }
- }
- } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
- if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
- // If this connection is keeping the service
- // created, then we want to try to better follow
- // its memory management semantics for activities.
- // That is, if it is sitting in the background
- // LRU list as a hidden process (with activities),
- // we don't want the service it is connected to
- // to go into the empty LRU and quickly get killed,
- // because I'll we'll do is just end up restarting
- // the service.
- app.hasClientActivities |= client.hasActivities;
- }
- }
- if (adj > clientAdj) {
- // If this process has recently shown UI, and
- // the process that is binding to it is less
- // important than being visible, then we don't
- // care about the binding as much as we care
- // about letting this process get into the LRU
- // list to be killed and restarted if needed for
- // memory.
- if (app.hasShownUi && app != mHomeProcess
- && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ }
+ clientAdj = computeOomAdjLocked(client, myHiddenAdj,
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
+ String adjType = null;
+ if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
+ // Not doing bind OOM management, so treat
+ // this guy more like a started service.
+ if (app.hasShownUi && app != mHomeProcess) {
+ // If this process has shown some UI, let it immediately
+ // go to the LRU list because it may be pretty heavy with
+ // UI stuff. We'll tag it with a label just to help
+ // debug and understand what is going on.
+ if (adj > clientAdj) {
adjType = "bound-bg-ui-services";
- } else {
- if ((cr.flags&(Context.BIND_ABOVE_CLIENT
- |Context.BIND_IMPORTANT)) != 0) {
- adj = clientAdj;
- } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
- && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
- && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
- adj = clientAdj;
- } else {
- app.pendingUiClean = true;
- if (adj > ProcessList.VISIBLE_APP_ADJ) {
- adj = ProcessList.VISIBLE_APP_ADJ;
- }
- }
- if (!client.hidden) {
- app.hidden = false;
- }
- if (client.keeping) {
- app.keeping = true;
- }
- adjType = "service";
- }
- }
- if (adjType != null) {
- app.adjType = adjType;
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_SERVICE_IN_USE;
- app.adjSource = cr.binding.client;
- app.adjSourceOom = clientAdj;
- app.adjTarget = s.name;
- }
- if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
- if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- }
- }
- }
- final ActivityRecord a = cr.activity;
- if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
- if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
- (a.visible || a.state == ActivityState.RESUMED
- || a.state == ActivityState.PAUSING)) {
- adj = ProcessList.FOREGROUND_APP_ADJ;
- if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
- schedGroup = Process.THREAD_GROUP_DEFAULT;
}
app.hidden = false;
- app.adjType = "service";
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_SERVICE_IN_USE;
- app.adjSource = a;
- app.adjSourceOom = adj;
- app.adjTarget = s.name;
+ clientAdj = adj;
+ } else {
+ if (now >= (s.lastActivity
+ + ActiveServices.MAX_SERVICE_INACTIVITY)) {
+ // This service has not seen activity within
+ // recent memory, so allow it to drop to the
+ // LRU list if there is no other reason to keep
+ // it around. We'll also tag it with a label just
+ // to help debug and undertand what is going on.
+ if (adj > clientAdj) {
+ adjType = "bound-bg-services";
+ }
+ clientAdj = adj;
+ }
}
+ } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
+ if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
+ // If this connection is keeping the service
+ // created, then we want to try to better follow
+ // its memory management semantics for activities.
+ // That is, if it is sitting in the background
+ // LRU list as a hidden process (with activities),
+ // we don't want the service it is connected to
+ // to go into the empty LRU and quickly get killed,
+ // because I'll we'll do is just end up restarting
+ // the service.
+ app.hasClientActivities |= client.hasActivities;
+ }
+ }
+ if (adj > clientAdj) {
+ // If this process has recently shown UI, and
+ // the process that is binding to it is less
+ // important than being visible, then we don't
+ // care about the binding as much as we care
+ // about letting this process get into the LRU
+ // list to be killed and restarted if needed for
+ // memory.
+ if (app.hasShownUi && app != mHomeProcess
+ && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ adjType = "bound-bg-ui-services";
+ } else {
+ if ((cr.flags&(Context.BIND_ABOVE_CLIENT
+ |Context.BIND_IMPORTANT)) != 0) {
+ adj = clientAdj;
+ } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
+ && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
+ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+ } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
+ adj = clientAdj;
+ } else {
+ app.pendingUiClean = true;
+ if (adj > ProcessList.VISIBLE_APP_ADJ) {
+ adj = ProcessList.VISIBLE_APP_ADJ;
+ }
+ }
+ if (!client.hidden) {
+ app.hidden = false;
+ }
+ if (client.keeping) {
+ app.keeping = true;
+ }
+ adjType = "service";
+ }
+ }
+ if (adjType != null) {
+ app.adjType = adjType;
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_SERVICE_IN_USE;
+ app.adjSource = cr.binding.client;
+ app.adjSourceOom = clientAdj;
+ app.adjTarget = s.name;
+ }
+ if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+ if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ }
+ }
+ }
+ final ActivityRecord a = cr.activity;
+ if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
+ if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
+ (a.visible || a.state == ActivityState.RESUMED
+ || a.state == ActivityState.PAUSING)) {
+ adj = ProcessList.FOREGROUND_APP_ADJ;
+ if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ }
+ app.hidden = false;
+ app.adjType = "service";
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_SERVICE_IN_USE;
+ app.adjSource = a;
+ app.adjSourceOom = adj;
+ app.adjTarget = s.name;
}
}
}
@@ -13288,86 +13397,84 @@
}
}
- if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
- Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
- while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
- ContentProviderRecord cpr = jt.next();
- for (int i = cpr.connections.size()-1;
- i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
- || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
- i--) {
- ContentProviderConnection conn = cpr.connections.get(i);
- ProcessRecord client = conn.client;
- if (client == app) {
- // Being our own client is not interesting.
- continue;
- }
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
- } else {
- myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
- }
- }
- int myClientHiddenAdj = clientHiddenAdj;
- if (myClientHiddenAdj > client.clientHiddenAdj) {
- if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- myClientHiddenAdj = client.clientHiddenAdj;
- } else {
- myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
- }
- }
- int myEmptyAdj = emptyAdj;
- if (myEmptyAdj > client.emptyAdj) {
- if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
- myEmptyAdj = client.emptyAdj;
- } else {
- myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
- }
- }
- int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
- if (adj > clientAdj) {
- if (app.hasShownUi && app != mHomeProcess
- && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- app.adjType = "bg-ui-provider";
- } else {
- adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
- ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
- app.adjType = "provider";
- }
- if (!client.hidden) {
- app.hidden = false;
- }
- if (client.keeping) {
- app.keeping = true;
- }
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_PROVIDER_IN_USE;
- app.adjSource = client;
- app.adjSourceOom = clientAdj;
- app.adjTarget = cpr.name;
- }
- if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
- schedGroup = Process.THREAD_GROUP_DEFAULT;
+ for (int provi = app.pubProviders.size()-1;
+ provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+ || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ provi--) {
+ ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
+ for (int i = cpr.connections.size()-1;
+ i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+ || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ i--) {
+ ContentProviderConnection conn = cpr.connections.get(i);
+ ProcessRecord client = conn.client;
+ if (client == app) {
+ // Being our own client is not interesting.
+ continue;
+ }
+ int myHiddenAdj = hiddenAdj;
+ if (myHiddenAdj > client.hiddenAdj) {
+ if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
+ myHiddenAdj = client.hiddenAdj;
+ } else {
+ myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
- // If the provider has external (non-framework) process
- // dependencies, ensure that its adjustment is at least
- // FOREGROUND_APP_ADJ.
- if (cpr.hasExternalProcessHandles()) {
- if (adj > ProcessList.FOREGROUND_APP_ADJ) {
- adj = ProcessList.FOREGROUND_APP_ADJ;
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.hidden = false;
- app.keeping = true;
- app.adjType = "provider";
- app.adjTarget = cpr.name;
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
+ int myEmptyAdj = emptyAdj;
+ if (myEmptyAdj > client.emptyAdj) {
+ if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
+ myEmptyAdj = client.emptyAdj;
+ } else {
+ myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
+ }
+ }
+ int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
+ if (adj > clientAdj) {
+ if (app.hasShownUi && app != mHomeProcess
+ && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ app.adjType = "bg-ui-provider";
+ } else {
+ adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
+ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
+ app.adjType = "provider";
+ }
+ if (!client.hidden) {
+ app.hidden = false;
+ }
+ if (client.keeping) {
+ app.keeping = true;
+ }
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_PROVIDER_IN_USE;
+ app.adjSource = client;
+ app.adjSourceOom = clientAdj;
+ app.adjTarget = cpr.name;
+ }
+ if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ }
+ }
+ // If the provider has external (non-framework) process
+ // dependencies, ensure that its adjustment is at least
+ // FOREGROUND_APP_ADJ.
+ if (cpr.hasExternalProcessHandles()) {
+ if (adj > ProcessList.FOREGROUND_APP_ADJ) {
+ adj = ProcessList.FOREGROUND_APP_ADJ;
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ app.hidden = false;
+ app.keeping = true;
+ app.adjType = "provider";
+ app.adjTarget = cpr.name;
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index a40b13c..561dd0f 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -86,6 +86,7 @@
CharSequence nonLocalizedLabel; // the label information from the package mgr.
int labelRes; // the label information from the package mgr.
int icon; // resource identifier of activity's icon.
+ int logo; // resource identifier of activity's logo.
int theme; // resource identifier of activity's theme.
int realTheme; // actual theme resource we will use, never 0.
int windowFlags; // custom window flags for preview window.
@@ -399,6 +400,7 @@
labelRes = app.labelRes;
}
icon = aInfo.getIconResource();
+ logo = aInfo.getLogoResource();
theme = aInfo.getThemeResource();
realTheme = theme;
if (realTheme == 0) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index d6a6eb8..5e6bdb1 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1465,8 +1465,8 @@
mWindowManager.setAppStartingWindow(
next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
- next.nonLocalizedLabel, next.labelRes, next.icon, next.windowFlags,
- null, true);
+ next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
+ next.windowFlags, null, true);
}
mStackSupervisor.startSpecificActivityLocked(next, true, false);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
@@ -1500,7 +1500,7 @@
mService.compatibilityInfoForPackageLocked(
next.info.applicationInfo),
next.nonLocalizedLabel,
- next.labelRes, next.icon, next.windowFlags,
+ next.labelRes, next.icon, next.logo, next.windowFlags,
null, true);
}
if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
@@ -1639,7 +1639,7 @@
r.appToken, r.packageName, r.theme,
mService.compatibilityInfoForPackageLocked(
r.info.applicationInfo), r.nonLocalizedLabel,
- r.labelRes, r.icon, r.windowFlags,
+ r.labelRes, r.icon, r.logo, r.windowFlags,
prev != null ? prev.appToken : null, showStartingIcon);
}
} else {
@@ -3333,14 +3333,20 @@
}
}
- void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
- boolean dumpClient, String dumpPackage) {
+ boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+ boolean dumpClient, String dumpPackage, boolean needSep, String header) {
+ boolean printed = false;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- pw.print(" Task "); pw.print(taskNdx); pw.print(": id #"); pw.println(task.taskId);
- ActivityStackSupervisor.dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities,
- " ", "Hist", true, !dumpAll, dumpClient, dumpPackage);
+ printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
+ mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll,
+ dumpClient, dumpPackage, needSep, header,
+ " Task " + taskNdx + ": id #" + task.taskId);
+ if (printed) {
+ header = null;
+ }
}
+ return printed;
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index bddca2b..b02a3e8 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2209,88 +2209,113 @@
pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
pw.println(mDismissKeyguardOnNextActivity);
pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
+ pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
+ pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
return getFocusedStack().getDumpActivitiesLocked(name);
}
+ static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
+ boolean needSep, String prefix) {
+ if (activity != null) {
+ if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
+ if (needSep) {
+ pw.println();
+ }
+ pw.print(prefix);
+ pw.println(activity);
+ return true;
+ }
+ }
+ return false;
+ }
+
boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
boolean dumpClient, String dumpPackage) {
- pw.print(" mStackState="); pw.println(stackStateToString(mStackState));
- if (mGoingToSleepActivities.size() > 0) {
- pw.println(" Activities waiting to sleep:");
- dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false,
- dumpPackage);
- }
- if (dumpAll) {
- pw.println(" mSleepTimeout: " + mSleepTimeout);
- }
+ boolean printed = false;
+ boolean needSep = false;
final int numStacks = mStacks.size();
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
- pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":");
- stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
- pw.println(" ");
- pw.println(" Running activities (most recent first):");
- dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false,
- dumpPackage);
+ StringBuilder stackHeader = new StringBuilder(128);
+ stackHeader.append(" Stack #");
+ stackHeader.append(mStacks.indexOf(stack));
+ stackHeader.append(":");
+ printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
+ stackHeader.toString());
+ printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll,
+ false, dumpPackage, true, " Running activities (most recent first):", null);
- pw.print(" Stack #"); pw.println(mStacks.indexOf(stack));
- if (stack.mPausingActivity != null) {
- pw.println(" mPausingActivity: " + stack.mPausingActivity);
+ needSep = printed;
+ boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
+ " mPausingActivity: ");
+ if (pr) {
+ printed = true;
+ needSep = false;
}
- pw.println(" mResumedActivity: " + stack.mResumedActivity);
+ pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
+ " mResumedActivity: ");
+ if (pr) {
+ printed = true;
+ needSep = false;
+ }
if (dumpAll) {
- pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity);
+ pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
+ " mLastPausedActivity: ");
+ if (pr) {
+ printed = true;
+ }
}
+ needSep = printed;
}
- if (mFinishingActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to finish:");
- dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll, false,
- dumpPackage);
- }
+ printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
+ false, dumpPackage, true, " Activities waiting to finish:", null);
+ printed |= dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll,
+ false, dumpPackage, true, " Activities waiting to stop:", null);
+ printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
+ false, dumpPackage, true, " Activities waiting for another to become visible:",
+ null);
+ printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
+ false, dumpPackage, true, " Activities waiting to sleep:", null);
+ printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, " ", "Sleep", false, !dumpAll,
+ false, dumpPackage, true, " Activities waiting to sleep:", null);
- if (mStoppingActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to stop:");
- dumpHistoryList(fd, pw, mStoppingActivities, " ", "Stop", false, !dumpAll, false,
- dumpPackage);
- }
-
- if (mWaitingVisibleActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting for another to become visible:");
- dumpHistoryList(fd, pw, mWaitingVisibleActivities, " ", "Wait", false, !dumpAll,
- false, dumpPackage);
- }
-
- if (dumpAll) {
- pw.println(" ");
- pw.println(" mCurTaskId: " + mCurTaskId);
- }
- return true;
+ return printed;
}
- static void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
+ static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
String prefix, String label, boolean complete, boolean brief, boolean client,
- String dumpPackage) {
+ String dumpPackage, boolean needNL, String header1, String header2) {
TaskRecord lastTask = null;
- boolean needNL = false;
- final String innerPrefix = prefix + " ";
- final String[] args = new String[0];
+ String innerPrefix = null;
+ String[] args = null;
+ boolean printed = false;
for (int i=list.size()-1; i>=0; i--) {
final ActivityRecord r = list.get(i);
if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
continue;
}
+ if (innerPrefix == null) {
+ innerPrefix = prefix + " ";
+ args = new String[0];
+ }
+ printed = true;
final boolean full = !brief && (complete || !r.isInHistory());
if (needNL) {
- pw.println(" ");
+ pw.println("");
needNL = false;
}
+ if (header1 != null) {
+ pw.println(header1);
+ header1 = null;
+ }
+ if (header2 != null) {
+ pw.println(header2);
+ header2 = null;
+ }
if (lastTask != r.task) {
lastTask = r.task;
pw.print(prefix);
@@ -2341,6 +2366,7 @@
needNL = true;
}
}
+ return printed;
}
void scheduleIdleTimeoutLocked(ActivityRecord next) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 7929f96..3a4a34c 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -32,12 +32,12 @@
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
/**
@@ -129,8 +129,8 @@
// all IIntentReceivers that are registered from this process.
final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
// class (String) -> ContentProviderRecord
- final HashMap<String, ContentProviderRecord> pubProviders
- = new HashMap<String, ContentProviderRecord>();
+ final ArrayMap<String, ContentProviderRecord> pubProviders
+ = new ArrayMap<String, ContentProviderRecord>();
// All ContentProviderRecord process is using
final ArrayList<ContentProviderConnection> conProviders
= new ArrayList<ContentProviderConnection>();
@@ -302,9 +302,9 @@
}
if (pubProviders.size() > 0) {
pw.print(prefix); pw.println("Published Providers:");
- for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) {
- pw.print(prefix); pw.print(" - "); pw.println(ent.getKey());
- pw.print(prefix); pw.print(" -> "); pw.println(ent.getValue());
+ for (int i=0; i<pubProviders.size(); i++) {
+ pw.print(prefix); pw.print(" - "); pw.println(pubProviders.keyAt(i));
+ pw.print(prefix); pw.print(" -> "); pw.println(pubProviders.valueAt(i));
}
}
if (conProviders.size() > 0) {
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 9dbf5f5..ee406c8 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -230,58 +230,87 @@
return didSomething;
}
- private void dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll,
- HashMap<ComponentName, ContentProviderRecord> map) {
+ private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage,
+ String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) {
Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
+ boolean written = false;
while (it.hasNext()) {
Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
ContentProviderRecord r = e.getValue();
+ if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+ continue;
+ }
+ if (needSep) {
+ pw.println("");
+ needSep = false;
+ }
+ if (header != null) {
+ pw.println(header);
+ header = null;
+ }
+ written = true;
pw.print(" * ");
pw.println(r);
r.dump(pw, " ", dumpAll);
}
+ return written;
}
- private void dumpProvidersByNameLocked(PrintWriter pw,
- HashMap<String, ContentProviderRecord> map) {
+ private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage,
+ String header, boolean needSep, HashMap<String, ContentProviderRecord> map) {
Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator();
+ boolean written = false;
while (it.hasNext()) {
Map.Entry<String, ContentProviderRecord> e = it.next();
ContentProviderRecord r = e.getValue();
+ if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+ continue;
+ }
+ if (needSep) {
+ pw.println("");
+ needSep = false;
+ }
+ if (header != null) {
+ pw.println(header);
+ header = null;
+ }
+ written = true;
pw.print(" ");
pw.print(e.getKey());
pw.print(": ");
pw.println(r.toShortString());
}
+ return written;
}
- void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) {
+ boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) {
+ boolean needSep = false;
+
if (mSingletonByClass.size() > 0) {
- pw.println(" Published single-user content providers (by class):");
- dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass);
+ needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
+ " Published single-user content providers (by class):", needSep,
+ mSingletonByClass);
}
- pw.println("");
for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
- pw.println("");
- pw.println(" Published user " + mProvidersByClassPerUser.keyAt(i)
- + " content providers (by class):");
- dumpProvidersByClassLocked(pw, dumpAll, map);
+ needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
+ " Published user " + mProvidersByClassPerUser.keyAt(i)
+ + " content providers (by class):", needSep, map);
}
if (dumpAll) {
- pw.println("");
- pw.println(" Single-user authority to provider mappings:");
- dumpProvidersByNameLocked(pw, mSingletonByName);
+ needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
+ " Single-user authority to provider mappings:", needSep, mSingletonByName);
for (int i = 0; i < mProvidersByNamePerUser.size(); i++) {
- pw.println("");
- pw.println(" User " + mProvidersByNamePerUser.keyAt(i)
- + " authority to provider mappings:");
- dumpProvidersByNameLocked(pw, mProvidersByNamePerUser.valueAt(i));
+ needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
+ " User " + mProvidersByNamePerUser.keyAt(i)
+ + " authority to provider mappings:", needSep,
+ mProvidersByNamePerUser.valueAt(i));
}
}
+ return needSep;
}
protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 9fdd293..707e8ee 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -16,34 +16,32 @@
package com.android.server.am;
-import android.app.PendingIntent;
-import android.net.Uri;
-import android.provider.Settings;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.NotificationManagerService;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.Slog;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
/**
@@ -76,11 +74,11 @@
final boolean exported; // from ServiceInfo.exported
final Runnable restarter; // used to schedule retries of starting the service
final long createTime; // when this service was created
- final HashMap<Intent.FilterComparison, IntentBindRecord> bindings
- = new HashMap<Intent.FilterComparison, IntentBindRecord>();
+ final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
+ = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
// All active bindings to the service.
- final HashMap<IBinder, ArrayList<ConnectionRecord>> connections
- = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
+ final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
+ = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
// IBinder -> ConnectionRecord of all bound clients
ProcessRecord app; // where this service is running or null.
@@ -258,10 +256,9 @@
dumpStartList(pw, prefix, pendingStarts, 0);
}
if (bindings.size() > 0) {
- Iterator<IntentBindRecord> it = bindings.values().iterator();
pw.print(prefix); pw.println("Bindings:");
- while (it.hasNext()) {
- IntentBindRecord b = it.next();
+ for (int i=0; i<bindings.size(); i++) {
+ IntentBindRecord b = bindings.valueAt(i);
pw.print(prefix); pw.print("* IntentBindRecord{");
pw.print(Integer.toHexString(System.identityHashCode(b)));
if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) {
@@ -273,9 +270,8 @@
}
if (connections.size() > 0) {
pw.print(prefix); pw.println("All Connections:");
- Iterator<ArrayList<ConnectionRecord>> it = connections.values().iterator();
- while (it.hasNext()) {
- ArrayList<ConnectionRecord> c = it.next();
+ for (int conni=0; conni<connections.size(); conni++) {
+ ArrayList<ConnectionRecord> c = connections.valueAt(conni);
for (int i=0; i<c.size(); i++) {
pw.print(prefix); pw.print(" "); pw.println(c.get(i));
}
diff --git a/services/java/com/android/server/wifi/WifiController.java b/services/java/com/android/server/wifi/WifiController.java
index 228fabf..87b4394 100644
--- a/services/java/com/android/server/wifi/WifiController.java
+++ b/services/java/com/android/server/wifi/WifiController.java
@@ -150,7 +150,11 @@
addState(mStaDisabledWithScanState, mDefaultState);
addState(mApEnabledState, mDefaultState);
addState(mEcmState, mDefaultState);
- setInitialState(mApStaDisabledState);
+ if (mSettingsStore.isScanAlwaysAvailable()) {
+ setInitialState(mStaDisabledWithScanState);
+ } else {
+ setInitialState(mApStaDisabledState);
+ }
setLogRecSize(100);
setLogOnlyTransitions(false);
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index 8ddc776..66ef978 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -651,7 +651,12 @@
Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
" with persist set to " + persist);
enforceChangePermission();
- mWifiStateMachine.setCountryCode(countryCode, persist);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mWifiStateMachine.setCountryCode(countryCode, persist);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
/**
@@ -668,7 +673,12 @@
if (!isDualBandSupported()) return;
Slog.i(TAG, "WifiService trying to set frequency band to " + band +
" with persist set to " + persist);
- mWifiStateMachine.setFrequencyBand(band, persist);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mWifiStateMachine.setFrequencyBand(band, persist);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 0647296..4a3699c 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -340,7 +340,7 @@
boolean setStackBoxSize(Rect contentRect) {
boolean change = false;
for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
- change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect);
+ change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect, true);
}
return change;
}
diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java
index 15f5dff..d352464 100644
--- a/services/java/com/android/server/wm/StackBox.java
+++ b/services/java/com/android/server/wm/StackBox.java
@@ -79,6 +79,9 @@
/** Dirty flag. Something inside this or some descendant of this has changed. */
boolean layoutNeeded;
+ /** True if this StackBox sits below the Status Bar. */
+ boolean mUnderStatusBar;
+
/** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */
Rect mTmpRect = new Rect();
@@ -286,14 +289,19 @@
/** If this is a terminal StackBox (contains a TaskStack) set the bounds.
* @param bounds The rectangle to set the bounds to.
+ * @param underStatusBar True if the StackBox is directly below the Status Bar.
* @return True if the bounds changed, false otherwise. */
- boolean setStackBoxSizes(Rect bounds) {
- boolean change;
+ boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) {
+ boolean change = false;
+ if (mUnderStatusBar != underStatusBar) {
+ change = true;
+ mUnderStatusBar = underStatusBar;
+ }
if (mStack != null) {
- change = !mBounds.equals(bounds);
+ change |= !mBounds.equals(bounds);
if (change) {
mBounds.set(bounds);
- mStack.setBounds(bounds);
+ mStack.setBounds(bounds, underStatusBar);
}
} else {
mTmpRect.set(bounds);
@@ -301,18 +309,18 @@
final int height = bounds.height();
int firstHeight = (int)(height * mWeight);
mTmpRect.bottom = bounds.top + firstHeight;
- change = mFirst.setStackBoxSizes(mTmpRect);
+ change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
mTmpRect.top = mTmpRect.bottom;
mTmpRect.bottom = bounds.top + height;
- change |= mSecond.setStackBoxSizes(mTmpRect);
+ change |= mSecond.setStackBoxSizes(mTmpRect, false);
} else {
final int width = bounds.width();
int firstWidth = (int)(width * mWeight);
mTmpRect.right = bounds.left + firstWidth;
- change = mFirst.setStackBoxSizes(mTmpRect);
+ change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
mTmpRect.left = mTmpRect.right;
mTmpRect.right = bounds.left + width;
- change |= mSecond.setStackBoxSizes(mTmpRect);
+ change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar);
}
}
return change;
diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java
index 46bb480..7115b0f 100644
--- a/services/java/com/android/server/wm/StartingData.java
+++ b/services/java/com/android/server/wm/StartingData.java
@@ -25,17 +25,19 @@
final CharSequence nonLocalizedLabel;
final int labelRes;
final int icon;
+ final int logo;
final int windowFlags;
StartingData(String _pkg, int _theme, CompatibilityInfo _compatInfo,
CharSequence _nonLocalizedLabel,
- int _labelRes, int _icon, int _windowFlags) {
+ int _labelRes, int _icon, int _logo, int _windowFlags) {
pkg = _pkg;
theme = _theme;
compatInfo = _compatInfo;
nonLocalizedLabel = _nonLocalizedLabel;
labelRes = _labelRes;
icon = _icon;
+ logo = _logo;
windowFlags = _windowFlags;
}
}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java
index 6fd8745..827958d 100644
--- a/services/java/com/android/server/wm/TaskStack.java
+++ b/services/java/com/android/server/wm/TaskStack.java
@@ -222,7 +222,7 @@
}
}
- void setBounds(Rect bounds) {
+ void setBounds(Rect bounds, boolean underStatusBar) {
mDimLayer.setBounds(bounds);
mAnimationBackgroundSurface.setBounds(bounds);
@@ -236,6 +236,7 @@
if (!resizingWindows.contains(win)) {
resizingWindows.add(win);
}
+ win.mUnderStatusBar = underStatusBar;
}
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index a1e07dc..f166c31 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3487,9 +3487,9 @@
final int firstToken = tokens.size() - 1;
for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
final AppWindowToken atoken = tokens.get(tokenNdx);
-
+
if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
-
+
// if we're about to tear down this window and not seek for
// the behind activity, don't use it for orientation
if (!findingBehind
@@ -3498,7 +3498,7 @@
+ " -- going to hide");
continue;
}
-
+
if (tokenNdx == firstToken) {
// If we have hit a new Task, and the bottom
// of the previous group didn't explicitly say to use
@@ -3512,19 +3512,19 @@
return lastOrientation;
}
}
-
+
// We ignore any hidden applications on the top.
if (atoken.hiddenRequested || atoken.willBeHidden) {
if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
+ " -- hidden on top");
continue;
}
-
+
if (tokenNdx == 0) {
// Last token in this task.
lastOrientation = atoken.requestedOrientation;
}
-
+
int or = atoken.requestedOrientation;
// If this application is fullscreen, and didn't explicitly say
// to use the orientation behind it, then just take whatever
@@ -3878,7 +3878,7 @@
@Override
public void setAppStartingWindow(IBinder token, String pkg,
int theme, CompatibilityInfo compatInfo,
- CharSequence nonLocalizedLabel, int labelRes, int icon,
+ CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppStartingWindow()")) {
@@ -4079,7 +4079,7 @@
if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
mStartingIconInTransition = true;
wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
- labelRes, icon, windowFlags);
+ labelRes, icon, logo, windowFlags);
Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
// Note: we really want to do sendMessageAtFrontOfQueue() because we
// want to process the message ASAP, before any other queued
@@ -7083,7 +7083,7 @@
try {
view = mPolicy.addStartingWindow(
wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
- sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
+ sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
} catch (Exception e) {
Slog.w(TAG, "Exception when adding starting window", e);
}
@@ -8605,7 +8605,7 @@
|| winAnimator.mSurfaceResized
|| configChanged) {
if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
- Slog.v(TAG, "Resize reasons: "
+ Slog.v(TAG, "Resize reasons for w=" + w + ": "
+ " contentInsetsChanged=" + w.mContentInsetsChanged
+ " " + w.mContentInsets.toShortString()
+ " visibleInsetsChanged=" + w.mVisibleInsetsChanged
@@ -9346,7 +9346,7 @@
}
setFocusedStackFrame();
-
+
// Check to see if we are now in a state where the screen should
// be enabled, because the window obscured flags have changed.
enableScreenIfNeededLocked();
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 377e8e8..7c6da92 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -298,6 +298,10 @@
/** When true this window can be displayed on screens owther than mOwnerUid's */
private boolean mShowToOwnerOnly;
+ /** When true this window is at the top of the screen and should be layed out to extend under
+ * the status bar */
+ boolean mUnderStatusBar = true;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, final DisplayContent displayContent) {
@@ -434,6 +438,9 @@
if (mAppToken != null) {
mContainingFrame.set(getStackBounds());
+ if (mUnderStatusBar) {
+ mContainingFrame.top = pf.top;
+ }
} else {
mContainingFrame.set(pf);
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 8b85d8c..3ae2106 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -152,6 +152,11 @@
String number = null;
Uri uri = intent.getData();
+
+ if (uri == null) {
+ return null;
+ }
+
String scheme = uri.getScheme();
if (scheme.equals("tel") || scheme.equals("sip")) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c14d61b..26dde1e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -130,10 +130,10 @@
* call. By default, the MMS app consumes this message and sends a text message to the caller. A
* third party app can provide this functionality in lieu of MMS app by consuming this Intent
* and sending the message using their own messaging system. The intent contains a URI
- * describing the recipient, and an EXTRA containg the message itself.
- * <p>
+ * describing the recipient, and an EXTRA containing the message itself.
+ * <p class="note"><strong>Note:</strong>
* The intent-filter which consumes this Intent needs to be in a service which requires the
- * permission SEND_RESPOND_VIA_MESSAGE.
+ * permission {@link android.Manifest.permission#SEND_RESPOND_VIA_MESSAGE}.</p>
*
* <p>
* {@link android.content.Intent#getData} is a URI describing the recipient of the message.
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
index 668f61d..3681784 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
@@ -49,8 +49,8 @@
float4 diff = idealPixel - givenPixel;
float totalDiff = diff.x + diff.y + diff.z + diff.w;
if (totalDiff < 0) {
- v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2, 0, 1));
+ v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2.f, 0.f, 1.f));
} else {
- v_out[0] = rsPackColorTo8888(clamp(totalDiff/2, 0, 1), 0, 0);
+ v_out[0] = rsPackColorTo8888(clamp(totalDiff/2.f, 0.f, 1.f), 0, 0);
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
index 13b6129..db6421e 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
@@ -20,19 +20,15 @@
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
-import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.ContextMenu;
import android.view.View;
-import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
-import java.io.File;
-
@SuppressWarnings({"UnusedDeclaration"})
public class ListActivity extends Activity {
private static final String[] DATA_LIST = {
@@ -86,7 +82,7 @@
ListAdapter adapter = new SimpleListAdapter(this);
- ListView list = (ListView) findViewById(R.id.list);
+ final ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
registerForContextMenu(list);
diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml
index 8cd36bf..be6b145 100644
--- a/tests/TransitionTests/AndroidManifest.xml
+++ b/tests/TransitionTests/AndroidManifest.xml
@@ -205,6 +205,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:label="InterruptionTest"
+ android:name="InterruptionTest">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
diff --git a/tests/TransitionTests/res/layout/interruption.xml b/tests/TransitionTests/res/layout/interruption.xml
new file mode 100644
index 0000000..9fdb27a
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <RadioGroup android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <RadioButton android:id="@+id/scene1RB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/state1"
+ android:onClick="onRadioButtonClicked"/>
+ <RadioButton android:id="@+id/scene2RB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/state2"
+ android:onClick="onRadioButtonClicked"/>
+ <RadioButton android:id="@+id/scene3RB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/state3"
+ android:onClick="onRadioButtonClicked"/>
+ <RadioButton android:id="@+id/scene4RB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/state4"
+ android:onClick="onRadioButtonClicked"/>
+ </RadioGroup>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:id="@+id/sceneRoot"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/interruption_inner_1"/>
+
+ </LinearLayout>
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_1.xml b/tests/TransitionTests/res/layout/interruption_inner_1.xml
new file mode 100644
index 0000000..f82dfb0
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_1.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/buttonContainer">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:text="@string/state1"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button1"
+ android:layout_alignLeft="@+id/button"
+ android:layout_below="@+id/button"
+ android:text="@string/state1"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_2.xml b/tests/TransitionTests/res/layout/interruption_inner_2.xml
new file mode 100644
index 0000000..e6821d6
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_2.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/buttonContainer">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:id="@+id/button"
+ android:layout_alignParentRight="true"
+ android:text="@string/state2"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button1"
+ android:layout_alignLeft="@+id/button"
+ android:layout_below="@+id/button"
+ android:text="@string/state2"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_3.xml b/tests/TransitionTests/res/layout/interruption_inner_3.xml
new file mode 100644
index 0000000..4e40150
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_3.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/buttonContainer">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:text="@string/state3"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button1"
+ android:layout_alignLeft="@+id/button"
+ android:layout_above="@+id/button"
+ android:text="@string/state3"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_4.xml b/tests/TransitionTests/res/layout/interruption_inner_4.xml
new file mode 100644
index 0000000..8c3661e
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_4.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/buttonContainer">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:text="@string/state4"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/button1"
+ android:layout_alignLeft="@+id/button"
+ android:layout_above="@+id/button"
+ android:text="@string/state4"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/values/strings.xml b/tests/TransitionTests/res/values/strings.xml
index e251d5c..3be243b 100644
--- a/tests/TransitionTests/res/values/strings.xml
+++ b/tests/TransitionTests/res/values/strings.xml
@@ -39,4 +39,8 @@
<string name="shortText2">Not much text here</string>
<string name="longText1">This is the beginning of the Spring of my discontent. In the event of a real emergency, you would be notified by email. Fear not, for death comes swiftly.</string>
<string name="longText2">When do we get to eat? I like all things, especially following strong leaders, and mangy cats. Break glass in emergency. The purpose of a framework is to provide the facilities and functionality of a powerful toolkit with the simplicity of a refrigerator.</string>
+ <string name="state1">State 1</string>
+ <string name="state2">State 2</string>
+ <string name="state3">State 3</string>
+ <string name="state4">State 4</string>
</resources>
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
index 3bb7100..05bed5f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
@@ -29,10 +29,8 @@
public class ChangingText extends Activity {
- Button mRemovingButton, mInvisibleButton, mGoneButton;
Scene mScene1, mScene2;
ViewGroup mSceneRoot;
- Fade fader;
TransitionGroup mChanger;
@Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
index 2fcdc30..d5f6a28 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -45,6 +45,8 @@
mScene2 = new Scene(mSceneRoot, R.layout.crossfade_1, this);
Crossfade crossfade = new Crossfade();
+ crossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
+ crossfade.setResizeBehavior(Crossfade.RESIZE_BEHAVIOR_NONE);
crossfade.setTargetIds(R.id.textview, R.id.textview1, R.id.textview2);
mTransitionManager = new TransitionManager();
TransitionGroup moveCrossFade = new TransitionGroup();
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
new file mode 100644
index 0000000..b380225
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2013 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.transition.AutoTransition;
+import android.view.transition.Move;
+import android.view.transition.Scene;
+import android.view.transition.TextChange;
+import android.view.transition.Transition;
+import android.view.transition.TransitionGroup;
+import android.view.transition.TransitionManager;
+import android.widget.RadioButton;
+
+public class InterruptionTest extends Activity {
+
+ RadioButton mScene1RB, mScene2RB, mScene3RB, mScene4RB;
+ private Scene mScene1;
+ private Scene mScene2;
+ private Scene mScene3;
+ private Scene mScene4;
+ TransitionGroup mSequencedMove = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.interruption);
+
+ ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
+
+ mScene1 = new Scene(sceneRoot, R.layout.interruption_inner_1, this);
+ mScene2 = new Scene(sceneRoot, R.layout.interruption_inner_2, this);
+ mScene3 = new Scene(sceneRoot, R.layout.interruption_inner_3, this);
+ mScene4 = new Scene(sceneRoot, R.layout.interruption_inner_4, this);
+
+ mScene1RB = (RadioButton) findViewById(R.id.scene1RB);
+ mScene2RB = (RadioButton) findViewById(R.id.scene2RB);
+ mScene3RB = (RadioButton) findViewById(R.id.scene3RB);
+ mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
+
+ sceneRoot.setCurrentScene(mScene1);
+
+ Move move1 = new Move();
+ move1.setTargetIds(R.id.button);
+ Move move2 = new Move();
+ move2.setTargetIds(R.id.button1);
+
+ mSequencedMove.addTransitions(move1, move2);
+ mSequencedMove.setDuration(1000);
+ }
+
+ public void onRadioButtonClicked(View clickedButton) {
+ if (clickedButton == mScene1RB) {
+ TransitionManager.go(mScene1, mSequencedMove);
+ } else if (clickedButton == mScene2RB) {
+ TransitionManager.go(mScene2, mSequencedMove);
+ } else if (clickedButton == mScene3RB) {
+ TransitionManager.go(mScene3, mSequencedMove);
+ } else {
+ TransitionManager.go(mScene4, mSequencedMove);
+ }
+ }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 10baac5..53318a4 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -164,7 +164,7 @@
}
try {
- mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, null, false);
+ mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, 0, null, false);
fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 0ca230c..a7b48bb 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -304,7 +304,7 @@
@Override
public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
- CharSequence arg4, int arg5, int arg6, int arg7, IBinder arg8, boolean arg9)
+ CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10)
throws RemoteException {
// TODO Auto-generated method stub
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index d53c320..9f3a0d3 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -347,6 +347,8 @@
public static final int CMD_DISABLE_P2P_REQ = BASE + 132;
public static final int CMD_DISABLE_P2P_RSP = BASE + 133;
+ public static final int CMD_BOOT_COMPLETED = BASE + 134;
+
public static final int CONNECT_MODE = 1;
public static final int SCAN_ONLY_MODE = 2;
public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE = 3;
@@ -410,6 +412,10 @@
private int mDelayedStopCounter;
private boolean mInDelayedStop = false;
+ // sometimes telephony gives us this data before boot is complete and we can't store it
+ // until after, so the write is deferred
+ private volatile String mPersistedCountryCode;
+
private static final int MIN_RSSI = -200;
private static final int MAX_RSSI = 256;
@@ -637,6 +643,15 @@
}
});
+ mContext.registerReceiver(
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ sendMessage(CMD_BOOT_COMPLETED);
+ }
+ },
+ new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+
mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
@@ -1004,6 +1019,7 @@
*/
public void setCountryCode(String countryCode, boolean persist) {
if (persist) {
+ mPersistedCountryCode = countryCode;
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.WIFI_COUNTRY_CODE,
countryCode);
@@ -1889,6 +1905,19 @@
setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true);
}
break;
+ case CMD_BOOT_COMPLETED:
+ String countryCode = mPersistedCountryCode;
+ if (TextUtils.isEmpty(countryCode) == false) {
+ Settings.Global.putString(mContext.getContentResolver(),
+ Settings.Global.WIFI_COUNTRY_CODE,
+ countryCode);
+ // it may be that the state transition that should send this info
+ // to the driver happened between mPersistedCountryCode getting set
+ // and now, so simply persisting it here would mean we have sent
+ // nothing to the driver. Send the cmd so it might be set now.
+ sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, countryCode);
+ }
+ break;
/* Discard */
case CMD_START_SUPPLICANT:
case CMD_STOP_SUPPLICANT:
@@ -2359,7 +2388,6 @@
mInDelayedStop = false;
mDelayedStopCounter++;
updateBatteryWorkSource(null);
-
/**
* Enable bluetooth coexistence scan mode when bluetooth connection is active.
* When this mode is on, some of the low-level scan parameters used by the