summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java2
-rw-r--r--core/java/android/app/ActivityManagerNative.java47
-rw-r--r--core/java/android/app/ActivityView.java39
-rw-r--r--core/java/android/app/ApplicationPackageManager.java2
-rw-r--r--core/java/android/app/ApplicationThreadNative.java4
-rw-r--r--core/java/android/app/ContextImpl.java7
-rw-r--r--core/java/android/app/IActivityManager.java11
-rw-r--r--core/java/android/app/IAlarmManager.aidl2
-rw-r--r--core/java/android/app/OnActivityPausedListener.java2
-rw-r--r--core/java/android/app/PendingIntent.java14
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java50
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl4
-rw-r--r--core/java/android/appwidget/AppWidgetProviderInfo.java2
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl4
-rw-r--r--core/java/android/content/pm/PackageInfo.java21
-rw-r--r--core/java/android/content/pm/PackageParser.java6
-rw-r--r--core/java/android/content/pm/UserInfo.java9
-rw-r--r--core/java/android/content/res/ColorStateList.java40
-rw-r--r--core/java/android/hardware/GeomagneticField.java2
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java38
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java46
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java207
-rw-r--r--core/java/android/net/ConnectivityManager.java7
-rw-r--r--core/java/android/net/IConnectivityManager.aidl4
-rw-r--r--core/java/android/net/NetworkStats.java72
-rw-r--r--core/java/android/net/ProxyDataTracker.java110
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl1
-rw-r--r--core/java/android/nfc/NdefRecord.java42
-rw-r--r--core/java/android/nfc/NfcActivityManager.java11
-rw-r--r--core/java/android/nfc/NfcAdapter.java39
-rw-r--r--core/java/android/os/BatteryProperties.java19
-rw-r--r--core/java/android/os/BatteryStats.java10
-rw-r--r--core/java/android/os/Broadcaster.java8
-rw-r--r--core/java/android/os/IPowerManager.aidl6
-rw-r--r--core/java/android/os/PowerManager.java9
-rw-r--r--core/java/android/os/SystemClock.java23
-rw-r--r--core/java/android/os/UserManager.java26
-rw-r--r--core/java/android/preference/GenericInflater.java2
-rw-r--r--core/java/android/provider/Settings.java6
-rw-r--r--core/java/android/text/style/BackgroundColorSpan.java20
-rw-r--r--core/java/android/text/style/CharacterStyle.java2
-rw-r--r--core/java/android/text/style/ForegroundColorSpan.java20
-rw-r--r--core/java/android/text/style/MaskFilterSpan.java22
-rw-r--r--core/java/android/text/style/MetricAffectingSpan.java2
-rw-r--r--core/java/android/text/style/RasterizerSpan.java22
-rw-r--r--core/java/android/text/style/RelativeSizeSpan.java30
-rw-r--r--core/java/android/text/style/ScaleXSpan.java30
-rw-r--r--core/java/android/text/style/StrikethroughSpan.java8
-rw-r--r--core/java/android/text/style/StyleSpan.java38
-rw-r--r--core/java/android/text/style/UnderlineSpan.java8
-rw-r--r--core/java/android/view/GLRenderer.java1
-rw-r--r--core/java/android/view/View.java61
-rw-r--r--core/java/android/view/ViewRootImpl.java188
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java28
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java30
-rw-r--r--core/java/android/widget/AbsListView.java116
-rw-r--r--core/java/android/widget/EditText.java19
-rw-r--r--core/java/android/widget/GridView.java86
-rw-r--r--core/java/android/widget/LinearLayout.java15
-rw-r--r--core/java/android/widget/ListView.java161
60 files changed, 1357 insertions, 504 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4f0683c..9a3c290 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1030,7 +1030,7 @@ public class Activity extends ContextThemeWrapper
/**
* Called after {@link #onCreate} — or after {@link #onRestart} when
* the activity had been stopped, but is now again being displayed to the
- * user. It will be followed by {@link #onResume}.
+ * user. It will be followed by {@link #onResume}.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b40008e..ea0ddc1 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1843,6 +1843,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IIntentSender r = IIntentSender.Stub.asInterface(
+ data.readStrongBinder());
+ String prefix = data.readString();
+ String tag = getTagForIntentSender(r, prefix);
+ reply.writeNoException();
+ reply.writeString(tag);
+ return true;
+ }
+
case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -2038,6 +2049,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case DELETE_ACTIVITY_CONTAINER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IActivityContainer activityContainer =
+ IActivityContainer.Stub.asInterface(data.readStrongBinder());
+ deleteActivityContainer(activityContainer);
+ reply.writeNoException();
+ return true;
+ }
+
case GET_ACTIVITY_CONTAINER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder activityToken = data.readStrongBinder();
@@ -4426,6 +4446,21 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public String getTagForIntentSender(IIntentSender sender, String prefix)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(sender.asBinder());
+ data.writeString(prefix);
+ mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ String res = reply.readString();
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void updatePersistentConfiguration(Configuration values) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -4697,6 +4732,18 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public void deleteActivityContainer(IActivityContainer activityContainer)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(activityContainer.asBinder());
+ mRemote.transact(DELETE_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 48ec420..113f123 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -37,8 +37,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+/** @hide */
public class ActivityView extends ViewGroup {
private final String TAG = "ActivityView";
+ private final boolean DEBUG = false;
private final TextureView mTextureView;
private IActivityContainer mActivityContainer;
@@ -76,6 +78,7 @@ public class ActivityView extends ViewGroup {
mTextureView = new TextureView(context);
mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
addView(mTextureView);
+ if (DEBUG) Log.v(TAG, "ctor()");
}
@Override
@@ -85,6 +88,8 @@ public class ActivityView extends ViewGroup {
@Override
protected void onAttachedToWindow() {
+ if (DEBUG) Log.v(TAG, "onAttachedToWindow()");
+ super.onAttachedToWindow();
try {
final IBinder token = mActivity.getActivityToken();
mActivityContainer =
@@ -99,19 +104,30 @@ public class ActivityView extends ViewGroup {
@Override
protected void onDetachedFromWindow() {
+ if (DEBUG) Log.v(TAG, "onDetachedFromWindow(): mActivityContainer=" + mActivityContainer);
+ super.onDetachedFromWindow();
if (mActivityContainer != null) {
detach();
+ try {
+ ActivityManagerNative.getDefault().deleteActivityContainer(mActivityContainer);
+ } catch (RemoteException e) {
+ }
mActivityContainer = null;
}
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
+ if (DEBUG) Log.v(TAG, "onWindowVisibilityChanged(): visibility=" + visibility);
super.onWindowVisibilityChanged(visibility);
- if (visibility == View.VISIBLE) {
- attachToSurfaceWhenReady();
- } else {
- detach();
+ switch (visibility) {
+ case View.VISIBLE:
+ attachToSurfaceWhenReady();
+ break;
+ case View.INVISIBLE:
+ break;
+ case View.GONE:
+ break;
}
}
@@ -143,6 +159,8 @@ public class ActivityView extends ViewGroup {
}
public void startActivity(Intent intent) {
+ if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " +
+ (isAttachedToDisplay() ? "" : "not") + " attached");
if (mSurface != null) {
try {
mActivityContainer.startActivity(intent);
@@ -165,6 +183,8 @@ public class ActivityView extends ViewGroup {
}
public void startActivity(IntentSender intentSender) {
+ if (DEBUG) Log.v(TAG, "startActivityIntentSender(): intentSender=" + intentSender + " " +
+ (isAttachedToDisplay() ? "" : "not") + " attached");
final IIntentSender iIntentSender = intentSender.getTarget();
if (mSurface != null) {
startActivityIntentSender(iIntentSender);
@@ -175,6 +195,8 @@ public class ActivityView extends ViewGroup {
}
public void startActivity(PendingIntent pendingIntent) {
+ if (DEBUG) Log.v(TAG, "startActivityPendingIntent(): PendingIntent=" + pendingIntent + " "
+ + (isAttachedToDisplay() ? "" : "not") + " attached");
final IIntentSender iIntentSender = pendingIntent.getTarget();
if (mSurface != null) {
startActivityIntentSender(iIntentSender);
@@ -205,6 +227,8 @@ public class ActivityView extends ViewGroup {
"ActivityView: Unable to create ActivityContainer. " + e);
}
+ if (DEBUG) Log.v(TAG, "attachToSurfaceWhenReady: " + (mQueuedIntent != null ||
+ mQueuedPendingIntent != null ? "" : "no") + " queued intent");
if (mQueuedIntent != null) {
startActivity(mQueuedIntent);
mQueuedIntent = null;
@@ -215,6 +239,7 @@ public class ActivityView extends ViewGroup {
}
private void detach() {
+ if (DEBUG) Log.d(TAG, "detach: attached=" + isAttachedToDisplay());
if (mSurface != null) {
try {
mActivityContainer.detachFromDisplay();
@@ -229,6 +254,8 @@ public class ActivityView extends ViewGroup {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width,
int height) {
+ if (DEBUG) Log.d(TAG, "onSurfaceTextureAvailable: width=" + width + " height="
+ + height);
mWidth = width;
mHeight = height;
if (mActivityContainer != null) {
@@ -239,12 +266,12 @@ public class ActivityView extends ViewGroup {
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
int height) {
- Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
+ if (DEBUG) Log.d(TAG, "onSurfaceTextureSizeChanged: w=" + width + " h=" + height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
- Log.d(TAG, "onSurfaceTextureDestroyed");
+ if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed");
detach();
return true;
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6b48130..061e5a5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1059,7 +1059,7 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
- public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
IPackageInstallObserver observer, int flags, String installerPackageName,
VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
try {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index c8f1280..20198f9 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -714,7 +714,7 @@ class ApplicationThreadProxy implements IApplicationThread {
}
public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
- throws RemoteException {
+ throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
@@ -884,7 +884,7 @@ class ApplicationThreadProxy implements IApplicationThread {
}
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
- int flags, Intent args) throws RemoteException {
+ int flags, Intent args) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ee73aba..9b3643c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -358,10 +358,11 @@ class ContextImpl extends Context {
ctx.mMainThread.getHandler());
}});
- registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
- public Object createStaticService() {
+ registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
- return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
+ return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b),
+ ctx.getPackageName());
}});
registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8c7fe10..4412261 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -367,6 +367,8 @@ public interface IActivityManager extends IInterface {
public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
+ public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
+
public void updatePersistentConfiguration(Configuration values) throws RemoteException;
public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -408,9 +410,13 @@ public interface IActivityManager extends IInterface {
public void performIdleMaintenance() throws RemoteException;
+ /** @hide */
public IActivityContainer createActivityContainer(IBinder parentActivityToken,
IActivityContainerCallback callback) throws RemoteException;
+ /** @hide */
+ public void deleteActivityContainer(IActivityContainer container) throws RemoteException;
+
public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
throws RemoteException;
@@ -704,4 +710,9 @@ public interface IActivityManager extends IInterface {
int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
+ int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
+
+
+ // Start of L transactions
+ int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
}
diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl
index 8476609..ef9f26e 100644
--- a/core/java/android/app/IAlarmManager.aidl
+++ b/core/java/android/app/IAlarmManager.aidl
@@ -28,7 +28,7 @@ interface IAlarmManager {
/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
void set(int type, long triggerAtTime, long windowLength,
long interval, in PendingIntent operation, in WorkSource workSource);
- void setTime(long millis);
+ boolean setTime(long millis);
void setTimeZone(String zone);
void remove(in PendingIntent operation);
}
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
index 379f133..5003973 100644
--- a/core/java/android/app/OnActivityPausedListener.java
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -5,7 +5,7 @@
* 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
+ * 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,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index d4de112..8efc14f 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -889,6 +889,20 @@ public final class PendingIntent implements Parcelable {
}
/**
+ * @hide
+ * Return descriptive tag for this PendingIntent.
+ */
+ public String getTag(String prefix) {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getTagForIntentSender(mTarget, prefix);
+ } catch (RemoteException e) {
+ // Should never happen.
+ return null;
+ }
+ }
+
+ /**
* Comparison operator on two PendingIntent objects, such that true
* is returned then they both represent the same operation from the
* same package. This allows you to use {@link #getActivity},
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 0cc878e..b4488cd 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -22,6 +22,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -1766,4 +1767,53 @@ public class DevicePolicyManager {
}
return null;
}
+
+ /**
+ * Called by a profile owner or device owner to add a default intent handler activity for
+ * intents that match a certain intent filter. This activity will remain the default intent
+ * handler even if the set of potential event handlers for the intent filter changes and if
+ * the intent preferences are reset.
+ *
+ * <p>The default disambiguation mechanism takes over if the activity is not installed
+ * (anymore). When the activity is (re)installed, it is automatically reset as default
+ * intent handler for the filter.
+ *
+ * <p>The calling device admin must be a profile owner or device owner. If it is not, a
+ * security exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param filter The IntentFilter for which a default handler is added.
+ * @param activity The Activity that is added as default intent handler.
+ */
+ public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
+ ComponentName activity) {
+ if (mService != null) {
+ try {
+ mService.addPersistentPreferredActivity(admin, filter, activity);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ }
+
+ /**
+ * Called by a profile owner or device owner to remove all persistent intent handler preferences
+ * associated with the given package that were set by {@link #addPersistentPreferredActivity}.
+ *
+ * <p>The calling device admin must be a profile owner. If it is not, a security
+ * exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param packageName The name of the package for which preferences are removed.
+ */
+ public void clearPackagePersistentPreferredActivities(ComponentName admin,
+ String packageName) {
+ if (mService != null) {
+ try {
+ mService.clearPackagePersistentPreferredActivities(admin, packageName);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 9d189db..8119585 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -18,6 +18,7 @@
package android.app.admin;
import android.content.ComponentName;
+import android.content.IntentFilter;
import android.os.RemoteCallback;
/**
@@ -109,4 +110,7 @@ interface IDevicePolicyManager {
boolean installCaCert(in byte[] certBuffer);
void uninstallCaCert(in byte[] certBuffer);
+
+ void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
+ void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 7b8b286..4b33799 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -172,7 +172,7 @@ public class AppWidgetProviderInfo implements Parcelable {
* <p>This field corresponds to the <code>android:previewImage</code> attribute in
* the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
*/
- public int previewImage;
+ public int previewImage;
/**
* The rules by which a widget can be resized. See {@link #RESIZE_NONE},
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 20002ad..c9fb530 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -237,6 +237,10 @@ interface IPackageManager {
int getPreferredActivities(out List<IntentFilter> outFilters,
out List<ComponentName> outActivities, String packageName);
+ void addPersistentPreferredActivity(in IntentFilter filter, in ComponentName activity, int userId);
+
+ void clearPackagePersistentPreferredActivities(String packageName, int userId);
+
/**
* Report the set of 'Home' activity candidates, plus (if any) which of them
* is the current "always use this one" setting.
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 785f2b4..ef0c4d5 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -209,6 +209,19 @@ public class PackageInfo implements Parcelable {
*/
public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;
/**
+ * Flag for {@link #requiredForProfile}
+ * The application will always be installed for a restricted profile.
+ * @hide
+ */
+ public static final int RESTRICTED_PROFILE = 1;
+ /**
+ * Flag for {@link #requiredForProfile}
+ * The application will always be installed for a managed profile.
+ * @hide
+ */
+ public static final int MANAGED_PROFILE = 2;
+
+ /**
* The install location requested by the activity. From the
* {@link android.R.attr#installLocation} attribute, one of
* {@link #INSTALL_LOCATION_AUTO},
@@ -218,6 +231,12 @@ public class PackageInfo implements Parcelable {
*/
public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
+ /**
+ * Defines which profiles this app is required for.
+ * @hide
+ */
+ public int requiredForProfile;
+
/** @hide */
public boolean requiredForAllUsers;
@@ -276,6 +295,7 @@ public class PackageInfo implements Parcelable {
dest.writeTypedArray(reqFeatures, parcelableFlags);
dest.writeInt(installLocation);
dest.writeInt(requiredForAllUsers ? 1 : 0);
+ dest.writeInt(requiredForProfile);
dest.writeString(restrictedAccountType);
dest.writeString(requiredAccountType);
dest.writeString(overlayTarget);
@@ -318,6 +338,7 @@ public class PackageInfo implements Parcelable {
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
installLocation = source.readInt();
requiredForAllUsers = source.readInt() != 0;
+ requiredForProfile = source.readInt();
restrictedAccountType = source.readString();
requiredAccountType = source.readString();
overlayTarget = source.readString();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7fa9417..c222003 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -304,6 +304,7 @@ public class PackageParser {
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
|| (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
pi.requiredForAllUsers = p.mRequiredForAllUsers;
+ pi.requiredForProfile = p.mRequiredForProfile;
}
pi.restrictedAccountType = p.mRestrictedAccountType;
pi.requiredAccountType = p.mRequiredAccountType;
@@ -1978,6 +1979,8 @@ public class PackageParser {
false)) {
owner.mRequiredForAllUsers = true;
}
+ owner.mRequiredForProfile = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestApplication_requiredForProfile, 0);
String restrictedAccountType = sa.getString(com.android.internal.R.styleable
.AndroidManifestApplication_restrictedAccountType);
@@ -3565,6 +3568,9 @@ public class PackageParser {
/* An app that's required for all users and cannot be uninstalled for a user */
public boolean mRequiredForAllUsers;
+ /* For which types of profile this app is required */
+ public int mRequiredForProfile;
+
/* The restricted account authenticator type that is used by this application */
public String mRestrictedAccountType;
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index aa4a243..6f1d4f8 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,6 +18,7 @@ package android.content.pm;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
import android.os.UserHandle;
/**
@@ -116,6 +117,14 @@ public class UserInfo implements Parcelable {
return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
}
+ /**
+ * @return true if this user can be switched to.
+ **/
+ public boolean supportsSwitchTo() {
+ // TODO remove fw.show_hidden_users when we have finished developing managed profiles.
+ return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
+ }
+
public UserInfo() {
}
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 431226a..2893522 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -17,12 +17,14 @@
package android.content.res;
import android.graphics.Color;
+
import com.android.internal.util.ArrayUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.AttributeSet;
+import android.util.MathUtils;
import android.util.SparseArray;
import android.util.StateSet;
import android.util.Xml;
@@ -172,7 +174,7 @@ public class ColorStateList implements Parcelable {
* Fill in this object based on the contents of an XML "selector" element.
*/
private void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
- throws XmlPullParserException, IOException {
+ throws XmlPullParserException, IOException {
int type;
@@ -195,6 +197,8 @@ public class ColorStateList implements Parcelable {
continue;
}
+ int alphaRes = 0;
+ float alpha = 1.0f;
int colorRes = 0;
int color = 0xffff0000;
boolean haveColor = false;
@@ -206,17 +210,20 @@ public class ColorStateList implements Parcelable {
for (i = 0; i < numAttrs; i++) {
final int stateResId = attrs.getAttributeNameResource(i);
if (stateResId == 0) break;
- if (stateResId == com.android.internal.R.attr.color) {
+ if (stateResId == com.android.internal.R.attr.alpha) {
+ alphaRes = attrs.getAttributeResourceValue(i, 0);
+ if (alphaRes == 0) {
+ alpha = attrs.getAttributeFloatValue(i, 1.0f);
+ }
+ } else if (stateResId == com.android.internal.R.attr.color) {
colorRes = attrs.getAttributeResourceValue(i, 0);
-
if (colorRes == 0) {
color = attrs.getAttributeIntValue(i, color);
haveColor = true;
}
} else {
stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
- ? stateResId
- : -stateResId;
+ ? stateResId : -stateResId;
}
}
stateSpec = StateSet.trimStateSet(stateSpec, j);
@@ -229,10 +236,18 @@ public class ColorStateList implements Parcelable {
+ ": <item> tag requires a 'android:color' attribute.");
}
+ if (alphaRes != 0) {
+ alpha = r.getFraction(alphaRes, 1, 1);
+ }
+
+ // Apply alpha modulation.
+ final int alphaMod = MathUtils.constrain((int) (Color.alpha(color) * alpha), 0, 255);
+ color = (color & 0xFFFFFF) | (alphaMod << 24);
+
if (listSize == 0 || stateSpec.length == 0) {
mDefaultColor = color;
}
-
+
if (listSize + 1 >= listAllocated) {
listAllocated = ArrayUtils.idealIntArraySize(listSize + 1);
@@ -300,6 +315,7 @@ public class ColorStateList implements Parcelable {
return mDefaultColor;
}
+ @Override
public String toString() {
return "ColorStateList{" +
"mStateSpecs=" + Arrays.deepToString(mStateSpecs) +
@@ -307,14 +323,16 @@ public class ColorStateList implements Parcelable {
"mDefaultColor=" + mDefaultColor + '}';
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
final int N = mStateSpecs.length;
dest.writeInt(N);
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
dest.writeIntArray(mStateSpecs[i]);
}
dest.writeIntArray(mColors);
@@ -322,17 +340,19 @@ public class ColorStateList implements Parcelable {
public static final Parcelable.Creator<ColorStateList> CREATOR =
new Parcelable.Creator<ColorStateList>() {
+ @Override
public ColorStateList[] newArray(int size) {
return new ColorStateList[size];
}
+ @Override
public ColorStateList createFromParcel(Parcel source) {
final int N = source.readInt();
- int[][] stateSpecs = new int[N][];
- for (int i=0; i<N; i++) {
+ final int[][] stateSpecs = new int[N][];
+ for (int i = 0; i < N; i++) {
stateSpecs[i] = source.createIntArray();
}
- int[] colors = source.createIntArray();
+ final int[] colors = source.createIntArray();
return new ColorStateList(stateSpecs, colors);
}
};
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 0369825..ef05732 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -361,7 +361,7 @@ public class GeomagneticField {
mP[0] = new float[] { 1.0f };
mPDeriv[0] = new float[] { 0.0f };
for (int n = 1; n <= maxN; n++) {
- mP[n] = new float[n + 1];
+ mP[n] = new float[n + 1];
mPDeriv[n] = new float[n + 1];
for (int m = 0; m <= n; m++) {
if (n == m) {
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index cbd6ec3..ff12d77 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -999,7 +999,7 @@ public abstract class CameraMetadata {
/**
* <p>Use specific scene mode. Enabling this disables
* control.aeMode, control.awbMode and control.afMode
- * controls; the HAL must ignore those settings while
+ * controls; the camera device will ignore those settings while
* USE_SCENE_MODE is active (except for FACE_PRIORITY
* scene mode). Other control entries are still active.
* This setting can only be used if availableSceneModes !=
@@ -1468,14 +1468,16 @@ public abstract class CameraMetadata {
/**
* <p>AE is off or recently reset. When a camera device is opened, it starts in
- * this state.</p>
+ * this state. This is a transient state, the camera device may skip reporting
+ * this state in capture result.</p>
* @see CaptureResult#CONTROL_AE_STATE
*/
public static final int CONTROL_AE_STATE_INACTIVE = 0;
/**
* <p>AE doesn't yet have a good set of control values
- * for the current scene.</p>
+ * for the current scene. This is a transient state, the camera device may skip
+ * reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AE_STATE
*/
public static final int CONTROL_AE_STATE_SEARCHING = 1;
@@ -1506,7 +1508,8 @@ public abstract class CameraMetadata {
* (through the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} START),
* and is currently executing it. Once PRECAPTURE
* completes, AE will transition to CONVERGED or
- * FLASH_REQUIRED as appropriate.</p>
+ * FLASH_REQUIRED as appropriate. This is a transient state, the
+ * camera device may skip reporting this state in capture result.</p>
*
* @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
* @see CaptureResult#CONTROL_AE_STATE
@@ -1520,7 +1523,8 @@ public abstract class CameraMetadata {
/**
* <p>AF off or has not yet tried to scan/been asked
* to scan. When a camera device is opened, it starts in
- * this state.</p>
+ * this state. This is a transient state, the camera device may
+ * skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_INACTIVE = 0;
@@ -1528,7 +1532,8 @@ public abstract class CameraMetadata {
/**
* <p>if CONTINUOUS_* modes are supported. AF is
* currently doing an AF scan initiated by a continuous
- * autofocus mode</p>
+ * autofocus mode. This is a transient state, the camera device may
+ * skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
@@ -1536,15 +1541,17 @@ public abstract class CameraMetadata {
/**
* <p>if CONTINUOUS_* modes are supported. AF currently
* believes it is in focus, but may restart scanning at
- * any time.</p>
+ * any time. This is a transient state, the camera device may skip
+ * reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2;
/**
* <p>if AUTO or MACRO modes are supported. AF is doing
- * an AF scan because it was triggered by AF
- * trigger</p>
+ * an AF scan because it was triggered by AF trigger. This is a
+ * transient state, the camera device may skip reporting
+ * this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3;
@@ -1552,7 +1559,7 @@ public abstract class CameraMetadata {
/**
* <p>if any AF mode besides OFF is supported. AF
* believes it is focused correctly and is
- * locked</p>
+ * locked.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
@@ -1560,7 +1567,7 @@ public abstract class CameraMetadata {
/**
* <p>if any AF mode besides OFF is supported. AF has
* failed to focus successfully and is
- * locked</p>
+ * locked.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
@@ -1568,7 +1575,8 @@ public abstract class CameraMetadata {
/**
* <p>if CONTINUOUS_* modes are supported. AF finished a
* passive scan without finding focus, and may restart
- * scanning at any time.</p>
+ * scanning at any time. This is a transient state, the camera
+ * device may skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AF_STATE
*/
public static final int CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6;
@@ -1579,14 +1587,16 @@ public abstract class CameraMetadata {
/**
* <p>AWB is not in auto mode. When a camera device is opened, it
- * starts in this state.</p>
+ * starts in this state. This is a transient state, the camera device may
+ * skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AWB_STATE
*/
public static final int CONTROL_AWB_STATE_INACTIVE = 0;
/**
* <p>AWB doesn't yet have a good set of control
- * values for the current scene.</p>
+ * values for the current scene. This is a transient state, the camera device
+ * may skip reporting this state in capture result.</p>
* @see CaptureResult#CONTROL_AWB_STATE
*/
public static final int CONTROL_AWB_STATE_SEARCHING = 1;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index dfde11b..c8668f5 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -390,7 +390,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>Gains applying to Bayer raw color channels for
- * white-balance</p>
+ * white-balance.</p>
* <p>The 4-channel white-balance gains are defined in
* the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
* for green pixels on even rows of the output, and <code>G_odd</code>
@@ -398,11 +398,11 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* does not support a separate gain for even/odd green channels,
* it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
* <code>G_even</code> in the output result metadata.</p>
- * <p>This array is either set by HAL when the request
+ * <p>This array is either set by the camera device when the request
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
* directly by the application in the request when the
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
- * <p>The output should be the gains actually applied by the HAL to
+ * <p>The output should be the gains actually applied by the camera device to
* the current frame.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -536,9 +536,9 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
* <p>If all regions have 0 weight, then no specific metering area
- * needs to be used by the HAL. If the metering region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * needs to be used by the camera device. If the metering region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -579,13 +579,15 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>Whether AF is currently enabled, and what
* mode it is set to</p>
- * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+ * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+ * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
* <p>If the lens is controlled by the camera device auto-focus algorithm,
* the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
* in result metadata.</p>
*
* @see CaptureResult#CONTROL_AF_STATE
* @see CaptureRequest#CONTROL_MODE
+ * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
* @see #CONTROL_AF_MODE_OFF
* @see #CONTROL_AF_MODE_AUTO
* @see #CONTROL_AF_MODE_MACRO
@@ -609,9 +611,9 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
* <p>If all regions have 0 weight, then no specific focus area
- * needs to be used by the HAL. If the focusing region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * needs to be used by the camera device. If the focusing region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -651,14 +653,14 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>Whether AWB is currently setting the color
* transform fields, and what its illumination target
- * is</p>
+ * is.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
* <p>When set to the ON mode, the camera device's auto white balance
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
* <p>When set to the OFF mode, the camera device's auto white balance
- * routine is disabled. The applicantion manually controls the white
+ * routine is disabled. The application manually controls the white
* balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
* and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
* <p>When set to any other modes, the camera device's auto white balance
@@ -695,10 +697,10 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific metering area
- * needs to be used by the HAL. If the metering region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+ * needs to be used by the camera device. If the AWB region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -753,7 +755,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>Overall mode of 3A control
- * routines</p>
+ * routines.</p>
* <p>High-level 3A control. When set to OFF, all 3A control
* by the camera device is disabled. The application must set the fields for
* capture parameters itself.</p>
@@ -830,9 +832,9 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>Operation mode for edge
- * enhancement</p>
+ * enhancement.</p>
* <p>Edge/sharpness/detail enhancement. OFF means no
- * enhancement will be applied by the HAL.</p>
+ * enhancement will be applied by the camera device.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
* will be applied. HIGH_QUALITY mode indicates that the
* camera device will use the highest-quality enhancement algorithms,
@@ -1044,7 +1046,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* <p>Mode of operation for the noise reduction
* algorithm</p>
* <p>Noise filtering control. OFF means no noise reduction
- * will be applied by the HAL.</p>
+ * will be applied by the camera device.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
@@ -1285,8 +1287,8 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
new Key<Integer>("android.statistics.faceDetectMode", int.class);
/**
- * <p>Whether the HAL needs to output the lens
- * shading map in output result metadata</p>
+ * <p>Whether the camera device will output the lens
+ * shading map in output result metadata.</p>
* <p>When set to ON,
* {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
* the output result metadata.</p>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index bd9ba2f..0749edd 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -143,7 +143,7 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>Gains applying to Bayer raw color channels for
- * white-balance</p>
+ * white-balance.</p>
* <p>The 4-channel white-balance gains are defined in
* the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
* for green pixels on even rows of the output, and <code>G_odd</code>
@@ -151,11 +151,11 @@ public final class CaptureResult extends CameraMetadata {
* does not support a separate gain for even/odd green channels,
* it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
* <code>G_even</code> in the output result metadata.</p>
- * <p>This array is either set by HAL when the request
+ * <p>This array is either set by the camera device when the request
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is not TRANSFORM_MATRIX, or
* directly by the application in the request when the
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
- * <p>The output should be the gains actually applied by the HAL to
+ * <p>The output should be the gains actually applied by the camera device to
* the current frame.</p>
*
* @see CaptureRequest#COLOR_CORRECTION_MODE
@@ -225,9 +225,9 @@ public final class CaptureResult extends CameraMetadata {
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
* <p>If all regions have 0 weight, then no specific metering area
- * needs to be used by the HAL. If the metering region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * needs to be used by the camera device. If the metering region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -370,6 +370,54 @@ public final class CaptureResult extends CameraMetadata {
* </tr>
* </tbody>
* </table>
+ * <p>For the above table, the camera device may skip reporting any state changes that happen
+ * without application intervention (i.e. mode switch, trigger, locking). Any state that
+ * can be skipped in that manner is called a transient state.</p>
+ * <p>For example, for above AE modes (AE_MODE_ON_*), in addition to the state transitions
+ * listed in above table, it is also legal for the camera device to skip one or more
+ * transient states between two results. See below table for examples:</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">State</th>
+ * <th align="center">Transition Cause</th>
+ * <th align="center">New State</th>
+ * <th align="center">Notes</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">INACTIVE</td>
+ * <td align="center">Camera device finished AE scan</td>
+ * <td align="center">CONVERGED</td>
+ * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Any state</td>
+ * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+ * <td align="center">FLASH_REQUIRED</td>
+ * <td align="center">Converged but too dark w/o flash after a precapture sequence, transient states are skipped by camera device.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">Any state</td>
+ * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+ * <td align="center">CONVERGED</td>
+ * <td align="center">Converged after a precapture sequence, transient states are skipped by camera device.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">CONVERGED</td>
+ * <td align="center">Camera device finished AE scan</td>
+ * <td align="center">FLASH_REQUIRED</td>
+ * <td align="center">Converged but too dark w/o flash after a new scan, transient states are skipped by camera device.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">FLASH_REQUIRED</td>
+ * <td align="center">Camera device finished AE scan</td>
+ * <td align="center">CONVERGED</td>
+ * <td align="center">Converged after a new scan, transient states are skipped by camera device.</td>
+ * </tr>
+ * </tbody>
+ * </table>
*
* @see CaptureRequest#CONTROL_AE_LOCK
* @see CaptureRequest#CONTROL_AE_MODE
@@ -389,13 +437,15 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>Whether AF is currently enabled, and what
* mode it is set to</p>
- * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
+ * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+ * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
* <p>If the lens is controlled by the camera device auto-focus algorithm,
* the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
* in result metadata.</p>
*
* @see CaptureResult#CONTROL_AF_STATE
* @see CaptureRequest#CONTROL_MODE
+ * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
* @see #CONTROL_AF_MODE_OFF
* @see #CONTROL_AF_MODE_AUTO
* @see #CONTROL_AF_MODE_MACRO
@@ -419,9 +469,9 @@ public final class CaptureResult extends CameraMetadata {
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
* <p>If all regions have 0 weight, then no specific focus area
- * needs to be used by the HAL. If the focusing region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * needs to be used by the camera device. If the focusing region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -431,7 +481,7 @@ public final class CaptureResult extends CameraMetadata {
new Key<int[]>("android.control.afRegions", int[].class);
/**
- * <p>Current state of AF algorithm</p>
+ * <p>Current state of AF algorithm.</p>
* <p>Switching between or enabling AF modes ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) always
* resets the AF state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
* or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
@@ -529,6 +579,48 @@ public final class CaptureResult extends CameraMetadata {
* </tr>
* </tbody>
* </table>
+ * <p>For the above table, the camera device may skip reporting any state changes that happen
+ * without application intervention (i.e. mode switch, trigger, locking). Any state that
+ * can be skipped in that manner is called a transient state.</p>
+ * <p>For example, for these AF modes (AF_MODE_AUTO and AF_MODE_MACRO), in addition to the
+ * state transitions listed in above table, it is also legal for the camera device to skip
+ * one or more transient states between two results. See below table for examples:</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">State</th>
+ * <th align="center">Transition Cause</th>
+ * <th align="center">New State</th>
+ * <th align="center">Notes</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">INACTIVE</td>
+ * <td align="center">AF_TRIGGER</td>
+ * <td align="center">FOCUSED_LOCKED</td>
+ * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">INACTIVE</td>
+ * <td align="center">AF_TRIGGER</td>
+ * <td align="center">NOT_FOCUSED_LOCKED</td>
+ * <td align="center">Focus failed after a scan, lens is now locked.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">FOCUSED_LOCKED</td>
+ * <td align="center">AF_TRIGGER</td>
+ * <td align="center">FOCUSED_LOCKED</td>
+ * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+ * </tr>
+ * <tr>
+ * <td align="center">NOT_FOCUSED_LOCKED</td>
+ * <td align="center">AF_TRIGGER</td>
+ * <td align="center">FOCUSED_LOCKED</td>
+ * <td align="center">Focus is good after a scan, lens is not locked.</td>
+ * </tr>
+ * </tbody>
+ * </table>
* <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_CONTINUOUS_VIDEO:</p>
* <table>
* <thead>
@@ -735,6 +827,41 @@ public final class CaptureResult extends CameraMetadata {
* </tr>
* </tbody>
* </table>
+ * <p>When switch between AF_MODE_CONTINUOUS_* (CAF modes) and AF_MODE_AUTO/AF_MODE_MACRO
+ * (AUTO modes), the initial INACTIVE or PASSIVE_SCAN states may be skipped by the
+ * camera device. When a trigger is included in a mode switch request, the trigger
+ * will be evaluated in the context of the new mode in the request.
+ * See below table for examples:</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">State</th>
+ * <th align="center">Transition Cause</th>
+ * <th align="center">New State</th>
+ * <th align="center">Notes</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">any state</td>
+ * <td align="center">CAF--&gt;AUTO mode switch</td>
+ * <td align="center">INACTIVE</td>
+ * <td align="center">Mode switch without trigger, initial state must be INACTIVE</td>
+ * </tr>
+ * <tr>
+ * <td align="center">any state</td>
+ * <td align="center">CAF--&gt;AUTO mode switch with AF_TRIGGER</td>
+ * <td align="center">trigger-reachable states from INACTIVE</td>
+ * <td align="center">Mode switch with trigger, INACTIVE is skipped</td>
+ * </tr>
+ * <tr>
+ * <td align="center">any state</td>
+ * <td align="center">AUTO--&gt;CAF mode switch</td>
+ * <td align="center">passively reachable states from INACTIVE</td>
+ * <td align="center">Mode switch without trigger, passive transient state is skipped</td>
+ * </tr>
+ * </tbody>
+ * </table>
*
* @see CaptureRequest#CONTROL_AF_MODE
* @see CaptureRequest#CONTROL_MODE
@@ -764,14 +891,14 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>Whether AWB is currently setting the color
* transform fields, and what its illumination target
- * is</p>
+ * is.</p>
* <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
* <p>When set to the ON mode, the camera device's auto white balance
* routine is enabled, overriding the application's selected
* {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
* {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
* <p>When set to the OFF mode, the camera device's auto white balance
- * routine is disabled. The applicantion manually controls the white
+ * routine is disabled. The application manually controls the white
* balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
* and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
* <p>When set to any other modes, the camera device's auto white balance
@@ -808,10 +935,10 @@ public final class CaptureResult extends CameraMetadata {
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.height - 1) being the
* bottom-right pixel in the active pixel array. The weight
* should be nonnegative.</p>
- * <p>If all regions have 0 weight, then no specific metering area
- * needs to be used by the HAL. If the metering region is
- * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the HAL
- * should ignore the sections outside the region and output the
+ * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+ * needs to be used by the camera device. If the AWB region is
+ * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+ * will ignore the sections outside the region and output the
* used sections in the frame metadata.</p>
*
* @see CaptureRequest#SCALER_CROP_REGION
@@ -905,11 +1032,35 @@ public final class CaptureResult extends CameraMetadata {
* <td align="center">SEARCHING</td>
* <td align="center">Values not good after unlock</td>
* </tr>
+ * </tbody>
+ * </table>
+ * <p>For the above table, the camera device may skip reporting any state changes that happen
+ * without application intervention (i.e. mode switch, trigger, locking). Any state that
+ * can be skipped in that manner is called a transient state.</p>
+ * <p>For example, for this AWB mode (AWB_MODE_AUTO), in addition to the state transitions
+ * listed in above table, it is also legal for the camera device to skip one or more
+ * transient states between two results. See below table for examples:</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">State</th>
+ * <th align="center">Transition Cause</th>
+ * <th align="center">New State</th>
+ * <th align="center">Notes</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">INACTIVE</td>
+ * <td align="center">Camera device finished AWB scan</td>
+ * <td align="center">CONVERGED</td>
+ * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+ * </tr>
* <tr>
* <td align="center">LOCKED</td>
* <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is OFF</td>
* <td align="center">CONVERGED</td>
- * <td align="center">Values good after unlock</td>
+ * <td align="center">Values good after unlock, transient states are skipped by camera device.</td>
* </tr>
* </tbody>
* </table>
@@ -928,7 +1079,7 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>Overall mode of 3A control
- * routines</p>
+ * routines.</p>
* <p>High-level 3A control. When set to OFF, all 3A control
* by the camera device is disabled. The application must set the fields for
* capture parameters itself.</p>
@@ -956,9 +1107,9 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>Operation mode for edge
- * enhancement</p>
+ * enhancement.</p>
* <p>Edge/sharpness/detail enhancement. OFF means no
- * enhancement will be applied by the HAL.</p>
+ * enhancement will be applied by the camera device.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
* will be applied. HIGH_QUALITY mode indicates that the
* camera device will use the highest-quality enhancement algorithms,
@@ -1236,7 +1387,7 @@ public final class CaptureResult extends CameraMetadata {
* <p>Mode of operation for the noise reduction
* algorithm</p>
* <p>Noise filtering control. OFF means no noise reduction
- * will be applied by the HAL.</p>
+ * will be applied by the camera device.</p>
* <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
@@ -1262,7 +1413,7 @@ public final class CaptureResult extends CameraMetadata {
* before the FINAL buffer for frame 4. PARTIAL buffers may be returned
* in any order relative to other frames, but all PARTIAL buffers for a given
* capture must arrive before the FINAL buffer for that capture. This entry may
- * only be used by the HAL if quirks.usePartialResult is set to 1.</p>
+ * only be used by the camera device if quirks.usePartialResult is set to 1.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
@@ -1755,7 +1906,7 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>The best-fit color channel gains calculated
- * by the HAL's statistics units for the current output frame</p>
+ * by the camera device's statistics units for the current output frame.</p>
* <p>This may be different than the gains used for this frame,
* since statistics processing on data from a new frame
* typically completes after the transform has already been
@@ -1774,11 +1925,11 @@ public final class CaptureResult extends CameraMetadata {
/**
* <p>The best-fit color transform matrix estimate
- * calculated by the HAL's statistics units for the current
- * output frame</p>
- * <p>The HAL must provide the estimate from its
+ * calculated by the camera device's statistics units for the current
+ * output frame.</p>
+ * <p>The camera device will provide the estimate from its
* statistics unit on the white balance transforms to use
- * for the next frame. These are the values the HAL believes
+ * for the next frame. These are the values the camera device believes
* are the best fit for the current output frame. This may
* be different than the transform used for this frame, since
* statistics processing on data from a new frame typically
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a35cb9..e6b9d4c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -400,6 +400,8 @@ public class ConnectivityManager {
private final IConnectivityManager mService;
+ private final String mPackageName;
+
/**
* Tests if a given integer represents a valid network type.
* @param networkType the type to be tested
@@ -811,7 +813,7 @@ public class ConnectivityManager {
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
byte[] address = hostAddress.getAddress();
try {
- return mService.requestRouteToHostAddress(networkType, address);
+ return mService.requestRouteToHostAddress(networkType, address, mPackageName);
} catch (RemoteException e) {
return false;
}
@@ -907,8 +909,9 @@ public class ConnectivityManager {
/**
* {@hide}
*/
- public ConnectivityManager(IConnectivityManager service) {
+ public ConnectivityManager(IConnectivityManager service, String packageName) {
mService = checkNotNull(service, "missing IConnectivityManager");
+ mPackageName = checkNotNull(packageName, "missing package name");
}
/** {@hide} */
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b3217eb..381a817 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -71,9 +71,9 @@ interface IConnectivityManager
int stopUsingNetworkFeature(int networkType, in String feature);
- boolean requestRouteToHost(int networkType, int hostAddress);
+ boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
- boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
+ boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
boolean getMobileDataEnabled();
void setMobileDataEnabled(boolean enabled);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index a7aae2a..25514f4 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -44,6 +44,8 @@ public class NetworkStats implements Parcelable {
public static final String IFACE_ALL = null;
/** {@link #uid} value when UID details unavailable. */
public static final int UID_ALL = -1;
+ /** {@link #tag} value matching any tag. */
+ public static final int TAG_ALL = -1;
/** {@link #set} value when all sets combined. */
public static final int SET_ALL = -1;
/** {@link #set} value where background data is accounted. */
@@ -59,8 +61,9 @@ public class NetworkStats implements Parcelable {
* {@link SystemClock#elapsedRealtime()} timestamp when this data was
* generated.
*/
- private final long elapsedRealtime;
+ private long elapsedRealtime;
private int size;
+ private int capacity;
private String[] iface;
private int[] uid;
private int[] set;
@@ -152,20 +155,27 @@ public class NetworkStats implements Parcelable {
public NetworkStats(long elapsedRealtime, int initialSize) {
this.elapsedRealtime = elapsedRealtime;
this.size = 0;
- this.iface = new String[initialSize];
- this.uid = new int[initialSize];
- this.set = new int[initialSize];
- this.tag = new int[initialSize];
- this.rxBytes = new long[initialSize];
- this.rxPackets = new long[initialSize];
- this.txBytes = new long[initialSize];
- this.txPackets = new long[initialSize];
- this.operations = new long[initialSize];
+ if (initialSize >= 0) {
+ this.capacity = initialSize;
+ this.iface = new String[initialSize];
+ this.uid = new int[initialSize];
+ this.set = new int[initialSize];
+ this.tag = new int[initialSize];
+ this.rxBytes = new long[initialSize];
+ this.rxPackets = new long[initialSize];
+ this.txBytes = new long[initialSize];
+ this.txPackets = new long[initialSize];
+ this.operations = new long[initialSize];
+ } else {
+ // Special case for use by NetworkStatsFactory to start out *really* empty.
+ this.capacity = 0;
+ }
}
public NetworkStats(Parcel parcel) {
elapsedRealtime = parcel.readLong();
size = parcel.readInt();
+ capacity = parcel.readInt();
iface = parcel.createStringArray();
uid = parcel.createIntArray();
set = parcel.createIntArray();
@@ -181,6 +191,7 @@ public class NetworkStats implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(elapsedRealtime);
dest.writeInt(size);
+ dest.writeInt(capacity);
dest.writeStringArray(iface);
dest.writeIntArray(uid);
dest.writeIntArray(set);
@@ -222,8 +233,8 @@ public class NetworkStats implements Parcelable {
* object can be recycled across multiple calls.
*/
public NetworkStats addValues(Entry entry) {
- if (size >= this.iface.length) {
- final int newLength = Math.max(iface.length, 10) * 3 / 2;
+ if (size >= capacity) {
+ final int newLength = Math.max(size, 10) * 3 / 2;
iface = Arrays.copyOf(iface, newLength);
uid = Arrays.copyOf(uid, newLength);
set = Arrays.copyOf(set, newLength);
@@ -233,6 +244,7 @@ public class NetworkStats implements Parcelable {
txBytes = Arrays.copyOf(txBytes, newLength);
txPackets = Arrays.copyOf(txPackets, newLength);
operations = Arrays.copyOf(operations, newLength);
+ capacity = newLength;
}
iface[size] = entry.iface;
@@ -270,6 +282,10 @@ public class NetworkStats implements Parcelable {
return elapsedRealtime;
}
+ public void setElapsedRealtime(long time) {
+ elapsedRealtime = time;
+ }
+
/**
* Return age of this {@link NetworkStats} object with respect to
* {@link SystemClock#elapsedRealtime()}.
@@ -284,7 +300,7 @@ public class NetworkStats implements Parcelable {
@VisibleForTesting
public int internalSize() {
- return iface.length;
+ return capacity;
}
@Deprecated
@@ -507,8 +523,25 @@ public class NetworkStats implements Parcelable {
* If counters have rolled backwards, they are clamped to {@code 0} and
* reported to the given {@link NonMonotonicObserver}.
*/
- public static <C> NetworkStats subtract(
- NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) {
+ public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+ NonMonotonicObserver<C> observer, C cookie) {
+ return subtract(left, right, observer, cookie, null);
+ }
+
+ /**
+ * Subtract the two given {@link NetworkStats} objects, returning the delta
+ * between two snapshots in time. Assumes that statistics rows collect over
+ * time, and that none of them have disappeared.
+ * <p>
+ * If counters have rolled backwards, they are clamped to {@code 0} and
+ * reported to the given {@link NonMonotonicObserver}.
+ * <p>
+ * If <var>recycle</var> is supplied, this NetworkStats object will be
+ * reused (and returned) as the result if it is large enough to contain
+ * the data.
+ */
+ public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+ NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) {
long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
if (deltaRealtime < 0) {
if (observer != null) {
@@ -519,7 +552,14 @@ public class NetworkStats implements Parcelable {
// result will have our rows, and elapsed time between snapshots
final Entry entry = new Entry();
- final NetworkStats result = new NetworkStats(deltaRealtime, left.size);
+ final NetworkStats result;
+ if (recycle != null && recycle.capacity >= left.size) {
+ result = recycle;
+ result.size = 0;
+ result.elapsedRealtime = deltaRealtime;
+ } else {
+ result = new NetworkStats(deltaRealtime, left.size);
+ }
for (int i = 0; i < left.size; i++) {
entry.iface = left.iface[i];
entry.uid = left.uid[i];
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index a7d287b..461e8b8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -16,13 +16,24 @@
package android.net;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -31,27 +42,70 @@ import java.util.concurrent.atomic.AtomicInteger;
* {@hide}
*/
public class ProxyDataTracker extends BaseNetworkStateTracker {
- private static final String NETWORK_TYPE = "PROXY";
private static final String TAG = "ProxyDataTracker";
+ private static final String NETWORK_TYPE = "PROXY";
// TODO: investigate how to get these DNS addresses from the system.
private static final String DNS1 = "8.8.8.8";
private static final String DNS2 = "8.8.4.4";
private static final String REASON_ENABLED = "enabled";
+ private static final String REASON_DISABLED = "disabled";
+ private static final String REASON_PROXY_DOWN = "proxy_down";
+
+ private static final int MSG_TEAR_DOWN_REQUEST = 1;
+ private static final int MSG_SETUP_REQUEST = 2;
+ private static final String PERMISSION_PROXY_STATUS_SENDER =
+ "android.permission.ACCESS_NETWORK_CONDITIONS";
+ private static final String ACTION_PROXY_STATUS_CHANGE =
+ "com.android.net.PROXY_STATUS_CHANGE";
+ private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
+ private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
+ private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
+ "reply_to_messenger_binder_bundle";
+
+ private Handler mTarget;
+ private Messenger mProxyStatusService;
+ private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
+ private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
- private final AtomicInteger mReconnectGeneration = new AtomicInteger(0);
+
+ private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
+ mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
+ if (mIsProxyAvailable.get()) {
+ Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
+ if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
+ Log.e(TAG, "no messenger binder in the intent to send future requests");
+ mIsProxyAvailable.set(false);
+ return;
+ }
+ mProxyStatusService =
+ new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
+ // If there is a pending reconnect request, do it now.
+ if (mReconnectRequested.get()) {
+ reconnect();
+ }
+ } else {
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+ REASON_PROXY_DOWN, null);
+ }
+ } else {
+ Log.d(TAG, "Unrecognized broadcast intent");
+ }
+ }
+ };
/**
* Create a new ProxyDataTracker
*/
public ProxyDataTracker() {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
- // TODO: update available state according to proxy state.
- mNetworkInfo.setIsAvailable(true);
mLinkProperties = new LinkProperties();
mLinkCapabilities = new LinkCapabilities();
-
+ mNetworkInfo.setIsAvailable(true);
try {
mLinkProperties.addDns(InetAddress.getByName(DNS1));
mLinkProperties.addDns(InetAddress.getByName(DNS2));
@@ -64,11 +118,31 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
throw new CloneNotSupportedException();
}
+ @Override
+ public void startMonitoring(Context context, Handler target) {
+ mContext = context;
+ mTarget = target;
+ mContext.registerReceiver(mProxyStatusServiceListener,
+ new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
+ PERMISSION_PROXY_STATUS_SENDER,
+ null);
+ }
+
/**
* Disable connectivity to the network.
*/
public boolean teardown() {
- // TODO: tell relevant service to tear down proxy.
+ setTeardownRequested(true);
+ mReconnectRequested.set(false);
+ try {
+ if (mIsProxyAvailable.get() && mProxyStatusService != null) {
+ mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to connect to proxy status service", e);
+ return false;
+ }
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
return true;
}
@@ -76,16 +150,24 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
* Re-enable proxy data connectivity after a {@link #teardown()}.
*/
public boolean reconnect() {
- if (!isAvailable()) {
- Log.w(TAG, "Reconnect requested even though network is disabled. Bailing.");
+ mReconnectRequested.set(true);
+ setTeardownRequested(false);
+ if (!mIsProxyAvailable.get()) {
+ Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
return false;
}
- setTeardownRequested(false);
- mReconnectGeneration.incrementAndGet();
- // TODO: tell relevant service to setup proxy. Set state to connected only if setup
- // succeeds.
- setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
+ setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
+ try {
+ mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to connect to proxy status service", e);
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
+ return false;
+ }
+ // We'll assume proxy is set up successfully. If not, a status change broadcast will be
+ // received afterwards to indicate any failure.
+ setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
return true;
}
@@ -116,7 +198,7 @@ public class ProxyDataTracker extends BaseNetworkStateTracker {
private void setDetailedState(NetworkInfo.DetailedState state, String reason,
String extraInfo) {
mNetworkInfo.setDetailedState(state, reason, extraInfo);
- Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+ Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
}
}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 10988c6..635a50f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -48,6 +48,7 @@ interface INfcAdapter
void setForegroundDispatch(in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void setAppCallback(in IAppCallback callback);
+ void invokeBeam();
void dispatch(in Tag tag);
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index de481cf..83d17ba 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -474,6 +475,45 @@ public final class NdefRecord implements Parcelable {
}
/**
+ * Create a new NDEF record containing UTF-8 text data.<p>
+ *
+ * The caller can either specify the language code for the provided text,
+ * or otherwise the language code corresponding to the current default
+ * locale will be used.
+ *
+ * Reference specification: NFCForum-TS-RTD_Text_1.0
+ * @param languageCode The languageCode for the record. If locale is empty or null,
+ * the language code of the current default locale will be used.
+ * @param text The text to be encoded in the record. Will be represented in UTF-8 format.
+ * @throws IllegalArgumentException if text is null
+ */
+ public static NdefRecord createTextRecord(String languageCode, String text) {
+ if (text == null) throw new NullPointerException("text is null");
+
+ byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
+
+ byte[] languageCodeBytes = null;
+ if (languageCode != null && !languageCode.isEmpty()) {
+ languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
+ } else {
+ languageCodeBytes = Locale.getDefault().getLanguage().
+ getBytes(StandardCharsets.US_ASCII);
+ }
+ // We only have 6 bits to indicate ISO/IANA language code.
+ if (languageCodeBytes.length >= 64) {
+ throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
+ }
+ ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
+
+ byte status = (byte) (languageCodeBytes.length & 0xFF);
+ buffer.put(status);
+ buffer.put(languageCodeBytes);
+ buffer.put(textBytes);
+
+ return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
+ }
+
+ /**
* Construct an NDEF Record from its component fields.<p>
* Recommend to use helpers such as {#createUri} or
* {{@link #createExternal} where possible, since they perform
@@ -775,7 +815,7 @@ public final class NdefRecord implements Parcelable {
throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
} else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
throw new FormatException("" +
- "unexpected TNF_UNCHANGED in first chunk or unchunked record");
+ "unexpected TNF_UNCHANGED in first chunk or unchunked record");
}
int typeLength = buffer.get() & 0xFF;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 77c0234..8643f2e 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@ package android.nfc;
import android.app.Activity;
import android.app.Application;
+import android.content.Intent;
import android.net.Uri;
import android.nfc.NfcAdapter.ReaderCallback;
import android.os.Binder;
@@ -327,6 +328,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
NfcAdapter.CreateNdefMessageCallback ndefCallback;
NfcAdapter.CreateBeamUrisCallback urisCallback;
NdefMessage message;
+ Activity activity;
Uri[] uris;
int flags;
synchronized (NfcActivityManager.this) {
@@ -338,6 +340,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
message = state.ndefMessage;
uris = state.uris;
flags = state.flags;
+ activity = state.activity;
}
// Make callbacks without lock
@@ -362,7 +365,13 @@ public final class NfcActivityManager extends IAppCallback.Stub
}
}
}
-
+ if (uris != null && uris.length > 0) {
+ for (Uri uri : uris) {
+ // Grant the NFC process permission to read these URIs
+ activity.grantUriPermission("com.android.nfc", uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ }
return new BeamShareData(message, uris, flags);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index e8b7437..96a3947 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -1249,6 +1249,45 @@ public final class NfcAdapter {
}
/**
+ * Manually invoke Android Beam to share data.
+ *
+ * <p>The Android Beam animation is normally only shown when two NFC-capable
+ * devices come into range.
+ * By calling this method, an Activity can invoke the Beam animation directly
+ * even if no other NFC device is in range yet. The Beam animation will then
+ * prompt the user to tap another NFC-capable device to complete the data
+ * transfer.
+ *
+ * <p>The main advantage of using this method is that it avoids the need for the
+ * user to tap the screen to complete the transfer, as this method already
+ * establishes the direction of the transfer and the consent of the user to
+ * share data. Callers are responsible for making sure that the user has
+ * consented to sharing data on NFC tap.
+ *
+ * <p>Note that to use this method, the passed in Activity must have already
+ * set data to share over Beam by using method calls such as
+ * {@link #setNdefPushMessageCallback} or
+ * {@link #setBeamPushUrisCallback}.
+ *
+ * @param activity the current foreground Activity that has registered data to share
+ * @return whether the Beam animation was successfully invoked
+ */
+ public boolean invokeBeam(Activity activity) {
+ if (activity == null) {
+ throw new NullPointerException("activity may not be null.");
+ }
+ enforceResumed(activity);
+ try {
+ sService.invokeBeam();
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "invokeBeam: NFC process has died.");
+ attemptDeadServiceRecovery(e);
+ return false;
+ }
+ }
+
+ /**
* Enable NDEF message push over NFC while this Activity is in the foreground.
*
* <p>You must explicitly call this method every time the activity is
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 2d67264..8f5cf8b 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -15,9 +15,6 @@
package android.os;
-import android.os.Parcel;
-import android.os.Parcelable;
-
/**
* {@hide}
*/
@@ -33,6 +30,22 @@ public class BatteryProperties implements Parcelable {
public int batteryTemperature;
public String batteryTechnology;
+ public BatteryProperties() {
+ }
+
+ public void set(BatteryProperties other) {
+ chargerAcOnline = other.chargerAcOnline;
+ chargerUsbOnline = other.chargerUsbOnline;
+ chargerWirelessOnline = other.chargerWirelessOnline;
+ batteryStatus = other.batteryStatus;
+ batteryHealth = other.batteryHealth;
+ batteryPresent = other.batteryPresent;
+ batteryLevel = other.batteryLevel;
+ batteryVoltage = other.batteryVoltage;
+ batteryTemperature = other.batteryTemperature;
+ batteryTechnology = other.batteryTechnology;
+ }
+
/*
* Parcel read/write code must be kept in sync with
* frameworks/native/services/batteryservice/BatteryProperties.cpp
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index dfba208..e91f7d7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -588,8 +588,10 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_FOREGROUND = 0x0002;
// Event is about an application package that is at the top of the screen.
public static final int EVENT_TOP = 0x0003;
+ // Event is about an application package that is at the top of the screen.
+ public static final int EVENT_SYNC = 0x0004;
// Number of event types.
- public static final int EVENT_COUNT = 0x0004;
+ public static final int EVENT_COUNT = 0x0005;
public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
@@ -597,6 +599,8 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
+ public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
+ public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
// For CMD_EVENT.
public int eventCode;
@@ -975,11 +979,11 @@ public abstract class BatteryStats implements Parcelable {
};
public static final String[] HISTORY_EVENT_NAMES = new String[] {
- "null", "proc", "fg", "top"
+ "null", "proc", "fg", "top", "sync"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
- "Nl", "Pr", "Fg", "Tp"
+ "Enl", "Epr", "Efg", "Etp", "Esy"
};
/**
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
index 96dc61a..70dcdd8 100644
--- a/core/java/android/os/Broadcaster.java
+++ b/core/java/android/os/Broadcaster.java
@@ -171,10 +171,10 @@ public class Broadcaster
public void broadcast(Message msg)
{
synchronized (this) {
- if (mReg == null) {
- return;
- }
-
+ if (mReg == null) {
+ return;
+ }
+
int senderWhat = msg.what;
Registration start = mReg;
Registration r = start;
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 56176a4..069285a 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,8 +25,10 @@ interface IPowerManager
{
// WARNING: The first four methods must remain the first three methods because their
// transaction numbers must not change unless IPowerManager.cpp is also updated.
- void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
- void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame);
+ void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
+ String historyTag);
+ void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
+ int uidtoblame);
void releaseWakeLock(IBinder lock, int flags);
void updateWakeLockUids(IBinder lock, in int[] uids);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 4d4c337..74ca3bb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -662,6 +662,7 @@ public final class PowerManager {
private boolean mRefCounted = true;
private boolean mHeld;
private WorkSource mWorkSource;
+ private String mHistoryTag;
private final Runnable mReleaser = new Runnable() {
public void run() {
@@ -748,7 +749,8 @@ public final class PowerManager {
// been explicitly released by the keyguard.
mHandler.removeCallbacks(mReleaser);
try {
- mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
+ mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
+ mHistoryTag);
} catch (RemoteException e) {
}
mHeld = true;
@@ -855,6 +857,11 @@ public final class PowerManager {
}
/** @hide */
+ public void setHistoryTag(String tag) {
+ mHistoryTag = tag;
+ }
+
+ /** @hide */
public void setUnimportantForLogging(boolean state) {
if (state) mFlags |= UNIMPORTANT_FOR_LOGGING;
else mFlags &= ~UNIMPORTANT_FOR_LOGGING;
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 729c64b..672df6d 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -16,6 +16,9 @@
package android.os;
+import android.app.IAlarmManager;
+import android.content.Context;
+import android.util.Slog;
/**
* Core timekeeping facilities.
@@ -89,6 +92,8 @@ package android.os;
* </ul>
*/
public final class SystemClock {
+ private static final String TAG = "SystemClock";
+
/**
* This class is uninstantiable.
*/
@@ -134,7 +139,23 @@ public final class SystemClock {
*
* @return if the clock was successfully set to the specified time.
*/
- native public static boolean setCurrentTimeMillis(long millis);
+ public static boolean setCurrentTimeMillis(long millis) {
+ IBinder b = ServiceManager.getService(Context.ALARM_SERVICE);
+ IAlarmManager mgr = IAlarmManager.Stub.asInterface(b);
+ if (mgr == null) {
+ return false;
+ }
+
+ try {
+ return mgr.setTime(millis);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to set RTC", e);
+ } catch (SecurityException e) {
+ Slog.e(TAG, "Unable to set RTC", e);
+ }
+
+ return false;
+ }
/**
* Returns milliseconds since boot, not counting time spent in deep sleep.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8f6dda1..1ec5cd5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -164,11 +164,13 @@ public class UserManager {
/**
* Returns whether the system supports multiple users.
- * @return true if multiple users can be created, false if it is a single user device.
+ * @return true if multiple users can be created by user, false if it is a single user device.
* @hide
*/
public static boolean supportsMultipleUsers() {
- return getMaxSupportedUsers() > 1;
+ return getMaxSupportedUsers() > 1
+ && SystemProperties.getBoolean("fw.show_multiuserui",
+ Resources.getSystem().getBoolean(R.bool.config_enableMultiUserUI));
}
/**
@@ -601,6 +603,26 @@ public class UserManager {
}
/**
+ * Returns true if the user switcher should be shown, this will be if there
+ * are multiple users that aren't managed profiles.
+ * @hide
+ * @return true if user switcher should be shown.
+ */
+ public boolean isUserSwitcherEnabled() {
+ List<UserInfo> users = getUsers(true);
+ if (users == null) {
+ return false;
+ }
+ int switchableUserCount = 0;
+ for (UserInfo user : users) {
+ if (user.supportsSwitchTo()) {
+ ++switchableUserCount;
+ }
+ }
+ return switchableUserCount > 1;
+ }
+
+ /**
* Returns a serial number on this device for a given userHandle. User handles can be recycled
* when deleting and creating users, but serial numbers are not reused until the device is wiped.
* @param userHandle
diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java
index 3003290..7de7d1c 100644
--- a/core/java/android/preference/GenericInflater.java
+++ b/core/java/android/preference/GenericInflater.java
@@ -191,7 +191,7 @@ abstract class GenericInflater<T, P extends GenericInflater.Parent> {
public void setFactory(Factory<T> factory) {
if (mFactorySet) {
throw new IllegalStateException("" +
- "A factory has already been set on this inflater");
+ "A factory has already been set on this inflater");
}
if (factory == null) {
throw new NullPointerException("Given factory can not be null");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 76ada09..18018e2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5254,6 +5254,12 @@ public final class Settings {
public static final String SMS_SHORT_CODE_RULE = "sms_short_code_rule";
/**
+ * Used to select TCP's default initial receiver window size in segments - defaults to a build config value
+ * @hide
+ */
+ public static final String TCP_DEFAULT_INIT_RWND = "tcp_default_init_rwnd";
+
+ /**
* Used to disable Tethering on a device - defaults to true
* @hide
*/
diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java
index 580a369..cda8015 100644
--- a/core/java/android/text/style/BackgroundColorSpan.java
+++ b/core/java/android/text/style/BackgroundColorSpan.java
@@ -26,9 +26,9 @@ public class BackgroundColorSpan extends CharacterStyle
private final int mColor;
- public BackgroundColorSpan(int color) {
- mColor = color;
- }
+ public BackgroundColorSpan(int color) {
+ mColor = color;
+ }
public BackgroundColorSpan(Parcel src) {
mColor = src.readInt();
@@ -46,12 +46,12 @@ public class BackgroundColorSpan extends CharacterStyle
dest.writeInt(mColor);
}
- public int getBackgroundColor() {
- return mColor;
- }
+ public int getBackgroundColor() {
+ return mColor;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.bgColor = mColor;
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.bgColor = mColor;
+ }
}
diff --git a/core/java/android/text/style/CharacterStyle.java b/core/java/android/text/style/CharacterStyle.java
index 14dfddd..5b95f1a 100644
--- a/core/java/android/text/style/CharacterStyle.java
+++ b/core/java/android/text/style/CharacterStyle.java
@@ -24,7 +24,7 @@ import android.text.TextPaint;
* ones may just implement {@link UpdateAppearance}.
*/
public abstract class CharacterStyle {
- public abstract void updateDrawState(TextPaint tp);
+ public abstract void updateDrawState(TextPaint tp);
/**
* A given CharacterStyle can only applied to a single region of a given
diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java
index 476124d..c9e09bd 100644
--- a/core/java/android/text/style/ForegroundColorSpan.java
+++ b/core/java/android/text/style/ForegroundColorSpan.java
@@ -26,9 +26,9 @@ public class ForegroundColorSpan extends CharacterStyle
private final int mColor;
- public ForegroundColorSpan(int color) {
- mColor = color;
- }
+ public ForegroundColorSpan(int color) {
+ mColor = color;
+ }
public ForegroundColorSpan(Parcel src) {
mColor = src.readInt();
@@ -46,12 +46,12 @@ public class ForegroundColorSpan extends CharacterStyle
dest.writeInt(mColor);
}
- public int getForegroundColor() {
- return mColor;
- }
+ public int getForegroundColor() {
+ return mColor;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setColor(mColor);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setColor(mColor);
+ }
}
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 64ab0d8..2ff52a8 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -21,18 +21,18 @@ import android.text.TextPaint;
public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
- private MaskFilter mFilter;
+ private MaskFilter mFilter;
- public MaskFilterSpan(MaskFilter filter) {
- mFilter = filter;
- }
+ public MaskFilterSpan(MaskFilter filter) {
+ mFilter = filter;
+ }
- public MaskFilter getMaskFilter() {
- return mFilter;
- }
+ public MaskFilter getMaskFilter() {
+ return mFilter;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setMaskFilter(mFilter);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setMaskFilter(mFilter);
+ }
}
diff --git a/core/java/android/text/style/MetricAffectingSpan.java b/core/java/android/text/style/MetricAffectingSpan.java
index a02b276..853ecc6 100644
--- a/core/java/android/text/style/MetricAffectingSpan.java
+++ b/core/java/android/text/style/MetricAffectingSpan.java
@@ -26,7 +26,7 @@ public abstract class MetricAffectingSpan
extends CharacterStyle
implements UpdateLayout {
- public abstract void updateMeasureState(TextPaint p);
+ public abstract void updateMeasureState(TextPaint p);
/**
* Returns "this" for most MetricAffectingSpans, but for
diff --git a/core/java/android/text/style/RasterizerSpan.java b/core/java/android/text/style/RasterizerSpan.java
index 75b5bcc..cae9640 100644
--- a/core/java/android/text/style/RasterizerSpan.java
+++ b/core/java/android/text/style/RasterizerSpan.java
@@ -21,18 +21,18 @@ import android.text.TextPaint;
public class RasterizerSpan extends CharacterStyle implements UpdateAppearance {
- private Rasterizer mRasterizer;
+ private Rasterizer mRasterizer;
- public RasterizerSpan(Rasterizer r) {
- mRasterizer = r;
- }
+ public RasterizerSpan(Rasterizer r) {
+ mRasterizer = r;
+ }
- public Rasterizer getRasterizer() {
- return mRasterizer;
- }
+ public Rasterizer getRasterizer() {
+ return mRasterizer;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setRasterizer(mRasterizer);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setRasterizer(mRasterizer);
+ }
}
diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java
index 9717362..632dbd4 100644
--- a/core/java/android/text/style/RelativeSizeSpan.java
+++ b/core/java/android/text/style/RelativeSizeSpan.java
@@ -23,11 +23,11 @@ import android.text.TextUtils;
public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableSpan {
- private final float mProportion;
+ private final float mProportion;
- public RelativeSizeSpan(float proportion) {
- mProportion = proportion;
- }
+ public RelativeSizeSpan(float proportion) {
+ mProportion = proportion;
+ }
public RelativeSizeSpan(Parcel src) {
mProportion = src.readFloat();
@@ -45,17 +45,17 @@ public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableS
dest.writeFloat(mProportion);
}
- public float getSizeChange() {
- return mProportion;
- }
+ public float getSizeChange() {
+ return mProportion;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setTextSize(ds.getTextSize() * mProportion);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setTextSize(ds.getTextSize() * mProportion);
+ }
- @Override
- public void updateMeasureState(TextPaint ds) {
- ds.setTextSize(ds.getTextSize() * mProportion);
- }
+ @Override
+ public void updateMeasureState(TextPaint ds) {
+ ds.setTextSize(ds.getTextSize() * mProportion);
+ }
}
diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java
index 655064b..a22a5a1 100644
--- a/core/java/android/text/style/ScaleXSpan.java
+++ b/core/java/android/text/style/ScaleXSpan.java
@@ -23,11 +23,11 @@ import android.text.TextUtils;
public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan {
- private final float mProportion;
+ private final float mProportion;
- public ScaleXSpan(float proportion) {
- mProportion = proportion;
- }
+ public ScaleXSpan(float proportion) {
+ mProportion = proportion;
+ }
public ScaleXSpan(Parcel src) {
mProportion = src.readFloat();
@@ -45,17 +45,17 @@ public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan {
dest.writeFloat(mProportion);
}
- public float getScaleX() {
- return mProportion;
- }
+ public float getScaleX() {
+ return mProportion;
+ }
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setTextScaleX(ds.getTextScaleX() * mProportion);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+ }
- @Override
- public void updateMeasureState(TextPaint ds) {
- ds.setTextScaleX(ds.getTextScaleX() * mProportion);
- }
+ @Override
+ public void updateMeasureState(TextPaint ds) {
+ ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+ }
}
diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java
index b51363a..303e415 100644
--- a/core/java/android/text/style/StrikethroughSpan.java
+++ b/core/java/android/text/style/StrikethroughSpan.java
@@ -40,8 +40,8 @@ public class StrikethroughSpan extends CharacterStyle
public void writeToParcel(Parcel dest, int flags) {
}
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setStrikeThruText(true);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setStrikeThruText(true);
+ }
}
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index 8e6147c..b08f70e 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -33,17 +33,17 @@ import android.text.TextUtils;
*/
public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
- private final int mStyle;
-
- /**
- *
- * @param style An integer constant describing the style for this span. Examples
- * include bold, italic, and normal. Values are constants defined
- * in {@link android.graphics.Typeface}.
- */
- public StyleSpan(int style) {
- mStyle = style;
- }
+ private final int mStyle;
+
+ /**
+ *
+ * @param style An integer constant describing the style for this span. Examples
+ * include bold, italic, and normal. Values are constants defined
+ * in {@link android.graphics.Typeface}.
+ */
+ public StyleSpan(int style) {
+ mStyle = style;
+ }
public StyleSpan(Parcel src) {
mStyle = src.readInt();
@@ -61,19 +61,19 @@ public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
dest.writeInt(mStyle);
}
- /**
- * Returns the style constant defined in {@link android.graphics.Typeface}.
- */
- public int getStyle() {
- return mStyle;
- }
+ /**
+ * Returns the style constant defined in {@link android.graphics.Typeface}.
+ */
+ public int getStyle() {
+ return mStyle;
+ }
- @Override
+ @Override
public void updateDrawState(TextPaint ds) {
apply(ds, mStyle);
}
- @Override
+ @Override
public void updateMeasureState(TextPaint paint) {
apply(paint, mStyle);
}
diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java
index b0cb0e8..80b2427 100644
--- a/core/java/android/text/style/UnderlineSpan.java
+++ b/core/java/android/text/style/UnderlineSpan.java
@@ -40,8 +40,8 @@ public class UnderlineSpan extends CharacterStyle
public void writeToParcel(Parcel dest, int flags) {
}
- @Override
- public void updateDrawState(TextPaint ds) {
- ds.setUnderlineText(true);
- }
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ ds.setUnderlineText(true);
+ }
}
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index b758930..4c92e950 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -478,6 +478,7 @@ public class GLRenderer extends HardwareRenderer {
@Override
void flushLayerUpdates() {
if (validate()) {
+ flushLayerChanges();
mGlCanvas.flushLayerUpdates();
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e30f825..e9082c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11465,7 +11465,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final int scrollX = mScrollX;
final int scrollY = mScrollY;
invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
- dirty.right - scrollX, dirty.bottom - scrollY, true);
+ dirty.right - scrollX, dirty.bottom - scrollY, true, false);
}
/**
@@ -11485,7 +11485,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void invalidate(int l, int t, int r, int b) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
- invalidateInternal(l - scrollX, t - scrollY, r - scrollY, b - scrollY, true);
+ invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
}
/**
@@ -11513,22 +11513,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* dimensions have not changed.
*/
void invalidate(boolean invalidateCache) {
- invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache);
+ invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
- void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache) {
+ void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
+ boolean fullInvalidate) {
if (skipInvalidate()) {
return;
}
- final boolean wasDrawn = (mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS))
- == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS);
- final boolean hasValidCache = (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) != 0;
- final boolean invalidated = (mPrivateFlags & PFLAG_INVALIDATED) != 0;
- final boolean opacityChanged = isOpaque() != mLastIsOpaque;
- if (wasDrawn || (invalidateCache && hasValidCache) || !invalidated || opacityChanged) {
- mLastIsOpaque = isOpaque();
- mPrivateFlags &= ~PFLAG_DRAWN;
+ if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
+ || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
+ || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
+ || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
+ if (fullInvalidate) {
+ mLastIsOpaque = isOpaque();
+ mPrivateFlags &= ~PFLAG_DRAWN;
+ }
+
mPrivateFlags |= PFLAG_DIRTY;
if (invalidateCache) {
@@ -11552,6 +11554,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
receiver.damageInParent();
}
}
+
+ // Damage the entire IsolatedZVolume recieving this view's shadow.
+ if (getCastsShadow() && getTranslationZ() != 0) {
+ damageIsolatedZVolume();
+ }
}
}
@@ -11579,6 +11586,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Damage area of the screen covered by the current isolated Z volume
+ *
+ * This method will guarantee that any changes to shadows cast by a View
+ * are damaged on the screen for future redraw.
+ */
+ private void damageIsolatedZVolume() {
+ final AttachInfo ai = mAttachInfo;
+ if (ai != null) {
+ ViewParent p = getParent();
+ while (p != null) {
+ if (p instanceof ViewGroup) {
+ final ViewGroup vg = (ViewGroup) p;
+ if (vg.hasIsolatedZVolume()) {
+ vg.damageInParent();
+ return;
+ }
+ }
+ p = p.getParent();
+ }
+ }
+ }
+
+ /**
* Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
* set any flags or handle all of the cases handled by the default invalidation methods.
* Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
@@ -11606,12 +11636,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
} else {
damageInParent();
}
+ if (invalidateParent && getCastsShadow() && getTranslationZ() != 0) {
+ damageIsolatedZVolume();
+ }
}
/**
* Tells the parent view to damage this view's bounds.
+ *
+ * @hide
*/
- private void damageInParent() {
+ protected void damageInParent() {
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
if (p != null && ai != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a13b184..2b32d70 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -264,10 +264,10 @@ public final class ViewRootImpl implements ViewParent,
int mScrollY;
int mCurScrollY;
Scroller mScroller;
-// HardwareLayer mResizeBuffer;
-// long mResizeBufferStartTime;
-// int mResizeBufferDuration;
-// static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
+ HardwareLayer mResizeBuffer;
+ long mResizeBufferStartTime;
+ int mResizeBufferDuration;
+ static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
private ArrayList<LayoutTransition> mPendingTransitions;
final ViewConfiguration mViewConfiguration;
@@ -931,17 +931,12 @@ public final class ViewRootImpl implements ViewParent,
return mAppVisible ? mView.getVisibility() : View.GONE;
}
-// void disposeResizeBuffer() {
-// if (mResizeBuffer != null && mAttachInfo.mHardwareRenderer != null) {
-// mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
-// @Override
-// public void run() {
-// mResizeBuffer.destroy();
-// mResizeBuffer = null;
-// }
-// });
-// }
-// }
+ void disposeResizeBuffer() {
+ if (mResizeBuffer != null) {
+ mResizeBuffer.destroy();
+ mResizeBuffer = null;
+ }
+ }
/**
* Add LayoutTransition to the list of transitions to be started in the next traversal.
@@ -1452,76 +1447,63 @@ public final class ViewRootImpl implements ViewParent,
final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(
mAttachInfo.mVisibleInsets);
if (contentInsetsChanged) {
-// TODO: Do something with this...
-// if (mWidth > 0 && mHeight > 0 && lp != null &&
-// ((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
-// & View.SYSTEM_UI_LAYOUT_FLAGS) == 0 &&
-// mSurface != null && mSurface.isValid() &&
-// !mAttachInfo.mTurnOffWindowResizeAnim &&
-// mAttachInfo.mHardwareRenderer != null &&
-// mAttachInfo.mHardwareRenderer.isEnabled() &&
-// mAttachInfo.mHardwareRenderer.validate() &&
-// lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
-//
-// disposeResizeBuffer();
-//
-// boolean completed = false;
-// HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas();
-// HardwareCanvas layerCanvas = null;
-// try {
-// if (mResizeBuffer == null) {
-// mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
-// mWidth, mHeight, false);
-// } else if (mResizeBuffer.getWidth() != mWidth ||
-// mResizeBuffer.getHeight() != mHeight) {
-// mResizeBuffer.resize(mWidth, mHeight);
-// }
-// // TODO: should handle create/resize failure
-// layerCanvas = mResizeBuffer.start(hwRendererCanvas);
-// final int restoreCount = layerCanvas.save();
-//
-// int yoff;
-// final boolean scrolling = mScroller != null
-// && mScroller.computeScrollOffset();
-// if (scrolling) {
-// yoff = mScroller.getCurrY();
-// mScroller.abortAnimation();
-// } else {
-// yoff = mScrollY;
-// }
-//
-// layerCanvas.translate(0, -yoff);
-// if (mTranslator != null) {
-// mTranslator.translateCanvas(layerCanvas);
-// }
-//
-// DisplayList displayList = mView.mDisplayList;
-// if (displayList != null && displayList.isValid()) {
-// layerCanvas.drawDisplayList(displayList, null,
-// DisplayList.FLAG_CLIP_CHILDREN);
-// } else {
-// mView.draw(layerCanvas);
-// }
-//
-// drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
-//
-// mResizeBufferStartTime = SystemClock.uptimeMillis();
-// mResizeBufferDuration = mView.getResources().getInteger(
-// com.android.internal.R.integer.config_mediumAnimTime);
-// completed = true;
-//
-// layerCanvas.restoreToCount(restoreCount);
-// } catch (OutOfMemoryError e) {
-// Log.w(TAG, "Not enough memory for content change anim buffer", e);
-// } finally {
-// if (mResizeBuffer != null) {
-// mResizeBuffer.end(hwRendererCanvas);
-// if (!completed) {
-// disposeResizeBuffer();
-// }
-// }
-// }
-// }
+ if (mWidth > 0 && mHeight > 0 && lp != null &&
+ ((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
+ & View.SYSTEM_UI_LAYOUT_FLAGS) == 0 &&
+ mSurface != null && mSurface.isValid() &&
+ !mAttachInfo.mTurnOffWindowResizeAnim &&
+ mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled() &&
+ lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
+
+ disposeResizeBuffer();
+
+ if (mResizeBuffer == null) {
+ mResizeBuffer = mAttachInfo.mHardwareRenderer.createDisplayListLayer(
+ mWidth, mHeight);
+ }
+ mResizeBuffer.prepare(mWidth, mHeight, false);
+ DisplayList layerDisplayList = mResizeBuffer.startRecording();
+ HardwareCanvas layerCanvas = layerDisplayList.start(mWidth, mHeight);
+ final int restoreCount = layerCanvas.save();
+
+ int yoff;
+ final boolean scrolling = mScroller != null
+ && mScroller.computeScrollOffset();
+ if (scrolling) {
+ yoff = mScroller.getCurrY();
+ mScroller.abortAnimation();
+ } else {
+ yoff = mScrollY;
+ }
+
+ layerCanvas.translate(0, -yoff);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(layerCanvas);
+ }
+
+ DisplayList displayList = mView.mDisplayList;
+ if (displayList != null && displayList.isValid()) {
+ layerCanvas.drawDisplayList(displayList, null,
+ DisplayList.FLAG_CLIP_CHILDREN);
+ } else {
+ mView.draw(layerCanvas);
+ }
+
+ drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
+
+ mResizeBufferStartTime = SystemClock.uptimeMillis();
+ mResizeBufferDuration = mView.getResources().getInteger(
+ com.android.internal.R.integer.config_mediumAnimTime);
+
+ layerCanvas.restoreToCount(restoreCount);
+ layerDisplayList.end();
+ layerDisplayList.setCaching(true);
+ layerDisplayList.setLeftTopRightBottom(0, 0, mWidth, mHeight);
+ mTempRect.set(0, 0, mWidth, mHeight);
+ mResizeBuffer.endRecording(mTempRect);
+ mAttachInfo.mHardwareRenderer.flushLayerUpdates();
+ }
mAttachInfo.mContentInsets.set(mPendingContentInsets);
if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
+ mAttachInfo.mContentInsets);
@@ -1581,7 +1563,7 @@ public final class ViewRootImpl implements ViewParent,
if (mScroller != null) {
mScroller.abortAnimation();
}
-// disposeResizeBuffer();
+ disposeResizeBuffer();
// Our surface is gone
if (mAttachInfo.mHardwareRenderer != null &&
mAttachInfo.mHardwareRenderer.isEnabled()) {
@@ -2180,10 +2162,10 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void onHardwarePostDraw(HardwareCanvas canvas) {
-// if (mResizeBuffer != null) {
-// mResizePaint.setAlpha(mResizeAlpha);
-// canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
-// }
+ if (mResizeBuffer != null) {
+ mResizePaint.setAlpha(mResizeAlpha);
+ canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
+ }
// TODO: this
if (!HardwareRenderer.sUseRenderThread) {
drawAccessibilityFocusedDrawableIfNeeded(canvas);
@@ -2342,17 +2324,17 @@ public final class ViewRootImpl implements ViewParent,
final boolean scalingRequired = attachInfo.mScalingRequired;
int resizeAlpha = 0;
-// if (mResizeBuffer != null) {
-// long deltaTime = SystemClock.uptimeMillis() - mResizeBufferStartTime;
-// if (deltaTime < mResizeBufferDuration) {
-// float amt = deltaTime/(float) mResizeBufferDuration;
-// amt = mResizeInterpolator.getInterpolation(amt);
-// animating = true;
-// resizeAlpha = 255 - (int)(amt*255);
-// } else {
-// disposeResizeBuffer();
-// }
-// }
+ if (mResizeBuffer != null) {
+ long deltaTime = SystemClock.uptimeMillis() - mResizeBufferStartTime;
+ if (deltaTime < mResizeBufferDuration) {
+ float amt = deltaTime/(float) mResizeBufferDuration;
+ amt = mResizeInterpolator.getInterpolation(amt);
+ animating = true;
+ resizeAlpha = 255 - (int)(amt*255);
+ } else {
+ disposeResizeBuffer();
+ }
+ }
final Rect dirty = mDirty;
if (mSurfaceHolder != null) {
@@ -2362,7 +2344,7 @@ public final class ViewRootImpl implements ViewParent,
if (mScroller != null) {
mScroller.abortAnimation();
}
-// disposeResizeBuffer();
+ disposeResizeBuffer();
}
return;
}
@@ -2725,7 +2707,7 @@ public final class ViewRootImpl implements ViewParent,
if (scrollY != mScrollY) {
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Pan scroll changed: old="
+ mScrollY + " , new=" + scrollY);
- if (!immediate /*&& mResizeBuffer == null*/) {
+ if (!immediate && mResizeBuffer == null) {
if (mScroller == null) {
mScroller = new Scroller(mView.getContext());
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 4fdbc1e..560d0c9 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -282,6 +282,22 @@ public class AccessibilityNodeInfo implements Parcelable {
*/
public static final int ACTION_DISMISS = 0x00100000;
+ /**
+ * Action that sets the text of the node. Performing the action without argument, using <code>
+ * null</code> or empty {@link CharSequence} will clear the text. This action will also put the
+ * cursor at the end of text.
+ * <p>
+ * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
+ * <strong>Example:</strong>
+ * <code><pre><p>
+ * Bundle arguments = new Bundle();
+ * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
+ * "android");
+ * info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
+ * </code></pre></p>
+ */
+ public static final int ACTION_SET_TEXT = 0x00200000;
+
// Action arguments
/**
@@ -351,6 +367,18 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final String ACTION_ARGUMENT_SELECTION_END_INT =
"ACTION_ARGUMENT_SELECTION_END_INT";
+ /**
+ * Argument for specifying the text content to set
+ * <p>
+ * <strong>Type:</strong> CharSequence<br>
+ * <strong>Actions:</strong> {@link #ACTION_SET_TEXT}
+ * </p>
+ *
+ * @see #ACTION_SET_TEXT
+ */
+ public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
+ "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+
// Focus types
/**
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 5df5811..9f2bf33 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.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
@@ -64,7 +64,7 @@ public final class InputMethodInfo implements Parcelable {
* The Service that implements this input method component.
*/
final ResolveInfo mService;
-
+
/**
* The unique string Id to identify the input method. This is generated
* from the input method component.
@@ -144,22 +144,22 @@ public final class InputMethodInfo implements Parcelable {
throw new XmlPullParserException("No "
+ InputMethod.SERVICE_META_DATA + " meta-data");
}
-
+
Resources res = pm.getResourcesForApplication(si.applicationInfo);
-
+
AttributeSet attrs = Xml.asAttributeSet(parser);
-
+
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
-
+
String nodeName = parser.getName();
if (!"input-method".equals(nodeName)) {
throw new XmlPullParserException(
"Meta-data does not start with input-method tag");
}
-
+
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.InputMethod);
settingsActivityComponent = sa.getString(
@@ -338,7 +338,7 @@ public final class InputMethodInfo implements Parcelable {
/**
* Load the user-displayed label for this input method.
- *
+ *
* @param pm Supply a PackageManager used to load the input method's
* resources.
*/
@@ -348,7 +348,7 @@ public final class InputMethodInfo implements Parcelable {
/**
* Load the user-displayed icon for this input method.
- *
+ *
* @param pm Supply a PackageManager used to load the input method's
* resources.
*/
@@ -362,7 +362,7 @@ public final class InputMethodInfo implements Parcelable {
* an {@link android.content.Intent} whose action is MAIN and with an
* explicit {@link android.content.ComponentName}
* composed of {@link #getPackageName} and the class name returned here.
- *
+ *
* <p>A null will be returned if there is no settings activity associated
* with the input method.
*/
@@ -419,7 +419,7 @@ public final class InputMethodInfo implements Parcelable {
pw.println(prefix + "Service:");
mService.dump(pw, prefix + " ");
}
-
+
@Override
public String toString() {
return "InputMethodInfo{" + mId
@@ -430,7 +430,7 @@ public final class InputMethodInfo implements Parcelable {
/**
* Used to test whether the given parameter object is an
* {@link InputMethodInfo} and its Id is the same to this one.
- *
+ *
* @return true if the given parameter object is an
* {@link InputMethodInfo} and its Id is the same to this one.
*/
@@ -467,7 +467,7 @@ public final class InputMethodInfo implements Parcelable {
/**
* Used to package this object into a {@link Parcel}.
- *
+ *
* @param dest The {@link Parcel} to be written.
* @param flags The flags used for parceling.
*/
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3fd0e5d..0b78e0a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -704,6 +704,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private SavedState mPendingSync;
/**
+ * Whether the view is in the process of detaching from its window.
+ */
+ private boolean mIsDetaching;
+
+ /**
* Interface definition for a callback to be invoked when the list or grid
* has been scrolled.
*/
@@ -2169,20 +2174,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
- * @return the direct child that contains accessibility focus, or null if no
+ * @param focusedView view that holds accessibility focus
+ * @return direct child that contains accessibility focus, or null if no
* child contains accessibility focus
*/
- View getAccessibilityFocusedChild() {
- final ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl == null) {
- return null;
- }
-
- View focusedView = viewRootImpl.getAccessibilityFocusedHost();
- if (focusedView == null) {
- return null;
- }
-
+ View getAccessibilityFocusedChild(View focusedView) {
ViewParent viewParent = focusedView.getParent();
while ((viewParent instanceof View) && (viewParent != this)) {
focusedView = (View) viewParent;
@@ -2335,12 +2331,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
} else {
isScrap[0] = true;
- // Clear any system-managed transient state so that we can
- // recycle this view and bind it to different data.
- if (child.isAccessibilityFocused()) {
- child.clearAccessibilityFocus();
- }
-
child.dispatchFinishTemporaryDetach();
}
}
@@ -2803,6 +2793,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ mIsDetaching = true;
+
// Dismiss the popup in case onSaveInstanceState() was not invoked
dismissPopup();
@@ -2851,6 +2843,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
removeCallbacks(mTouchModeReset);
mTouchModeReset.run();
}
+
+ mIsDetaching = false;
}
@Override
@@ -3477,7 +3471,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mPositionScroller.stop();
}
- if (!isAttachedToWindow()) {
+ if (mIsDetaching || !isAttachedToWindow()) {
// Something isn't right.
// Since we rely on being attached to get data set change notifications,
// don't risk doing anything where we might try to resync and find things
@@ -3716,7 +3710,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mTouchMode = TOUCH_MODE_REST;
child.setPressed(false);
setPressed(false);
- if (!mDataChanged && isAttachedToWindow()) {
+ if (!mDataChanged && !mIsDetaching && isAttachedToWindow()) {
performClick.run();
}
}
@@ -3991,7 +3985,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mPositionScroller.stop();
}
- if (!isAttachedToWindow()) {
+ if (mIsDetaching || !isAttachedToWindow()) {
// Something isn't right.
// Since we rely on being attached to get data set change notifications,
// don't risk doing anything where we might try to resync and find things
@@ -6196,18 +6190,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
void clear() {
if (mViewTypeCount == 1) {
final ArrayList<View> scrap = mCurrentScrap;
- final int scrapCount = scrap.size();
- for (int i = 0; i < scrapCount; i++) {
- removeDetachedView(scrap.remove(scrapCount - 1 - i), false);
- }
+ clearScrap(scrap);
} else {
final int typeCount = mViewTypeCount;
for (int i = 0; i < typeCount; i++) {
final ArrayList<View> scrap = mScrapViews[i];
- final int scrapCount = scrap.size();
- for (int j = 0; j < scrapCount; j++) {
- removeDetachedView(scrap.remove(scrapCount - 1 - j), false);
- }
+ clearScrap(scrap);
}
}
@@ -6308,7 +6296,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mViewTypeCount == 1) {
return retrieveFromScrap(mCurrentScrap, position);
} else {
- int whichScrap = mAdapter.getItemViewType(position);
+ final int whichScrap = mAdapter.getItemViewType(position);
if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
return retrieveFromScrap(mScrapViews[whichScrap], position);
}
@@ -6380,13 +6368,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mScrapViews[viewType].add(scrap);
}
- // Clear any system-managed transient state.
- if (scrap.isAccessibilityFocused()) {
- scrap.clearAccessibilityFocus();
- }
-
- scrap.setAccessibilityDelegate(null);
-
if (mRecyclerListener != null) {
mRecyclerListener.onMovedToScrapHeap(scrap);
}
@@ -6460,7 +6441,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
lp.scrappedFromPosition = mFirstActivePosition + i;
scrapViews.add(victim);
- victim.setAccessibilityDelegate(null);
if (hasListener) {
mRecyclerListener.onMovedToScrapHeap(victim);
}
@@ -6564,23 +6544,52 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
- }
- static View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
- int size = scrapViews.size();
- if (size > 0) {
- // See if we still have a view for this position.
- for (int i=0; i<size; i++) {
- View view = scrapViews.get(i);
- if (((AbsListView.LayoutParams)view.getLayoutParams())
- .scrappedFromPosition == position) {
- scrapViews.remove(i);
- return view;
+ private View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
+ final int size = scrapViews.size();
+ if (size > 0) {
+ // See if we still have a view for this position or ID.
+ for (int i = 0; i < size; i++) {
+ final View view = scrapViews.get(i);
+ final AbsListView.LayoutParams params =
+ (AbsListView.LayoutParams) view.getLayoutParams();
+
+ if (mAdapterHasStableIds) {
+ final long id = mAdapter.getItemId(position);
+ if (id == params.itemId) {
+ return scrapViews.remove(i);
+ }
+ } else if (params.scrappedFromPosition == position) {
+ final View scrap = scrapViews.remove(i);
+ clearAccessibilityFromScrap(scrap);
+ return scrap;
+ }
}
+ final View scrap = scrapViews.remove(size - 1);
+ clearAccessibilityFromScrap(scrap);
+ return scrap;
+ } else {
+ return null;
}
- return scrapViews.remove(size - 1);
- } else {
- return null;
+ }
+
+ private void clearScrap(final ArrayList<View> scrap) {
+ final int scrapCount = scrap.size();
+ for (int j = 0; j < scrapCount; j++) {
+ removeDetachedView(scrap.remove(scrapCount - 1 - j), false);
+ }
+ }
+
+ private void clearAccessibilityFromScrap(View view) {
+ if (view.isAccessibilityFocused()) {
+ view.clearAccessibilityFocus();
+ }
+ view.setAccessibilityDelegate(null);
+ }
+
+ private void removeDetachedView(View child, boolean animate) {
+ child.setAccessibilityDelegate(null);
+ AbsListView.this.removeDetachedView(child, animate);
}
}
@@ -7179,7 +7188,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
startOffsetRatio = -firstChild.getTop() / (float) firstChildHeight;
}
- final float startSubRow = firstRow + startOffsetRatio;
+ final float startSubRow = MathUtils.constrain(
+ firstRow + startOffsetRatio, 0, getCount());
if (startSubRow == endSubRow && mOffset == 0) {
// Don't scroll, target is already in position.
return;
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 3a7cc87..a8ff562 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,6 +17,7 @@
package android.widget;
import android.content.Context;
+import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
@@ -132,4 +133,22 @@ public class EditText extends TextView {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(EditText.class.getName());
}
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SET_TEXT: {
+ CharSequence text = (arguments != null) ? arguments.getCharSequence(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null;
+ setText(text);
+ if (text != null && text.length() > 0) {
+ setSelection(text.length());
+ }
+ return true;
+ }
+ default: {
+ return super.performAccessibilityAction(action, arguments);
+ }
+ }
+ }
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 6743002..04b18c1 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -30,13 +30,13 @@ import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
import android.view.animation.GridLayoutAnimationController;
-import android.widget.AbsListView.AbsPositionScroller;
-import android.widget.ListView.ListViewPositionScroller;
import android.widget.RemoteViews.RemoteView;
import java.lang.annotation.Retention;
@@ -1222,22 +1222,32 @@ public class GridView extends AbsListView {
setSelectedPositionInt(mNextSelectedPosition);
- // Remember which child, if any, had accessibility focus.
- final int accessibilityFocusPosition;
- final View accessFocusedChild = getAccessibilityFocusedChild();
- if (accessFocusedChild != null) {
- accessibilityFocusPosition = getPositionForView(accessFocusedChild);
- accessFocusedChild.setHasTransientState(true);
- } else {
- accessibilityFocusPosition = INVALID_POSITION;
- }
+ AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
+ View accessibilityFocusLayoutRestoreView = null;
+ int accessibilityFocusPosition = INVALID_POSITION;
+
+ // Remember which child, if any, had accessibility focus. This must
+ // occur before recycling any views, since that will clear
+ // accessibility focus.
+ final ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null) {
+ final View focusHost = viewRootImpl.getAccessibilityFocusedHost();
+ if (focusHost != null) {
+ final View focusChild = getAccessibilityFocusedChild(focusHost);
+ if (focusChild != null) {
+ if (!dataChanged || focusChild.hasTransientState()
+ || mAdapterHasStableIds) {
+ // The views won't be changing, so try to maintain
+ // focus on the current host and virtual view.
+ accessibilityFocusLayoutRestoreView = focusHost;
+ accessibilityFocusLayoutRestoreNode = viewRootImpl
+ .getAccessibilityFocusedVirtualView();
+ }
- // Ensure the child containing focus, if any, has transient state.
- // If the list data hasn't changed, or if the adapter has stable
- // IDs, this will maintain focus.
- final View focusedChild = getFocusedChild();
- if (focusedChild != null) {
- focusedChild.setHasTransientState(true);
+ // Try to maintain focus at the same position.
+ accessibilityFocusPosition = getPositionForView(focusChild);
+ }
+ }
}
// Pull all children into the RecycleBin.
@@ -1324,27 +1334,35 @@ public class GridView extends AbsListView {
mSelectorRect.setEmpty();
}
- if (accessFocusedChild != null) {
- accessFocusedChild.setHasTransientState(false);
-
- // If we failed to maintain accessibility focus on the previous
- // view, attempt to restore it to the previous position.
- if (!accessFocusedChild.isAccessibilityFocused()
- && accessibilityFocusPosition != INVALID_POSITION) {
- // Bound the position within the visible children.
- final int position = MathUtils.constrain(
- accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
- final View restoreView = getChildAt(position);
- if (restoreView != null) {
- restoreView.requestAccessibilityFocus();
+ // Attempt to restore accessibility focus, if necessary.
+ if (viewRootImpl != null) {
+ final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+ if (newAccessibilityFocusedView == null) {
+ if (accessibilityFocusLayoutRestoreView != null
+ && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+ final AccessibilityNodeProvider provider =
+ accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+ if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
+ final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+ accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+ provider.performAction(virtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+ } else {
+ accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+ }
+ } else if (accessibilityFocusPosition != INVALID_POSITION) {
+ // Bound the position within the visible children.
+ final int position = MathUtils.constrain(
+ accessibilityFocusPosition - mFirstPosition, 0,
+ getChildCount() - 1);
+ final View restoreView = getChildAt(position);
+ if (restoreView != null) {
+ restoreView.requestAccessibilityFocus();
+ }
}
}
}
- if (focusedChild != null) {
- focusedChild.setHasTransientState(false);
- }
-
mLayoutMode = LAYOUT_NORMAL;
mDataChanged = false;
if (mPositionScrollAfterLayout != null) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 65f1ab7..82e624d 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -667,6 +667,7 @@ public class LinearLayout extends ViewGroup {
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
boolean matchWidth = false;
+ boolean skippedMeasure = false;
final int baselineChildIndex = mBaselineAlignedChildIndex;
final boolean useLargestChild = mUseLargestChild;
@@ -701,6 +702,7 @@ public class LinearLayout extends ViewGroup {
// there is any leftover space.
final int totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
+ skippedMeasure = true;
} else {
int oldHeight = Integer.MIN_VALUE;
@@ -827,9 +829,10 @@ public class LinearLayout extends ViewGroup {
heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
// Either expand children with weight to take up available space or
- // shrink them if they extend beyond our current bounds
+ // shrink them if they extend beyond our current bounds. If we skipped
+ // measurement on any children, we need to measure them now.
int delta = heightSize - mTotalLength;
- if (delta != 0 && totalWeight > 0.0f) {
+ if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
mTotalLength = 0;
@@ -995,6 +998,7 @@ public class LinearLayout extends ViewGroup {
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
boolean matchHeight = false;
+ boolean skippedMeasure = false;
if (mMaxAscent == null || mMaxDescent == null) {
mMaxAscent = new int[VERTICAL_GRAVITY_COUNT];
@@ -1057,6 +1061,8 @@ public class LinearLayout extends ViewGroup {
if (baselineAligned) {
final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
child.measure(freeSpec, freeSpec);
+ } else {
+ skippedMeasure = true;
}
} else {
int oldWidth = Integer.MIN_VALUE;
@@ -1205,9 +1211,10 @@ public class LinearLayout extends ViewGroup {
widthSize = widthSizeAndState & MEASURED_SIZE_MASK;
// Either expand children with weight to take up available space or
- // shrink them if they extend beyond our current bounds
+ // shrink them if they extend beyond our current bounds. If we skipped
+ // measurement on any children, we need to measure them now.
int delta = widthSize - mTotalLength;
- if (delta != 0 && totalWeight > 0.0f) {
+ if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index cef2138..5de67c8 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -39,10 +39,12 @@ import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.widget.RemoteViews.RemoteView;
import java.util.ArrayList;
@@ -1567,22 +1569,58 @@ public class ListView extends AbsListView {
setSelectedPositionInt(mNextSelectedPosition);
- // Remember which child, if any, had accessibility focus.
- final int accessibilityFocusPosition;
- final View accessFocusedChild = getAccessibilityFocusedChild();
- if (accessFocusedChild != null) {
- accessibilityFocusPosition = getPositionForView(accessFocusedChild);
- accessFocusedChild.setHasTransientState(true);
- } else {
- accessibilityFocusPosition = INVALID_POSITION;
+ AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
+ View accessibilityFocusLayoutRestoreView = null;
+ int accessibilityFocusPosition = INVALID_POSITION;
+
+ // Remember which child, if any, had accessibility focus. This must
+ // occur before recycling any views, since that will clear
+ // accessibility focus.
+ final ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null) {
+ final View focusHost = viewRootImpl.getAccessibilityFocusedHost();
+ if (focusHost != null) {
+ final View focusChild = getAccessibilityFocusedChild(focusHost);
+ if (focusChild != null) {
+ if (!dataChanged || isDirectChildHeaderOrFooter(focusChild)
+ || focusChild.hasTransientState() || mAdapterHasStableIds) {
+ // The views won't be changing, so try to maintain
+ // focus on the current host and virtual view.
+ accessibilityFocusLayoutRestoreView = focusHost;
+ accessibilityFocusLayoutRestoreNode = viewRootImpl
+ .getAccessibilityFocusedVirtualView();
+ }
+
+ // If all else fails, maintain focus at the same
+ // position.
+ accessibilityFocusPosition = getPositionForView(focusChild);
+ }
+ }
}
- // Ensure the child containing focus, if any, has transient state.
- // If the list data hasn't changed, or if the adapter has stable
- // IDs, this will maintain focus.
+ View focusLayoutRestoreDirectChild = null;
+ View focusLayoutRestoreView = null;
+
+ // Take focus back to us temporarily to avoid the eventual call to
+ // clear focus when removing the focused child below from messing
+ // things up when ViewAncestor assigns focus back to someone else.
final View focusedChild = getFocusedChild();
if (focusedChild != null) {
- focusedChild.setHasTransientState(true);
+ // TODO: in some cases focusedChild.getParent() == null
+
+ // We can remember the focused view to restore after re-layout
+ // if the data hasn't changed, or if the focused position is a
+ // header or footer.
+ if (!dataChanged || isDirectChildHeaderOrFooter(focusedChild)) {
+ focusLayoutRestoreDirectChild = focusedChild;
+ // Remember the specific view that had focus.
+ focusLayoutRestoreView = findFocus();
+ if (focusLayoutRestoreView != null) {
+ // Tell it we are going to mess with it.
+ focusLayoutRestoreView.onStartTemporaryDetach();
+ }
+ }
+ requestFocus();
}
// Pull all children into the RecycleBin.
@@ -1656,20 +1694,24 @@ public class ListView extends AbsListView {
recycleBin.scrapActiveViews();
if (sel != null) {
- final boolean shouldPlaceFocus = mItemsCanFocus && hasFocus();
- final boolean maintainedFocus = focusedChild != null && focusedChild.hasFocus();
- if (shouldPlaceFocus && !maintainedFocus && !sel.hasFocus()) {
- if (sel.requestFocus()) {
- // Successfully placed focus, clear selection.
- sel.setSelected(false);
- mSelectorRect.setEmpty();
- } else {
- // Failed to place focus, clear current (invalid) focus.
+ // The current selected item should get focus if items are
+ // focusable.
+ if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) {
+ final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild &&
+ focusLayoutRestoreView != null &&
+ focusLayoutRestoreView.requestFocus()) || sel.requestFocus();
+ if (!focusWasTaken) {
+ // Selected item didn't take focus, but we still want to
+ // make sure something else outside of the selected view
+ // has focus.
final View focused = getFocusedChild();
if (focused != null) {
focused.clearFocus();
}
positionSelector(INVALID_POSITION, sel);
+ } else {
+ sel.setSelected(false);
+ mSelectorRect.setEmpty();
}
} else {
positionSelector(INVALID_POSITION, sel);
@@ -1687,27 +1729,48 @@ public class ListView extends AbsListView {
mSelectedTop = 0;
mSelectorRect.setEmpty();
}
- }
-
- if (accessFocusedChild != null) {
- accessFocusedChild.setHasTransientState(false);
- // If we failed to maintain accessibility focus on the previous
- // view, attempt to restore it to the previous position.
- if (!accessFocusedChild.isAccessibilityFocused()
- && accessibilityFocusPosition != INVALID_POSITION) {
- // Bound the position within the visible children.
- final int position = MathUtils.constrain(
- accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
- final View restoreView = getChildAt(position);
- if (restoreView != null) {
- restoreView.requestAccessibilityFocus();
+ // Even if there is not selected position, we may need to
+ // restore focus (i.e. something focusable in touch mode).
+ if (hasFocus() && focusLayoutRestoreView != null) {
+ focusLayoutRestoreView.requestFocus();
+ }
+ }
+
+ // Attempt to restore accessibility focus, if necessary.
+ if (viewRootImpl != null) {
+ final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+ if (newAccessibilityFocusedView == null) {
+ if (accessibilityFocusLayoutRestoreView != null
+ && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+ final AccessibilityNodeProvider provider =
+ accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+ if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
+ final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+ accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+ provider.performAction(virtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+ } else {
+ accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+ }
+ } else if (accessibilityFocusPosition != INVALID_POSITION) {
+ // Bound the position within the visible children.
+ final int position = MathUtils.constrain(
+ accessibilityFocusPosition - mFirstPosition, 0,
+ getChildCount() - 1);
+ final View restoreView = getChildAt(position);
+ if (restoreView != null) {
+ restoreView.requestAccessibilityFocus();
+ }
}
}
}
- if (focusedChild != null) {
- focusedChild.setHasTransientState(false);
+ // Tell focus view we are done mucking with it, if it is still in
+ // our view hierarchy.
+ if (focusLayoutRestoreView != null
+ && focusLayoutRestoreView.getWindowToken() != null) {
+ focusLayoutRestoreView.onFinishTemporaryDetach();
}
mLayoutMode = LAYOUT_NORMAL;
@@ -1734,6 +1797,30 @@ public class ListView extends AbsListView {
}
/**
+ * @param child a direct child of this list.
+ * @return Whether child is a header or footer view.
+ */
+ private boolean isDirectChildHeaderOrFooter(View child) {
+ final ArrayList<FixedViewInfo> headers = mHeaderViewInfos;
+ final int numHeaders = headers.size();
+ for (int i = 0; i < numHeaders; i++) {
+ if (child == headers.get(i).view) {
+ return true;
+ }
+ }
+
+ final ArrayList<FixedViewInfo> footers = mFooterViewInfos;
+ final int numFooters = footers.size();
+ for (int i = 0; i < numFooters; i++) {
+ if (child == footers.get(i).view) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Obtain the view and add it to our list of children. The view can be made
* fresh, converted from an unused view, or used as is if it was in the
* recycle bin.