summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/animation/ValueAnimator.java85
-rw-r--r--core/java/android/app/ActivityManagerNative.java18
-rw-r--r--core/java/android/app/ApplicationErrorReport.java18
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java16
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java4
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java99
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java2
-rw-r--r--core/java/android/bluetooth/IBluetoothManager.aidl4
-rwxr-xr-xcore/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl30
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java38
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java2
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java2
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareImpl.java64
-rw-r--r--core/java/android/net/ConnectivityManager.java14
-rw-r--r--core/java/android/os/BatteryStats.java70
-rw-r--r--core/java/android/provider/Settings.java12
-rw-r--r--core/java/android/text/StaticLayout.java8
-rw-r--r--core/java/android/text/util/Linkify.java4
-rw-r--r--core/java/android/util/Log.java5
-rw-r--r--core/java/android/util/Slog.java7
-rw-r--r--core/java/android/view/Window.java2
-rw-r--r--core/java/android/view/WindowManager.java7
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl1
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java147
-rw-r--r--core/java/com/android/server/backup/SystemBackupAgent.java10
27 files changed, 576 insertions, 98 deletions
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index e18aa5c..8b70ae6 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -114,6 +114,15 @@ public class ValueAnimator extends Animator {
private boolean mPlayingBackwards = false;
/**
+ * Flag to indicate whether this animator is playing in reverse mode, specifically
+ * by being started or interrupted by a call to reverse(). This flag is different than
+ * mPlayingBackwards, which indicates merely whether the current iteration of the
+ * animator is playing in reverse. It is used in corner cases to determine proper end
+ * behavior.
+ */
+ private boolean mReversing;
+
+ /**
* This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the
* repeatCount (if repeatCount!=INFINITE), the animation ends
*/
@@ -545,21 +554,51 @@ public class ValueAnimator extends Animator {
* Sets the position of the animation to the specified fraction. This fraction should
* be between 0 and the total fraction of the animation, including any repetition. That is,
* a fraction of 0 will position the animation at the beginning, a value of 1 at the end,
- * and a value of 2 at the beginning of a reversing animator that repeats once. If
+ * and a value of 2 at the end of a reversing animator that repeats once. If
* the animation has not yet been started, then it will not advance forward after it is
* set to this fraction; it will simply set the fraction to this value and perform any
* appropriate actions based on that fraction. If the animation is already running, then
* setCurrentFraction() will set the current fraction to this value and continue
- * playing from that point.
+ * playing from that point. {@link Animator.AnimatorListener} events are not called
+ * due to changing the fraction; those events are only processed while the animation
+ * is running.
*
- * @param fraction The fraction to which the animation is advanced or rewound.
+ * @param fraction The fraction to which the animation is advanced or rewound. Values
+ * outside the range of 0 to the maximum fraction for the animator will be clamped to
+ * the correct range.
*/
public void setCurrentFraction(float fraction) {
initAnimation();
+ if (fraction < 0) {
+ fraction = 0;
+ }
+ int iteration = (int) fraction;
+ if (fraction == 1) {
+ iteration -= 1;
+ } else if (fraction > 1) {
+ if (iteration < (mRepeatCount + 1) || mRepeatCount == INFINITE) {
+ if (mRepeatMode == REVERSE) {
+ mPlayingBackwards = (iteration % 2) != 0;
+ }
+ fraction = fraction % 1f;
+ } else {
+ fraction = 1;
+ iteration -= 1;
+ }
+ } else {
+ mPlayingBackwards = mReversing;
+ }
+ mCurrentIteration = iteration;
+ long seekTime = (long) (mDuration * fraction);
+ long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ mStartTime = currentTime - seekTime;
if (mPlayingState != RUNNING) {
mSeekFraction = fraction;
mPlayingState = SEEKED;
}
+ if (mPlayingBackwards) {
+ fraction = 1f - fraction;
+ }
animateValue(fraction);
}
@@ -962,8 +1001,30 @@ public class ValueAnimator extends Animator {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+ mReversing = playBackwards;
mPlayingBackwards = playBackwards;
- mCurrentIteration = 0;
+ if (playBackwards && mSeekFraction != -1) {
+ if (mSeekFraction == 0 && mCurrentIteration == 0) {
+ // special case: reversing from seek-to-0 should act as if not seeked at all
+ mSeekFraction = 0;
+ } else if (mRepeatCount == INFINITE) {
+ mSeekFraction = 1 - (mSeekFraction % 1);
+ } else {
+ mSeekFraction = 1 + mRepeatCount - (mCurrentIteration + mSeekFraction);
+ }
+ mCurrentIteration = (int) mSeekFraction;
+ mSeekFraction = mSeekFraction % 1;
+ }
+ if (mCurrentIteration > 0 && mRepeatMode == REVERSE &&
+ (mCurrentIteration < (mRepeatCount + 1) || mRepeatCount == INFINITE)) {
+ // if we were seeked to some other iteration in a reversing animator,
+ // figure out the correct direction to start playing based on the iteration
+ if (playBackwards) {
+ mPlayingBackwards = (mCurrentIteration % 2) == 0;
+ } else {
+ mPlayingBackwards = (mCurrentIteration % 2) != 0;
+ }
+ }
int prevPlayingState = mPlayingState;
mPlayingState = STOPPED;
mStarted = true;
@@ -1071,6 +1132,7 @@ public class ValueAnimator extends Animator {
long currentPlayTime = currentTime - mStartTime;
long timeLeft = mDuration - currentPlayTime;
mStartTime = currentTime - timeLeft;
+ mReversing = !mReversing;
} else if (mStarted) {
end();
} else {
@@ -1113,6 +1175,8 @@ public class ValueAnimator extends Animator {
mStarted = false;
mStartListenersCalled = false;
mPlayingBackwards = false;
+ mReversing = false;
+ mCurrentIteration = 0;
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
System.identityHashCode(this));
@@ -1201,8 +1265,16 @@ public class ValueAnimator extends Animator {
case RUNNING:
case SEEKED:
float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
+ if (mDuration == 0 && mRepeatCount != INFINITE) {
+ // Skip to the end
+ mCurrentIteration = mRepeatCount;
+ if (!mReversing) {
+ mPlayingBackwards = false;
+ }
+ }
if (fraction >= 1f) {
- if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
+ if (mCurrentIteration < mRepeatCount ||
+ (mRepeatCount == INFINITE && mDuration != 0)) {
// Time to repeat
if (mListeners != null) {
int numListeners = mListeners.size();
@@ -1213,7 +1285,7 @@ public class ValueAnimator extends Animator {
if (mRepeatMode == REVERSE) {
mPlayingBackwards = !mPlayingBackwards;
}
- mCurrentIteration += (int)fraction;
+ mCurrentIteration += (int) fraction;
fraction = fraction % 1f;
mStartTime += mDuration;
} else {
@@ -1313,6 +1385,7 @@ public class ValueAnimator extends Animator {
}
anim.mSeekFraction = -1;
anim.mPlayingBackwards = false;
+ anim.mReversing = false;
anim.mCurrentIteration = 0;
anim.mInitialized = false;
anim.mPlayingState = STOPPED;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 06a26ec..e8d08b8 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2363,6 +2363,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
+
+ case SYSTEM_BACKUP_RESTORED: {
+ data.enforceInterface(IActivityManager.descriptor);
+ systemBackupRestored();
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -5458,5 +5465,16 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
+ @Override
+ public void systemBackupRestored() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(SYSTEM_BACKUP_RESTORED, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 49ab7c1..6c2511e 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -168,10 +168,20 @@ public class ApplicationErrorReport implements Parcelable {
PackageManager pm = context.getPackageManager();
// look for receiver in the installer package
- String candidate = pm.getInstallerPackageName(packageName);
- ComponentName result = getErrorReportReceiver(pm, packageName, candidate);
- if (result != null) {
- return result;
+ String candidate = null;
+ ComponentName result = null;
+
+ try {
+ candidate = pm.getInstallerPackageName(packageName);
+ } catch (IllegalArgumentException e) {
+ // the package could already removed
+ }
+
+ if (candidate != null) {
+ result = getErrorReportReceiver(pm, packageName, candidate);
+ if (result != null) {
+ return result;
+ }
}
// if the error app is on the system image, look for system apps
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1ccbd27..e505d69 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -469,6 +469,8 @@ public interface IActivityManager extends IInterface {
public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException;
public void notifyEnterAnimationComplete(IBinder token) throws RemoteException;
+ public void systemBackupRestored() throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -790,4 +792,5 @@ public interface IActivityManager extends IInterface {
int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242;
+ int SYSTEM_BACKUP_RESTORED = IBinder.FIRST_CALL_TRANSACTION+243;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4753099..ead89b3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -504,6 +504,22 @@ public class DevicePolicyManager {
}
return false;
}
+ /**
+ * Return true if the given administrator component is currently being removed
+ * for the user.
+ * @hide
+ */
+ public boolean isRemovingAdmin(ComponentName who, int userId) {
+ if (mService != null) {
+ try {
+ return mService.isRemovingAdmin(who, userId);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return false;
+ }
+
/**
* Return a list of all currently active device administrator's component
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d144ae8..0ca60c0 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -196,4 +196,6 @@ interface IDevicePolicyManager {
void setAutoTimeRequired(in ComponentName who, int userHandle, boolean required);
boolean getAutoTimeRequired();
+
+ boolean isRemovingAdmin(in ComponentName adminReceiver, int userHandle);
}
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index c203a8e..ea2dca0 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -928,7 +928,7 @@ public final class BluetoothGatt implements BluetoothProfile {
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
- if (mService == null || mClientIf == 0) return false;
+ if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
BluetoothGattService service = characteristic.getService();
if (service == null) return false;
@@ -1015,7 +1015,7 @@ public final class BluetoothGatt implements BluetoothProfile {
*/
public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
- if (mService == null || mClientIf == 0) return false;
+ if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false;
BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
if (characteristic == null) return false;
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 353f0fb..546a50e 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -20,9 +20,10 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
@@ -221,11 +222,14 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
public static final int STATE_AUDIO_CONNECTED = 12;
+ private static final int MESSAGE_HEADSET_SERVICE_CONNECTED = 100;
+ private static final int MESSAGE_HEADSET_SERVICE_DISCONNECTED = 101;
private Context mContext;
private ServiceListener mServiceListener;
private IBluetoothHeadset mService;
private BluetoothAdapter mAdapter;
+ private boolean mIsClosed;
final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
@@ -233,14 +237,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
if (!up) {
if (VDBG) Log.d(TAG,"Unbinding service...");
- synchronized (mConnection) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG,"",re);
- }
- }
+ doUnbind();
} else {
synchronized (mConnection) {
try {
@@ -263,6 +260,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
mContext = context;
mServiceListener = l;
mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mIsClosed = false;
IBluetoothManager mgr = mAdapter.getBluetoothManager();
if (mgr != null) {
@@ -277,15 +275,26 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
boolean doBind() {
- Intent intent = new Intent(IBluetoothHeadset.class.getName());
- ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
- intent.setComponent(comp);
- if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- android.os.Process.myUserHandle())) {
- Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
- return false;
+ try {
+ return mAdapter.getBluetoothManager().bindBluetoothProfileService(
+ BluetoothProfile.HEADSET, mConnection);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to bind HeadsetService", e);
+ }
+ return false;
+ }
+
+ void doUnbind() {
+ synchronized (mConnection) {
+ if (mService != null) {
+ try {
+ mAdapter.getBluetoothManager().unbindBluetoothProfileService(
+ BluetoothProfile.HEADSET, mConnection);
+ } catch (RemoteException e) {
+ Log.e(TAG,"Unable to unbind HeadsetService", e);
+ }
+ }
}
- return true;
}
/**
@@ -305,18 +314,8 @@ public final class BluetoothHeadset implements BluetoothProfile {
Log.e(TAG,"",e);
}
}
-
- synchronized (mConnection) {
- if (mService != null) {
- try {
- mService = null;
- mContext.unbindService(mConnection);
- } catch (Exception re) {
- Log.e(TAG,"",re);
- }
- }
- }
- mServiceListener = null;
+ mIsClosed = true;
+ doUnbind();
}
/**
@@ -930,21 +929,21 @@ public final class BluetoothHeadset implements BluetoothProfile {
return false;
}
- private final ServiceConnection mConnection = new ServiceConnection() {
+ private final IBluetoothProfileServiceConnection mConnection
+ = new IBluetoothProfileServiceConnection.Stub() {
+ @Override
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothHeadset.Stub.asInterface(service);
-
- if (mServiceListener != null) {
- mServiceListener.onServiceConnected(BluetoothProfile.HEADSET, BluetoothHeadset.this);
- }
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_HEADSET_SERVICE_CONNECTED));
}
+ @Override
public void onServiceDisconnected(ComponentName className) {
if (DBG) Log.d(TAG, "Proxy object disconnected");
mService = null;
- if (mServiceListener != null) {
- mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
- }
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_HEADSET_SERVICE_DISCONNECTED));
}
};
@@ -968,4 +967,28 @@ public final class BluetoothHeadset implements BluetoothProfile {
private static void log(String msg) {
Log.d(TAG, msg);
}
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_HEADSET_SERVICE_CONNECTED: {
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.HEADSET,
+ BluetoothHeadset.this);
+ }
+ break;
+ }
+ case MESSAGE_HEADSET_SERVICE_DISCONNECTED: {
+ if (mServiceListener != null) {
+ mServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
+ }
+ if (mIsClosed){
+ mServiceListener = null;
+ }
+ break;
+ }
+ }
+ }
+ };
}
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 1e22eb3..194a53e 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -66,6 +66,8 @@ public final class BluetoothUuid {
ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BNEP =
ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid PBAP_PCE =
+ ParcelUuid.fromString("0000112e-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid PBAP_PSE =
ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid MAP =
diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl
index 493d2f8..7411d3f 100644
--- a/core/java/android/bluetooth/IBluetoothManager.aidl
+++ b/core/java/android/bluetooth/IBluetoothManager.aidl
@@ -19,6 +19,7 @@ package android.bluetooth;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManagerCallback;
+import android.bluetooth.IBluetoothProfileServiceConnection;
import android.bluetooth.IBluetoothStateChangeCallback;
/**
@@ -38,6 +39,9 @@ interface IBluetoothManager
boolean disable(boolean persist);
IBluetoothGatt getBluetoothGatt();
+ boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
+ void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);
+
String getAddress();
String getName();
}
diff --git a/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl b/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
new file mode 100755
index 0000000..96c59e2
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothProfileServiceConnection.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.content.ComponentName;
+import android.os.IBinder;
+
+/**
+ * Callback for bluetooth profile connections.
+ *
+ * {@hide}
+ */
+interface IBluetoothProfileServiceConnection {
+ void onServiceConnected(in ComponentName comp, in IBinder service);
+ void onServiceDisconnected(in ComponentName comp);
+}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 999de8a..1b10858 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1648,11 +1648,41 @@ public abstract class CameraMetadata<TKey> {
public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17;
/**
- * <p>Turn on custom high dynamic range (HDR) mode.</p>
- * <p>This is intended for LEGACY mode devices only;
- * HAL3+ camera devices should not implement this mode.</p>
+ * <p>Turn on a device-specific high dynamic range (HDR) mode.</p>
+ * <p>In this scene mode, the camera device captures images
+ * that keep a larger range of scene illumination levels
+ * visible in the final image. For example, when taking a
+ * picture of a object in front of a bright window, both
+ * the object and the scene through the window may be
+ * visible when using HDR mode, while in normal AUTO mode,
+ * one or the other may be poorly exposed. As a tradeoff,
+ * HDR mode generally takes much longer to capture a single
+ * image, has no user control, and may have other artifacts
+ * depending on the HDR method used.</p>
+ * <p>Therefore, HDR captures operate at a much slower rate
+ * than regular captures.</p>
+ * <p>In this mode, on LIMITED or FULL devices, when a request
+ * is made with a {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} of
+ * STILL_CAPTURE, the camera device will capture an image
+ * using a high dynamic range capture technique. On LEGACY
+ * devices, captures that target a JPEG-format output will
+ * be captured with HDR, and the capture intent is not
+ * relevant.</p>
+ * <p>The HDR capture may involve the device capturing a burst
+ * of images internally and combining them into one, or it
+ * may involve the device using specialized high dynamic
+ * range capture hardware. In all cases, a single image is
+ * produced in response to a capture request submitted
+ * while in HDR mode.</p>
+ * <p>Since substantial post-processing is generally needed to
+ * produce an HDR image, only YUV and JPEG outputs are
+ * supported for LIMITED/FULL device HDR captures, and only
+ * JPEG outputs are supported for LEGACY HDR
+ * captures. Using a RAW output for HDR capture is not
+ * supported.</p>
+ *
+ * @see CaptureRequest#CONTROL_CAPTURE_INTENT
* @see CaptureRequest#CONTROL_SCENE_MODE
- * @hide
*/
public static final int CONTROL_SCENE_MODE_HDR = 18;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index e89a402..0849df8 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1294,6 +1294,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <li>{@link #CONTROL_SCENE_MODE_CANDLELIGHT CANDLELIGHT}</li>
* <li>{@link #CONTROL_SCENE_MODE_BARCODE BARCODE}</li>
* <li>{@link #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}</li>
+ * <li>{@link #CONTROL_SCENE_MODE_HDR HDR}</li>
* </ul></p>
* <p><b>Available values for this device:</b><br>
* {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}</p>
@@ -1322,6 +1323,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* @see #CONTROL_SCENE_MODE_CANDLELIGHT
* @see #CONTROL_SCENE_MODE_BARCODE
* @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
+ * @see #CONTROL_SCENE_MODE_HDR
*/
@PublicKey
public static final Key<Integer> CONTROL_SCENE_MODE =
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 2c3b85f..1396940 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1910,6 +1910,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <li>{@link #CONTROL_SCENE_MODE_CANDLELIGHT CANDLELIGHT}</li>
* <li>{@link #CONTROL_SCENE_MODE_BARCODE BARCODE}</li>
* <li>{@link #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}</li>
+ * <li>{@link #CONTROL_SCENE_MODE_HDR HDR}</li>
* </ul></p>
* <p><b>Available values for this device:</b><br>
* {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}</p>
@@ -1938,6 +1939,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* @see #CONTROL_SCENE_MODE_CANDLELIGHT
* @see #CONTROL_SCENE_MODE_BARCODE
* @see #CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO
+ * @see #CONTROL_SCENE_MODE_HDR
*/
@PublicKey
public static final Key<Integer> CONTROL_SCENE_MODE =
diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java
index 5c7a8da..6e5d064 100644
--- a/core/java/android/hardware/location/GeofenceHardwareImpl.java
+++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java
@@ -23,6 +23,7 @@ import android.location.IGpsGeofenceHardware;
import android.location.Location;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IInterface;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -30,6 +31,7 @@ import android.util.Log;
import android.util.SparseArray;
import java.util.ArrayList;
+import java.util.Iterator;
/**
* This class manages the geofences which are handled by hardware.
@@ -558,8 +560,34 @@ public final class GeofenceHardwareImpl {
try {
callback.onGeofenceRemove(geofenceId, msg.arg2);
} catch (RemoteException e) {}
+ IBinder callbackBinder = callback.asBinder();
+ boolean callbackInUse = false;
synchronized (mGeofences) {
mGeofences.remove(geofenceId);
+ // Check if the underlying binder is still useful for other geofences,
+ // if no, unlink the DeathRecipient to avoid memory leak.
+ for (int i = 0; i < mGeofences.size(); i++) {
+ if (mGeofences.valueAt(i).asBinder() == callbackBinder) {
+ callbackInUse = true;
+ break;
+ }
+ }
+ }
+
+ // Remove the reaper associated with this binder.
+ if (!callbackInUse) {
+ for (Iterator<Reaper> iterator = mReapers.iterator();
+ iterator.hasNext();) {
+ Reaper reaper = iterator.next();
+ if (reaper.mCallback != null &&
+ reaper.mCallback.asBinder() == callbackBinder) {
+ iterator.remove();
+ reaper.unlinkToDeath();
+ if (DEBUG) Log.d(TAG, String.format("Removed reaper %s " +
+ "because binder %s is no longer needed.",
+ reaper, callbackBinder));
+ }
+ }
}
}
releaseWakeLock();
@@ -803,8 +831,9 @@ public final class GeofenceHardwareImpl {
@Override
public int hashCode() {
int result = 17;
- result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0);
- result = 31 * result + (mMonitorCallback != null ? mMonitorCallback.hashCode() : 0);
+ result = 31 * result + (mCallback != null ? mCallback.asBinder().hashCode() : 0);
+ result = 31 * result + (mMonitorCallback != null
+ ? mMonitorCallback.asBinder().hashCode() : 0);
result = 31 * result + mMonitoringType;
return result;
}
@@ -815,9 +844,38 @@ public final class GeofenceHardwareImpl {
if (obj == this) return true;
Reaper rhs = (Reaper) obj;
- return rhs.mCallback == mCallback && rhs.mMonitorCallback == mMonitorCallback &&
+ return binderEquals(rhs.mCallback, mCallback) &&
+ binderEquals(rhs.mMonitorCallback, mMonitorCallback) &&
rhs.mMonitoringType == mMonitoringType;
}
+
+ /**
+ * Compares the underlying Binder of the given two IInterface objects and returns true if
+ * they equals. null values are accepted.
+ */
+ private boolean binderEquals(IInterface left, IInterface right) {
+ if (left == null) {
+ return right == null;
+ } else {
+ return right == null ? false : left.asBinder() == right.asBinder();
+ }
+ }
+
+ /**
+ * Unlinks this DeathRecipient.
+ */
+ private boolean unlinkToDeath() {
+ if (mMonitorCallback != null) {
+ return mMonitorCallback.asBinder().unlinkToDeath(this, 0);
+ } else if (mCallback != null) {
+ return mCallback.asBinder().unlinkToDeath(this, 0);
+ }
+ return true;
+ }
+
+ private boolean callbackEquals(IGeofenceHardwareCallback cb) {
+ return mCallback != null && mCallback.asBinder() == cb.asBinder();
+ }
}
int getAllowedResolutionLevel(int pid, int uid) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4fe418a..4215f20 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -100,7 +100,7 @@ public class ConnectivityManager {
/**
* Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
- * historic {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
+ * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
*
* @hide
*/
@@ -428,6 +428,18 @@ public class ConnectivityManager {
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
/**
+ * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
+ * milliseconds. This was introduced because IPv6 routes seem to take a
+ * moment to settle - trying network activity before the routes are adjusted
+ * can lead to packets using the wrong interface or having the wrong IP address.
+ * This delay is a bit crude, but in the future hopefully we will have kernel
+ * notifications letting us know when it's safe to use the new network.
+ *
+ * @hide
+ */
+ public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
+
+ /**
* @hide
*/
public final static int REQUEST_ID_UNSET = 0;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 11fc69e..5fd697a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -459,6 +459,20 @@ public abstract class BatteryStats implements Parcelable {
public abstract int getStarts(int which);
/**
+ * Returns the number of times the process has crashed.
+ *
+ * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ */
+ public abstract int getNumCrashes(int which);
+
+ /**
+ * Returns the number of times the process has ANRed.
+ *
+ * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ */
+ public abstract int getNumAnrs(int which);
+
+ /**
* Returns the cpu time spent in microseconds while the process was in the foreground.
* @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
* @return foreground cpu time in microseconds
@@ -694,8 +708,10 @@ public abstract class BatteryStats implements Parcelable {
public static final int EVENT_USER_RUNNING = 0x0007;
// Events for foreground user.
public static final int EVENT_USER_FOREGROUND = 0x0008;
+ // Events for connectivity changed.
+ public static final int EVENT_CONNECTIVITY_CHANGED = 0x0009;
// Number of event types.
- public static final int EVENT_COUNT = 0x0009;
+ public static final int EVENT_COUNT = 0x000a;
// Mask to extract out only the type part of the event.
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
@@ -1107,6 +1123,13 @@ public abstract class BatteryStats implements Parcelable {
public abstract int getLowPowerModeEnabledCount(int which);
/**
+ * Returns the number of times that connectivity state changed.
+ *
+ * {@hide}
+ */
+ public abstract int getNumConnectivityChange(int which);
+
+ /**
* Returns the time in microseconds that the phone has been on while the device was
* running on battery.
*
@@ -1306,11 +1329,11 @@ public abstract class BatteryStats implements Parcelable {
};
public static final String[] HISTORY_EVENT_NAMES = new String[] {
- "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg"
+ "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn"
};
public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
- "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf"
+ "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn"
};
/**
@@ -1871,6 +1894,7 @@ public abstract class BatteryStats implements Parcelable {
final long screenOnTime = getScreenOnTime(rawRealtime, which);
final long interactiveTime = getInteractiveTime(rawRealtime, which);
final long lowPowerModeEnabledTime = getLowPowerModeEnabledTime(rawRealtime, which);
+ final int connChanges = getNumConnectivityChange(which);
final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
final long wifiOnTime = getWifiOnTime(rawRealtime, which);
final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
@@ -1941,7 +1965,7 @@ public abstract class BatteryStats implements Parcelable {
fullWakeLockTimeTotal / 1000, partialWakeLockTimeTotal / 1000,
0 /*legacy input event count*/, getMobileRadioActiveTime(rawRealtime, which) / 1000,
getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000,
- lowPowerModeEnabledTime / 1000);
+ lowPowerModeEnabledTime / 1000, connChanges);
// Dump screen brightness stats
Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
@@ -2271,12 +2295,14 @@ public abstract class BatteryStats implements Parcelable {
final long userMillis = ps.getUserTime(which) * 10;
final long systemMillis = ps.getSystemTime(which) * 10;
final long foregroundMillis = ps.getForegroundTime(which) * 10;
- final long starts = ps.getStarts(which);
+ final int starts = ps.getStarts(which);
+ final int numCrashes = ps.getNumCrashes(which);
+ final int numAnrs = ps.getNumAnrs(which);
if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
- || starts != 0) {
+ || starts != 0 || numAnrs != 0 || numCrashes != 0) {
dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
- systemMillis, foregroundMillis, starts);
+ systemMillis, foregroundMillis, starts, numAnrs, numCrashes);
}
}
}
@@ -2457,6 +2483,11 @@ public abstract class BatteryStats implements Parcelable {
sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
sb.append(") "); sb.append(getPhoneOnCount(which));
}
+ int connChanges = getNumConnectivityChange(which);
+ if (connChanges != 0) {
+ pw.print(prefix);
+ pw.print(" Connectivity changes: "); pw.println(connChanges);
+ }
// Calculate wakelock times across all uids.
long fullWakeLockTimeTotalMicros = 0;
@@ -3273,11 +3304,13 @@ public abstract class BatteryStats implements Parcelable {
systemTime = ps.getSystemTime(which);
foregroundTime = ps.getForegroundTime(which);
starts = ps.getStarts(which);
+ final int numCrashes = ps.getNumCrashes(which);
+ final int numAnrs = ps.getNumAnrs(which);
numExcessive = which == STATS_SINCE_CHARGED
? ps.countExcessivePowers() : 0;
if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
- || numExcessive != 0) {
+ || numExcessive != 0 || numCrashes != 0 || numAnrs != 0) {
sb.setLength(0);
sb.append(prefix); sb.append(" Proc ");
sb.append(ent.getKey()); sb.append(":\n");
@@ -3285,9 +3318,26 @@ public abstract class BatteryStats implements Parcelable {
formatTime(sb, userTime); sb.append("usr + ");
formatTime(sb, systemTime); sb.append("krn ; ");
formatTime(sb, foregroundTime); sb.append("fg");
- if (starts != 0) {
+ if (starts != 0 || numCrashes != 0 || numAnrs != 0) {
sb.append("\n"); sb.append(prefix); sb.append(" ");
- sb.append(starts); sb.append(" proc starts");
+ boolean hasOne = false;
+ if (starts != 0) {
+ hasOne = true;
+ sb.append(starts); sb.append(" starts");
+ }
+ if (numCrashes != 0) {
+ if (hasOne) {
+ sb.append(", ");
+ }
+ hasOne = true;
+ sb.append(numCrashes); sb.append(" crashes");
+ }
+ if (numAnrs != 0) {
+ if (hasOne) {
+ sb.append(", ");
+ }
+ sb.append(numAnrs); sb.append(" anrs");
+ }
}
pw.println(sb.toString());
for (int e=0; e<numExcessive; e++) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3bc74ae..0062eb2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4349,6 +4349,16 @@ public final class Settings {
Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS;
/**
+ * The number of milliseconds to hold on to a PendingIntent based request. This delay gives
+ * the receivers of the PendingIntent an opportunity to make a new network request before
+ * the Network satisfying the request is potentially removed.
+ *
+ * @hide
+ */
+ public static final String CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS =
+ "connectivity_release_pending_intent_delay_ms";
+
+ /**
* Whether background data usage is allowed.
*
* @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH},
@@ -6118,7 +6128,7 @@ public final class Settings {
/**
* The number of milliseconds to delay before sending out
- * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcasts. Ignored.
+ * {@link ConnectivityManager#CONNECTIVITY_ACTION} broadcasts.
*
* @hide
*/
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 02297e3..74b7b69 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -416,7 +416,11 @@ public class StaticLayout extends Layout {
currentTextWidth = widths[here - paraStart];
}
- v = out(source, here, endPos,
+ int ellipseEnd = endPos;
+ if (mMaximumVisibleLineCount == 1 && ellipsize == TextUtils.TruncateAt.MIDDLE) {
+ ellipseEnd = paraEnd;
+ }
+ v = out(source, here, ellipseEnd,
above, below, top, bottom,
v, spacingmult, spacingadd, chooseHt,chooseHtv, fm, hasTabOrEmoji,
needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad,
@@ -704,7 +708,7 @@ public class StaticLayout extends Layout {
int left = 0, right = len;
float ravail = (avail - ellipsisWidth) / 2;
- for (right = len; right >= 0; right--) {
+ for (right = len; right > 0; right--) {
float w = widths[right - 1 + lineStart - widthStart];
if (w + rsum > ravail) {
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index c1341e1..14be269 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -402,7 +402,7 @@ public class Linkify {
}
boolean hasPrefix = false;
-
+
for (int i = 0; i < prefixes.length; i++) {
if (url.regionMatches(true, 0, prefixes[i], 0,
prefixes[i].length())) {
@@ -450,7 +450,7 @@ public class Linkify {
private static final void gatherTelLinks(ArrayList<LinkSpec> links, Spannable s) {
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Iterable<PhoneNumberMatch> matches = phoneUtil.findNumbers(s.toString(),
- Locale.getDefault().getCountry(), Leniency.POSSIBLE, Long.MAX_VALUE);
+ Locale.getDefault().getCountry(), Leniency.VALID, Long.MAX_VALUE);
for (PhoneNumberMatch match : matches) {
LinkSpec spec = new LinkSpec();
spec.url = "tel:" + PhoneNumberUtils.normalizeNumber(match.rawString());
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index a9b3571..121485a 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -295,6 +295,11 @@ public final class Log {
return bytes;
}
+ static void wtfQuiet(int logId, String tag, String msg, boolean system) {
+ TerribleFailure what = new TerribleFailure(msg, null);
+ sWtfHandler.onTerribleFailure(tag, what, system);
+ }
+
/**
* Sets the terrible failure handler, for testing.
*
diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java
index e92b846..58a2703 100644
--- a/core/java/android/util/Slog.java
+++ b/core/java/android/util/Slog.java
@@ -83,6 +83,13 @@ public final class Slog {
}
/**
+ * Like {@link #wtf(String, String)}, but does not output anything to the log.
+ */
+ public static void wtfQuiet(String tag, String msg) {
+ Log.wtfQuiet(Log.LOG_ID_SYSTEM, tag, msg, true);
+ }
+
+ /**
* Like {@link Log#wtfStack(String, String)}, but will never cause the caller to crash, and
* will always be handled asynchronously. Primarily for use by coding running within
* the system process.
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2e5c1e0..6944c53 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -364,7 +364,7 @@ public abstract class Window {
/**
* This hook is called whenever the window focus changes. See
* {@link View#onWindowFocusChanged(boolean)
- * View.onWindowFocusChanged(boolean)} for more information.
+ * View.onWindowFocusChangedNotLocked(boolean)} for more information.
*
* @param hasFocus Whether the window now has focus.
*/
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f4f047e..094a8a1 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1102,6 +1102,13 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_KEYGUARD = 0x00000400;
/**
+ * Flag that prevents the wallpaper behind the current window from receiving touch events.
+ *
+ * {@hide}
+ */
+ public static final int PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS = 0x00000800;
+
+ /**
* Control flags that are private to the platform.
* @hide
*/
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 55b3ecc..87b6ed7 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -77,6 +77,7 @@ interface IBatteryStats {
void noteScreenBrightness(int brightness);
void noteUserActivity(int uid, int event);
void noteInteractive(boolean interactive);
+ void noteConnectivityChanged(int type, String extra);
void noteMobileRadioPowerState(int powerState, long timestampNs);
void notePhoneOn();
void notePhoneOff();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 0dfb11a..8ceee20 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -94,7 +94,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 115 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 116 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -374,6 +374,10 @@ public final class BatteryStatsImpl extends BatteryStats {
private int mPhoneServiceStateRaw = -1;
private int mPhoneSimStateRaw = -1;
+ private int mNumConnectivityChange;
+ private int mLoadedNumConnectivityChange;
+ private int mUnpluggedNumConnectivityChange;
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
@@ -2540,6 +2544,22 @@ public final class BatteryStatsImpl extends BatteryStats {
addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
}
+ public void noteProcessCrashLocked(String name, int uid) {
+ uid = mapUid(uid);
+ if (isOnBattery()) {
+ Uid u = getUidStatsLocked(uid);
+ u.getProcessStatsLocked(name).incNumCrashesLocked();
+ }
+ }
+
+ public void noteProcessAnrLocked(String name, int uid) {
+ uid = mapUid(uid);
+ if (isOnBattery()) {
+ Uid u = getUidStatsLocked(uid);
+ u.getProcessStatsLocked(name).incNumAnrsLocked();
+ }
+ }
+
public void noteProcessStateLocked(String name, int uid, int state) {
uid = mapUid(uid);
final long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -3109,6 +3129,14 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ public void noteConnectivityChangedLocked(int type, String extra) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
+ extra, type);
+ mNumConnectivityChange++;
+ }
+
public void noteMobileRadioPowerState(int powerState, long timestampNs) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
@@ -3965,6 +3993,16 @@ public final class BatteryStatsImpl extends BatteryStats {
return mLowPowerModeEnabledTimer.getCountLocked(which);
}
+ @Override public int getNumConnectivityChange(int which) {
+ int val = mNumConnectivityChange;
+ if (which == STATS_CURRENT) {
+ val -= mLoadedNumConnectivityChange;
+ } else if (which == STATS_SINCE_UNPLUGGED) {
+ val -= mUnpluggedNumConnectivityChange;
+ }
+ return val;
+ }
+
@Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
}
@@ -5374,6 +5412,16 @@ public final class BatteryStatsImpl extends BatteryStats {
int mStarts;
/**
+ * Number of times the process has crashed.
+ */
+ int mNumCrashes;
+
+ /**
+ * Number of times the process has had an ANR.
+ */
+ int mNumAnrs;
+
+ /**
* The amount of user time loaded from a previous save.
*/
long mLoadedUserTime;
@@ -5394,24 +5442,14 @@ public final class BatteryStatsImpl extends BatteryStats {
int mLoadedStarts;
/**
- * The amount of user time loaded from the previous run.
- */
- long mLastUserTime;
-
- /**
- * The amount of system time loaded from the previous run.
- */
- long mLastSystemTime;
-
- /**
- * The amount of foreground time loaded from the previous run
+ * Number of times the process has crashed from a previous save.
*/
- long mLastForegroundTime;
+ int mLoadedNumCrashes;
/**
- * The number of times the process has started from the previous run.
+ * Number of times the process has had an ANR from a previous save.
*/
- int mLastStarts;
+ int mLoadedNumAnrs;
/**
* The amount of user time when last unplugged.
@@ -5434,6 +5472,16 @@ public final class BatteryStatsImpl extends BatteryStats {
int mUnpluggedStarts;
/**
+ * Number of times the process has crashed before unplugged.
+ */
+ int mUnpluggedNumCrashes;
+
+ /**
+ * Number of times the process has had an ANR before unplugged.
+ */
+ int mUnpluggedNumAnrs;
+
+ /**
* Current process state.
*/
int mProcessState = PROCESS_STATE_NONE;
@@ -5453,6 +5501,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mUnpluggedSystemTime = mSystemTime;
mUnpluggedForegroundTime = mForegroundTime;
mUnpluggedStarts = mStarts;
+ mUnpluggedNumCrashes = mNumCrashes;
+ mUnpluggedNumAnrs = mNumAnrs;
}
public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
@@ -5460,13 +5510,11 @@ public final class BatteryStatsImpl extends BatteryStats {
void reset() {
mUserTime = mSystemTime = mForegroundTime = 0;
- mStarts = 0;
+ mStarts = mNumCrashes = mNumAnrs = 0;
mLoadedUserTime = mLoadedSystemTime = mLoadedForegroundTime = 0;
- mLoadedStarts = 0;
- mLastUserTime = mLastSystemTime = mLastForegroundTime = 0;
- mLastStarts = 0;
+ mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
- mUnpluggedStarts = 0;
+ mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
for (int i = 0; i < mSpeedBins.length; i++) {
SamplingCounter c = mSpeedBins[i];
if (c != null) {
@@ -5565,14 +5613,20 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(mSystemTime);
out.writeLong(mForegroundTime);
out.writeInt(mStarts);
+ out.writeInt(mNumCrashes);
+ out.writeInt(mNumAnrs);
out.writeLong(mLoadedUserTime);
out.writeLong(mLoadedSystemTime);
out.writeLong(mLoadedForegroundTime);
out.writeInt(mLoadedStarts);
+ out.writeInt(mLoadedNumCrashes);
+ out.writeInt(mLoadedNumAnrs);
out.writeLong(mUnpluggedUserTime);
out.writeLong(mUnpluggedSystemTime);
out.writeLong(mUnpluggedForegroundTime);
out.writeInt(mUnpluggedStarts);
+ out.writeInt(mUnpluggedNumCrashes);
+ out.writeInt(mUnpluggedNumAnrs);
out.writeInt(mSpeedBins.length);
for (int i = 0; i < mSpeedBins.length; i++) {
@@ -5593,18 +5647,20 @@ public final class BatteryStatsImpl extends BatteryStats {
mSystemTime = in.readLong();
mForegroundTime = in.readLong();
mStarts = in.readInt();
+ mNumCrashes = in.readInt();
+ mNumAnrs = in.readInt();
mLoadedUserTime = in.readLong();
mLoadedSystemTime = in.readLong();
mLoadedForegroundTime = in.readLong();
mLoadedStarts = in.readInt();
- mLastUserTime = 0;
- mLastSystemTime = 0;
- mLastForegroundTime = 0;
- mLastStarts = 0;
+ mLoadedNumCrashes = in.readInt();
+ mLoadedNumAnrs = in.readInt();
mUnpluggedUserTime = in.readLong();
mUnpluggedSystemTime = in.readLong();
mUnpluggedForegroundTime = in.readLong();
mUnpluggedStarts = in.readInt();
+ mUnpluggedNumCrashes = in.readInt();
+ mUnpluggedNumAnrs = in.readInt();
int bins = in.readInt();
int steps = getCpuSpeedSteps();
@@ -5635,6 +5691,14 @@ public final class BatteryStatsImpl extends BatteryStats {
mStarts++;
}
+ public void incNumCrashesLocked() {
+ mNumCrashes++;
+ }
+
+ public void incNumAnrsLocked() {
+ mNumAnrs++;
+ }
+
@Override
public boolean isActive() {
return mActive;
@@ -5684,6 +5748,28 @@ public final class BatteryStatsImpl extends BatteryStats {
return val;
}
+ @Override
+ public int getNumCrashes(int which) {
+ int val = mNumCrashes;
+ if (which == STATS_CURRENT) {
+ val -= mLoadedNumCrashes;
+ } else if (which == STATS_SINCE_UNPLUGGED) {
+ val -= mUnpluggedNumCrashes;
+ }
+ return val;
+ }
+
+ @Override
+ public int getNumAnrs(int which) {
+ int val = mNumAnrs;
+ if (which == STATS_CURRENT) {
+ val -= mLoadedNumAnrs;
+ } else if (which == STATS_SINCE_UNPLUGGED) {
+ val -= mUnpluggedNumAnrs;
+ }
+ return val;
+ }
+
/* Called by ActivityManagerService when CPU times are updated. */
public void addSpeedStepTimes(long[] values) {
for (int i = 0; i < mSpeedBins.length && i < values.length; i++) {
@@ -6647,6 +6733,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
mBluetoothStateTimer[i].reset(false);
}
+ mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
for (int i=0; i<mUidStats.size(); i++) {
if (mUidStats.valueAt(i).reset()) {
@@ -7861,6 +7948,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
}
+ mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
mFlashlightOn = false;
mFlashlightOnTimer.readSummaryFromParcelLocked(in);
@@ -8022,6 +8110,8 @@ public final class BatteryStatsImpl extends BatteryStats {
p.mSystemTime = p.mLoadedSystemTime = in.readLong();
p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
p.mStarts = p.mLoadedStarts = in.readInt();
+ p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
+ p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
int NSB = in.readInt();
if (NSB > 100) {
Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
@@ -8143,6 +8233,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
}
+ out.writeInt(mNumConnectivityChange);
mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
out.writeInt(mKernelWakelockStats.size());
@@ -8326,6 +8417,8 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(ps.mSystemTime);
out.writeLong(ps.mForegroundTime);
out.writeInt(ps.mStarts);
+ out.writeInt(ps.mNumCrashes);
+ out.writeInt(ps.mNumAnrs);
final int N = ps.mSpeedBins.length;
out.writeInt(N);
for (int i=0; i<N; i++) {
@@ -8444,6 +8537,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
null, mOnBatteryTimeBase, in);
}
+ mNumConnectivityChange = in.readInt();
+ mLoadedNumConnectivityChange = in.readInt();
+ mUnpluggedNumConnectivityChange = in.readInt();
mAudioOnNesting = 0;
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOnNesting = 0;
@@ -8588,6 +8684,9 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
}
+ out.writeInt(mNumConnectivityChange);
+ out.writeInt(mLoadedNumConnectivityChange);
+ out.writeInt(mUnpluggedNumConnectivityChange);
mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
out.writeInt(mDischargeUnplugLevel);
out.writeInt(mDischargePlugLevel);
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index ed7ce63..35a1a5a 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -17,6 +17,7 @@
package com.android.server.backup;
+import android.app.ActivityManagerNative;
import android.app.IWallpaperManager;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
@@ -186,4 +187,13 @@ public class SystemBackupAgent extends BackupAgentHelper {
}
}
}
+
+ @Override
+ public void onRestoreFinished() {
+ try {
+ ActivityManagerNative.getDefault().systemBackupRestored();
+ } catch (RemoteException e) {
+ // Not possible since this code is running in the system process.
+ }
+ }
}