summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/os/BatteryStats.java37
-rw-r--r--core/java/android/os/storage/IMountService.java53
-rw-r--r--core/java/android/os/storage/StorageManager.java12
-rw-r--r--core/java/android/service/carrier/CarrierConfigService.java4
-rw-r--r--core/java/android/service/carrier/CarrierMessagingService.java4
-rw-r--r--core/java/android/widget/DayPickerPagerAdapter.java9
-rw-r--r--core/java/android/widget/DayPickerView.java4
-rw-r--r--core/java/com/android/internal/app/PlatLogoActivity.java170
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java296
-rw-r--r--core/java/com/android/internal/os/CpuPowerCalculator.java70
-rw-r--r--core/java/com/android/internal/os/KernelCpuSpeedReader.java69
-rw-r--r--core/java/com/android/internal/os/KernelUidCpuTimeReader.java115
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java79
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java7
-rw-r--r--core/jni/android/graphics/NinePatch.cpp4
-rw-r--r--core/jni/android/graphics/NinePatchImpl.cpp3
-rw-r--r--core/res/AndroidManifest.xml16
-rw-r--r--core/res/res/drawable-nodpi/platlogo.xml41
-rw-r--r--core/res/res/drawable-nodpi/stat_sys_adb.xml7
-rw-r--r--core/res/res/values/strings.xml4
21 files changed, 543 insertions, 463 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 4dfe0de..5f515eb 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -425,6 +425,24 @@ public abstract class BatteryStats implements Parcelable {
public abstract long getMobileRadioActiveTime(int which);
public abstract int getMobileRadioActiveCount(int which);
+ /**
+ * Get the total cpu time (in microseconds) this UID had processes executing in userspace.
+ */
+ public abstract long getUserCpuTimeUs(int which);
+
+ /**
+ * Get the total cpu time (in microseconds) this UID had processes executing kernel syscalls.
+ */
+ public abstract long getSystemCpuTimeUs(int which);
+
+ /**
+ * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
+ * @param speedStep the index of the CPU speed. This is not the actual speed of the CPU.
+ * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ * @see BatteryStats#getCpuSpeedSteps()
+ */
+ public abstract long getTimeAtCpuSpeed(int step, int which);
+
public static abstract class Sensor {
/*
* FIXME: it's not correct to use this magic value because it
@@ -506,15 +524,6 @@ public abstract class BatteryStats implements Parcelable {
*/
public abstract long getForegroundTime(int which);
- /**
- * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
- * @param speedStep the index of the CPU speed. This is not the actual speed of the
- * CPU.
- * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
- * @see BatteryStats#getCpuSpeedSteps()
- */
- public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
-
public abstract int countExcessivePowers();
public abstract ExcessivePower getExcessivePower(int i);
@@ -3873,6 +3882,16 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ final long userCpuTimeUs = u.getUserCpuTimeUs(which);
+ final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
+ if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Total cpu time: ");
+ formatTimeMs(sb, (userCpuTimeUs + systemCpuTimeUs) / 1000);
+ pw.println(sb.toString());
+ }
+
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
= u.getProcessStats();
for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 2b058a8..e55ae99 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1005,6 +1005,22 @@ public interface IMountService extends IInterface {
}
@Override
+ public long benchmark(String volId) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(volId);
+ mRemote.transact(Stub.TRANSACTION_benchmark, _data, _reply, 0);
+ _reply.readException();
+ return _reply.readLong();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
public void partitionPublic(String diskId) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1113,6 +1129,22 @@ public interface IMountService extends IInterface {
}
@Override
+ public void setDebugFlags(int _flags, int _mask) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(_flags);
+ _data.writeInt(_mask);
+ mRemote.transact(Stub.TRANSACTION_setDebugFlags, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
public String getPrimaryStorageUuid() throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1257,6 +1289,9 @@ public interface IMountService extends IInterface {
static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58;
+ static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
+ static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
+
/**
* Cast an IBinder object into an IMountService interface, generating a
* proxy if needed.
@@ -1726,6 +1761,14 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
+ case TRANSACTION_benchmark: {
+ data.enforceInterface(DESCRIPTOR);
+ String volId = data.readString();
+ long res = benchmark(volId);
+ reply.writeNoException();
+ reply.writeLong(res);
+ return true;
+ }
case TRANSACTION_partitionPublic: {
data.enforceInterface(DESCRIPTOR);
String diskId = data.readString();
@@ -1778,6 +1821,14 @@ public interface IMountService extends IInterface {
reply.writeNoException();
return true;
}
+ case TRANSACTION_setDebugFlags: {
+ data.enforceInterface(DESCRIPTOR);
+ int _flags = data.readInt();
+ int _mask = data.readInt();
+ setDebugFlags(_flags, _mask);
+ reply.writeNoException();
+ return true;
+ }
case TRANSACTION_getPrimaryStorageUuid: {
data.enforceInterface(DESCRIPTOR);
String volumeUuid = getPrimaryStorageUuid();
@@ -2088,6 +2139,7 @@ public interface IMountService extends IInterface {
public void mount(String volId) throws RemoteException;
public void unmount(String volId) throws RemoteException;
public void format(String volId) throws RemoteException;
+ public long benchmark(String volId) throws RemoteException;
public void partitionPublic(String diskId) throws RemoteException;
public void partitionPrivate(String diskId) throws RemoteException;
@@ -2097,6 +2149,7 @@ public interface IMountService extends IInterface {
public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
public void forgetVolume(String fsUuid) throws RemoteException;
public void forgetAllVolumes() throws RemoteException;
+ public void setDebugFlags(int flags, int mask) throws RemoteException;
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8c0bbbf..8ff56f8 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -82,6 +82,9 @@ public class StorageManager {
/** {@hide} */
public static final String UUID_PRIMARY_PHYSICAL = "primary_physical";
+ /** {@hide} */
+ public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
+
private final Context mContext;
private final ContentResolver mResolver;
@@ -641,6 +644,15 @@ public class StorageManager {
}
/** {@hide} */
+ public long benchmark(String volId) {
+ try {
+ return mMountService.benchmark(volId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
public void partitionPublic(String diskId) {
try {
mMountService.partitionPublic(diskId);
diff --git a/core/java/android/service/carrier/CarrierConfigService.java b/core/java/android/service/carrier/CarrierConfigService.java
index bc42b6b..bf33ad5 100644
--- a/core/java/android/service/carrier/CarrierConfigService.java
+++ b/core/java/android/service/carrier/CarrierConfigService.java
@@ -23,14 +23,14 @@ import android.os.PersistableBundle;
* A service that sets carrier configuration for telephony services.
* <p>
* To extend this class, you must declare the service in your manifest file to require the
- * {@link android.Manifest.permission#BIND_CARRIER_CONFIG_SERVICE} permission and include an intent
+ * {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
* filter with the {@link #SERVICE_INTERFACE} action. For example:
* </p>
*
* <pre>{@code
* <service android:name=".MyCarrierConfigService"
* android:label="@string/service_name"
- * android:permission="android.permission.BIND_CARRIER_CONFIG_SERVICE">
+ * android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
* <action android:name="android.service.carrier.CarrierConfigService" />
* </intent-filter>
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index d7bf10c..f5396a3 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -31,12 +31,12 @@ import java.util.List;
* A service that receives calls from the system when new SMS and MMS are
* sent or received.
* <p>To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE} permission
+ * the {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission
* and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
* <pre>
* &lt;service android:name=".MyMessagingService"
* android:label="&#64;string/service_name"
- * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE">
+ * android:permission="android.permission.BIND_CARRIER_SERVICES">
* &lt;intent-filter>
* &lt;action android:name="android.service.carrier.CarrierMessagingService" />
* &lt;/intent-filter>
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index d271af2..8fe8252 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -186,11 +186,12 @@ class DayPickerPagerAdapter extends PagerAdapter {
}
private int getMonthForPosition(int position) {
- return position % MONTHS_IN_YEAR + mMinDate.get(Calendar.MONTH);
+ return (position + mMinDate.get(Calendar.MONTH)) % MONTHS_IN_YEAR;
}
private int getYearForPosition(int position) {
- return position / MONTHS_IN_YEAR + mMinDate.get(Calendar.YEAR);
+ final int yearOffset = (position + mMinDate.get(Calendar.MONTH)) / MONTHS_IN_YEAR;
+ return yearOffset + mMinDate.get(Calendar.YEAR);
}
private int getPositionForDay(@Nullable Calendar day) {
@@ -198,8 +199,8 @@ class DayPickerPagerAdapter extends PagerAdapter {
return -1;
}
- final int yearOffset = (day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR));
- final int monthOffset = (day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH));
+ final int yearOffset = day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
+ final int monthOffset = day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
final int position = yearOffset * MONTHS_IN_YEAR + monthOffset;
return position;
}
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index a434317..dc772fb 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -176,8 +176,6 @@ class DayPickerView extends ViewGroup {
}
}
});
-
- updateButtonVisibility(mViewPager.getCurrentItem());
}
private void updateButtonVisibility(int position) {
@@ -346,6 +344,8 @@ class DayPickerView extends ViewGroup {
// Changing the min/max date changes the selection position since we
// don't really have stable IDs. Jumps immediately to the new position.
setDate(mSelectedDay.getTimeInMillis(), false, false);
+
+ updateButtonVisibility(mViewPager.getCurrentItem());
}
/**
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 80bc5fe..49230c1 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -45,33 +45,11 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
public class PlatLogoActivity extends Activity {
- final static int[] FLAVORS = {
- 0xFF9C27B0, 0xFFBA68C8, // grape
- 0xFFFF9800, 0xFFFFB74D, // orange
- 0xFFF06292, 0xFFF8BBD0, // bubblegum
- 0xFFAFB42B, 0xFFCDDC39, // lime
- 0xFFFFEB3B, 0xFFFFF176, // lemon
- 0xFF795548, 0xFFA1887F, // mystery flavor
- };
FrameLayout mLayout;
int mTapCount;
int mKeyCount;
PathInterpolator mInterpolator = new PathInterpolator(0f, 0f, 0.5f, 1f);
- static int newColorIndex() {
- return 2*((int) (Math.random()*FLAVORS.length/2));
- }
-
- Drawable makeRipple() {
- final int idx = newColorIndex();
- final ShapeDrawable popbg = new ShapeDrawable(new OvalShape());
- popbg.getPaint().setColor(FLAVORS[idx]);
- final RippleDrawable ripple = new RippleDrawable(
- ColorStateList.valueOf(FLAVORS[idx+1]),
- popbg, null);
- return ripple;
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -87,120 +65,62 @@ public class PlatLogoActivity extends Activity {
final int size = (int)
(Math.min(Math.min(dm.widthPixels, dm.heightPixels), 600*dp) - 100*dp);
- final View stick = new View(this) {
- Paint mPaint = new Paint();
- Path mShadow = new Path();
-
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- setWillNotDraw(false);
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRect(0, getHeight() / 2, getWidth(), getHeight());
- }
- });
- }
+ final View im = new View(this);
+ im.setTranslationZ(20);
+ im.setScaleX(0.5f);
+ im.setScaleY(0.5f);
+ im.setAlpha(0f);
+ im.setOutlineProvider(new ViewOutlineProvider() {
@Override
- public void onDraw(Canvas c) {
- final int w = c.getWidth();
- final int h = c.getHeight() / 2;
- c.translate(0, h);
- final GradientDrawable g = new GradientDrawable();
- g.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
- g.setGradientCenter(w * 0.75f, 0);
- g.setColors(new int[] { 0xFFFFFFFF, 0xFFAAAAAA });
- g.setBounds(0, 0, w, h);
- g.draw(c);
- mPaint.setColor(0xFFAAAAAA);
- mShadow.reset();
- mShadow.moveTo(0,0);
- mShadow.lineTo(w, 0);
- mShadow.lineTo(w, size/2 + 1.5f*w);
- mShadow.lineTo(0, size/2);
- mShadow.close();
- c.drawPath(mShadow, mPaint);
+ public void getOutline(View view, Outline outline) {
+ final int pad = (int) (8*dp);
+ outline.setOval(pad, pad, view.getWidth()-pad, view.getHeight()-pad);
}
- };
- mLayout.addView(stick, new FrameLayout.LayoutParams((int) (32 * dp),
- ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL));
- stick.setAlpha(0f);
-
- final ImageView im = new ImageView(this);
- im.setTranslationZ(20);
- im.setScaleX(0);
- im.setScaleY(0);
+ });
final Drawable platlogo = getDrawable(com.android.internal.R.drawable.platlogo);
- platlogo.setAlpha(0);
- im.setImageDrawable(platlogo);
- im.setBackground(makeRipple());
+ im.setBackground(new RippleDrawable(
+ ColorStateList.valueOf(0xFFFFFFFF),
+ platlogo,
+ null));
im.setClickable(true);
- final ShapeDrawable highlight = new ShapeDrawable(new OvalShape());
- highlight.getPaint().setColor(0x10FFFFFF);
- highlight.setBounds((int)(size*.15f), (int)(size*.15f),
- (int)(size*.6f), (int)(size*.6f));
- im.getOverlay().add(highlight);
im.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mTapCount == 0) {
- im.animate()
- .translationZ(40)
- .scaleX(1)
- .scaleY(1)
- .setInterpolator(mInterpolator)
- .setDuration(700)
- .setStartDelay(500)
- .start();
-
- final ObjectAnimator a = ObjectAnimator.ofInt(platlogo, "alpha", 0, 255);
- a.setInterpolator(mInterpolator);
- a.setStartDelay(1000);
- a.start();
-
- stick.animate()
- .translationZ(20)
- .alpha(1)
- .setInterpolator(mInterpolator)
- .setDuration(700)
- .setStartDelay(750)
- .start();
-
- im.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- if (mTapCount < 5) return false;
-
- final ContentResolver cr = getContentResolver();
- if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
- == 0) {
- // For posterity: the moment this user unlocked the easter egg
+ im.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (mTapCount < 5) return false;
+
+ final ContentResolver cr = getContentResolver();
+ if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
+ == 0) {
+ // For posterity: the moment this user unlocked the easter egg
+ try {
Settings.System.putLong(cr,
Settings.System.EGG_MODE,
System.currentTimeMillis());
+ } catch (RuntimeException e) {
+ Log.e("PlatLogoActivity", "Can't write settings", e);
}
- im.post(new Runnable() {
- @Override
- public void run() {
- try {
- startActivity(new Intent(Intent.ACTION_MAIN)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- .addCategory("com.android.internal.category.PLATLOGO"));
- } catch (ActivityNotFoundException ex) {
- Log.e("PlatLogoActivity", "No more eggs.");
- }
- finish();
- }
- });
- return true;
}
- });
- } else {
- im.setBackground(makeRipple());
- }
+ im.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ startActivity(new Intent(Intent.ACTION_MAIN)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .addCategory("com.android.internal.category.PLATLOGO"));
+ } catch (ActivityNotFoundException ex) {
+ Log.e("PlatLogoActivity", "No more eggs.");
+ }
+ finish();
+ }
+ });
+ return true;
+ }
+ });
mTapCount++;
}
});
@@ -229,7 +149,7 @@ public class PlatLogoActivity extends Activity {
mLayout.addView(im, new FrameLayout.LayoutParams(size, size, Gravity.CENTER));
- im.animate().scaleX(0.3f).scaleY(0.3f)
+ im.animate().scaleX(1f).scaleY(1f).alpha(1f)
.setInterpolator(mInterpolator)
.setDuration(500)
.setStartDelay(800)
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index a53d46c..fbe87c5 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -615,6 +615,7 @@ public final class BatteryStatsHelper {
mStatsType);
if (bs.sumPower() > 0) {
aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
+ mUsageList.add(bs);
}
}
@@ -742,7 +743,6 @@ public final class BatteryStatsHelper {
parcel.setDataPosition(0);
BatteryStatsImpl stats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel);
- stats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
return stats;
} catch (IOException e) {
Log.w(TAG, "Unable to read statistics stream", e);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c2212f7..eaca43b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -105,7 +105,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 125 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 126 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -132,6 +132,9 @@ public final class BatteryStatsImpl extends BatteryStats {
private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
+ private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
+ private final KernelCpuSpeedReader mKernelCpuSpeedReader = new KernelCpuSpeedReader();
+
public interface BatteryCallback {
public void batteryNeedsCpuUpdate();
public void batteryPowerChanged(boolean onBattery);
@@ -794,20 +797,6 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public static class SamplingCounter extends Counter {
- SamplingCounter(TimeBase timeBase, Parcel in) {
- super(timeBase, in);
- }
-
- SamplingCounter(TimeBase timeBase) {
- super(timeBase);
- }
-
- public void addCountAtomic(long count) {
- mCount.addAndGet((int)count);
- }
- }
-
public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
final TimeBase mTimeBase;
long mCount;
@@ -2918,8 +2907,7 @@ public final class BatteryStatsImpl extends BatteryStats {
public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
- int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime,
- long[] cpuSpeedTimes) {
+ int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime) {
if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
+ " user=" + statUserTime + " sys=" + statSystemTime
+ " io=" + statIOWaitTime + " irq=" + statIrqTime
@@ -2959,7 +2947,7 @@ public final class BatteryStatsImpl extends BatteryStats {
remainSTtime -= mySTime;
num--;
Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
- proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes);
+ proc.addCpuTimeLocked(myUTime, mySTime);
}
}
}
@@ -2970,7 +2958,7 @@ public final class BatteryStatsImpl extends BatteryStats {
Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
if (uid != null) {
Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
- proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes);
+ proc.addCpuTimeLocked(remainUTime, remainSTtime);
}
}
}
@@ -4398,6 +4386,10 @@ public final class BatteryStatsImpl extends BatteryStats {
long mCurStepUserTime;
long mCurStepSystemTime;
+ LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
+ LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
+ LongSamplingCounter[] mSpeedBins;
+
/**
* The statistics we have collected for this uid's wake locks.
*/
@@ -4455,6 +4447,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mOnBatteryTimeBase);
mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
+ mSpeedBins = new LongSamplingCounter[getCpuSpeedSteps()];
}
@Override
@@ -4925,6 +4918,26 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public long getUserCpuTimeUs(int which) {
+ return mUserCpuTime.getCountLocked(which);
+ }
+
+ @Override
+ public long getSystemCpuTimeUs(int which) {
+ return mSystemCpuTime.getCountLocked(which);
+ }
+
+ @Override
+ public long getTimeAtCpuSpeed(int step, int which) {
+ if (step >= 0 && step < mSpeedBins.length) {
+ if (mSpeedBins[step] != null) {
+ return mSpeedBins[step].getCountLocked(which);
+ }
+ }
+ return 0;
+ }
+
+ @Override
public long getWifiControllerActivity(int type, int which) {
if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
mWifiControllerTime[type] != null) {
@@ -5026,6 +5039,15 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ mUserCpuTime.reset(false);
+ mSystemCpuTime.reset(false);
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ c.reset(false);
+ }
+ }
+
final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
for (int iw=wakeStats.size()-1; iw>=0; iw--) {
Wakelock wl = wakeStats.valueAt(iw);
@@ -5159,6 +5181,15 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
mPids.clear();
+
+ mUserCpuTime.detach();
+ mSystemCpuTime.detach();
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ c.detach();
+ }
+ }
}
return !active;
@@ -5317,6 +5348,20 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(0);
}
}
+
+ mUserCpuTime.writeToParcel(out);
+ mSystemCpuTime.writeToParcel(out);
+
+ out.writeInt(mSpeedBins.length);
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ out.writeInt(1);
+ c.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
}
void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
@@ -5482,6 +5527,18 @@ public final class BatteryStatsImpl extends BatteryStats {
mBluetoothControllerTime[i] = null;
}
}
+
+ mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+
+ int bins = in.readInt();
+ int steps = getCpuSpeedSteps();
+ mSpeedBins = new LongSamplingCounter[bins >= steps ? bins : steps];
+ for (int i = 0; i < bins; i++) {
+ if (in.readInt() != 0) {
+ mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ }
+ }
}
/**
@@ -5762,14 +5819,11 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
int mProcessState = PROCESS_STATE_NONE;
- SamplingCounter[] mSpeedBins;
-
ArrayList<ExcessivePower> mExcessivePower;
Proc(String name) {
mName = name;
mOnBatteryTimeBase.add(this);
- mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
}
public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
@@ -5791,25 +5845,12 @@ public final class BatteryStatsImpl extends BatteryStats {
mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- c.reset(false);
- }
- }
mExcessivePower = null;
}
void detach() {
mActive = false;
mOnBatteryTimeBase.remove(this);
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- mOnBatteryTimeBase.remove(c);
- mSpeedBins[i] = null;
- }
- }
}
public int countExcessivePowers() {
@@ -5903,18 +5944,6 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(mUnpluggedStarts);
out.writeInt(mUnpluggedNumCrashes);
out.writeInt(mUnpluggedNumAnrs);
-
- out.writeInt(mSpeedBins.length);
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- out.writeInt(1);
- c.writeToParcel(out);
- } else {
- out.writeInt(0);
- }
- }
-
writeExcessivePowerToParcelLocked(out);
}
@@ -5937,39 +5966,12 @@ public final class BatteryStatsImpl extends BatteryStats {
mUnpluggedStarts = in.readInt();
mUnpluggedNumCrashes = in.readInt();
mUnpluggedNumAnrs = in.readInt();
-
- int bins = in.readInt();
- int steps = getCpuSpeedSteps();
- mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
- for (int i = 0; i < bins; i++) {
- if (in.readInt() != 0) {
- mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
- }
- }
-
readExcessivePowerFromParcelLocked(in);
}
- public BatteryStatsImpl getBatteryStats() {
- return BatteryStatsImpl.this;
- }
-
- public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) {
+ public void addCpuTimeLocked(int utime, int stime) {
mUserTime += utime;
- mCurStepUserTime += utime;
mSystemTime += stime;
- mCurStepSystemTime += stime;
-
- for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) {
- long amt = speedStepBins[i];
- if (amt != 0) {
- SamplingCounter c = mSpeedBins[i];
- if (c == null) {
- mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
- }
- c.addCountAtomic(speedStepBins[i]);
- }
- }
}
public void addForegroundTimeLocked(long ttime) {
@@ -6058,16 +6060,6 @@ public final class BatteryStatsImpl extends BatteryStats {
}
return val;
}
-
- @Override
- public long getTimeAtCpuSpeedStep(int speedStep, int which) {
- if (speedStep < mSpeedBins.length) {
- SamplingCounter c = mSpeedBins[speedStep];
- return c != null ? c.getCountLocked(which) : 0;
- } else {
- return 0;
- }
- }
}
/**
@@ -7729,7 +7721,7 @@ public final class BatteryStatsImpl extends BatteryStats {
* @param info The energy information from the bluetooth controller.
*/
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
- if (info != null && mOnBatteryInternal && false) {
+ if (info != null && mOnBatteryInternal) {
mHasBluetoothEnergyReporting = true;
mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
info.getControllerRxTimeMillis());
@@ -7785,6 +7777,32 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ /**
+ * Read and distribute CPU usage across apps.
+ */
+ public void updateCpuTimeLocked(boolean firstTime) {
+ final int cpuSpeedSteps = getCpuSpeedSteps();
+ final long[] cpuSpeeds = mKernelCpuSpeedReader.readDelta();
+ KernelUidCpuTimeReader.Callback callback = null;
+ if (mOnBatteryInternal && !firstTime) {
+ callback = new KernelUidCpuTimeReader.Callback() {
+ @Override
+ public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
+ final Uid u = getUidStatsLocked(mapUid(uid));
+ u.mUserCpuTime.addCountLocked(userTimeUs);
+ u.mSystemCpuTime.addCountLocked(systemTimeUs);
+ for (int i = 0; i < cpuSpeedSteps; i++) {
+ if (u.mSpeedBins[i] == null) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ }
+ u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
+ }
+ }
+ };
+ }
+ mKernelUidCpuTimeReader.readDelta(callback);
+ }
+
boolean setChargingLocked(boolean charging) {
if (mCharging != charging) {
mCharging = charging;
@@ -8407,6 +8425,7 @@ public final class BatteryStatsImpl extends BatteryStats {
* Remove the statistics object for a particular uid.
*/
public void removeUidStatsLocked(int uid) {
+ mKernelUidCpuTimeReader.removeUid(uid);
mUidStats.remove(uid);
}
@@ -8440,58 +8459,6 @@ public final class BatteryStatsImpl extends BatteryStats {
return u.getServiceStatsLocked(pkg, name);
}
- /**
- * Massage data to distribute any reasonable work down to more specific
- * owners. Must only be called on a dead BatteryStats object!
- */
- public void distributeWorkLocked(int which) {
- // Aggregate all CPU time associated with WIFI.
- Uid wifiUid = mUidStats.get(Process.WIFI_UID);
- if (wifiUid != null) {
- long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
- for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) {
- Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip);
- long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
- for (int i=0; i<mUidStats.size(); i++) {
- Uid uid = mUidStats.valueAt(i);
- if (uid.mUid != Process.WIFI_UID) {
- long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
- if (uidRunningTime > 0) {
- Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
- long time = proc.getUserTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mUserTime += time;
- proc.mUserTime -= time;
- time = proc.getSystemTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mSystemTime += time;
- proc.mSystemTime -= time;
- time = proc.getForegroundTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mForegroundTime += time;
- proc.mForegroundTime -= time;
- for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
- SamplingCounter sc = proc.mSpeedBins[sb];
- if (sc != null) {
- time = sc.getCountLocked(which);
- time = (time*uidRunningTime)/totalRunningTime;
- SamplingCounter uidSc = uidProc.mSpeedBins[sb];
- if (uidSc == null) {
- uidSc = new SamplingCounter(mOnBatteryTimeBase);
- uidProc.mSpeedBins[sb] = uidSc;
- }
- uidSc.mCount.addAndGet((int)time);
- sc.mCount.addAndGet((int)-time);
- }
- }
- totalRunningTime -= uidRunningTime;
- }
- }
- }
- }
- }
- }
-
public void shutdownLocked() {
recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
writeSyncLocked();
@@ -8950,6 +8917,23 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
}
+ u.mUserCpuTime.readSummaryFromParcelLocked(in);
+ u.mSystemCpuTime.readSummaryFromParcelLocked(in);
+
+ int NSB = in.readInt();
+ if (NSB > 100) {
+ Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
+ return;
+ }
+
+ u.mSpeedBins = new LongSamplingCounter[NSB];
+ for (int i=0; i<NSB; i++) {
+ if (in.readInt() != 0) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ u.mSpeedBins[i].readSummaryFromParcelLocked(in);
+ }
+ }
+
int NW = in.readInt();
if (NW > 100) {
Slog.w(TAG, "File corrupt: too many wake locks " + NW);
@@ -9007,18 +8991,6 @@ public final class BatteryStatsImpl extends BatteryStats {
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);
- return;
- }
- p.mSpeedBins = new SamplingCounter[NSB];
- for (int i=0; i<NSB; i++) {
- if (in.readInt() != 0) {
- p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
- p.mSpeedBins[i].readSummaryFromParcelLocked(in);
- }
- }
if (!p.readExcessivePowerFromParcelLocked(in)) {
return;
}
@@ -9278,6 +9250,20 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
}
+ u.mUserCpuTime.writeSummaryFromParcelLocked(out);
+ u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
+
+ out.writeInt(u.mSpeedBins.length);
+ for (int i = 0; i < u.mSpeedBins.length; i++) {
+ LongSamplingCounter speedBin = u.mSpeedBins[i];
+ if (speedBin != null) {
+ out.writeInt(1);
+ speedBin.writeSummaryFromParcelLocked(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
+
final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
int NW = wakeStats.size();
out.writeInt(NW);
@@ -9344,16 +9330,6 @@ public final class BatteryStatsImpl extends BatteryStats {
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++) {
- if (ps.mSpeedBins[i] != null) {
- out.writeInt(1);
- ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
- } else {
- out.writeInt(0);
- }
- }
ps.writeExcessivePowerToParcelLocked(out);
}
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index 6c3f958..a3ef612 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -44,55 +44,57 @@ public class CpuPowerCalculator extends PowerCalculator {
long rawUptimeUs, int statsType) {
final int speedSteps = mSpeedStepTimes.length;
+ long totalTimeAtSpeeds = 0;
+ for (int step = 0; step < speedSteps; step++) {
+ mSpeedStepTimes[step] = u.getTimeAtCpuSpeed(step, statsType);
+ totalTimeAtSpeeds += mSpeedStepTimes[step];
+ }
+ totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
+
+ app.cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
+ if (DEBUG && app.cpuTimeMs != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU time " + app.cpuTimeMs + " ms");
+ }
+
+ double cpuPowerMaMs = 0;
+ for (int step = 0; step < speedSteps; step++) {
+ final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
+ final double cpuSpeedStepPower = ratio * app.cpuTimeMs * mPowerCpuNormal[step];
+ if (DEBUG && ratio != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
+ + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
+ + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+ }
+ cpuPowerMaMs += cpuSpeedStepPower;
+ }
+
+ if (DEBUG && cpuPowerMaMs != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": cpu total power="
+ + BatteryStatsHelper.makemAh(cpuPowerMaMs / (60 * 60 * 1000)));
+ }
+
// Keep track of the package with highest drain.
double highestDrain = 0;
+ app.cpuFgTimeMs = 0;
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
final int processStatsCount = processStats.size();
for (int i = 0; i < processStatsCount; i++) {
final BatteryStats.Uid.Proc ps = processStats.valueAt(i);
final String processName = processStats.keyAt(i);
-
app.cpuFgTimeMs += ps.getForegroundTime(statsType);
- final long totalCpuTime = ps.getUserTime(statsType) + ps.getSystemTime(statsType);
- app.cpuTimeMs += totalCpuTime;
-
- // Calculate the total CPU time spent at the various speed steps.
- long totalTimeAtSpeeds = 0;
- for (int step = 0; step < speedSteps; step++) {
- mSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, statsType);
- totalTimeAtSpeeds += mSpeedStepTimes[step];
- }
- totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
-
- // Then compute the ratio of time spent at each speed and figure out
- // the total power consumption.
- double cpuPower = 0;
- for (int step = 0; step < speedSteps; step++) {
- final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
- final double cpuSpeedStepPower = ratio * totalCpuTime * mPowerCpuNormal[step];
- if (DEBUG && ratio != 0) {
- Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
- + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
- + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
- }
- cpuPower += cpuSpeedStepPower;
- }
- if (DEBUG && cpuPower != 0) {
- Log.d(TAG, String.format("process %s, cpu power=%s",
- processName, BatteryStatsHelper.makemAh(cpuPower / (60 * 60 * 1000))));
- }
- app.cpuPowerMah += cpuPower;
+ final long costValue = ps.getUserTime(statsType) + ps.getSystemTime(statsType)
+ + ps.getForegroundTime(statsType);
// Each App can have multiple packages and with multiple running processes.
// Keep track of the package who's process has the highest drain.
if (app.packageWithHighestDrain == null ||
app.packageWithHighestDrain.startsWith("*")) {
- highestDrain = cpuPower;
+ highestDrain = costValue;
app.packageWithHighestDrain = processName;
- } else if (highestDrain < cpuPower && !processName.startsWith("*")) {
- highestDrain = cpuPower;
+ } else if (highestDrain < costValue && !processName.startsWith("*")) {
+ highestDrain = costValue;
app.packageWithHighestDrain = processName;
}
}
@@ -108,6 +110,6 @@ public class CpuPowerCalculator extends PowerCalculator {
}
// Convert the CPU power to mAh
- app.cpuPowerMah /= (60 * 60 * 1000);
+ app.cpuPowerMah = cpuPowerMaMs / (60 * 60 * 1000);
}
}
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
new file mode 100644
index 0000000..c30df28
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Reads CPU time spent at various frequencies and provides a delta from the last call to
+ * {@link #readDelta}. Each line in the proc file has the format:
+ *
+ * freq time
+ *
+ * where time is measured in 1/100 seconds.
+ */
+public class KernelCpuSpeedReader {
+ private static final String TAG = "KernelCpuSpeedReader";
+ private static final String sProcFile =
+ "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
+ private static final int MAX_SPEEDS = 60;
+
+ private long[] mLastSpeedTimes = new long[MAX_SPEEDS];
+ private long[] mDeltaSpeedTimes = new long[MAX_SPEEDS];
+
+ /**
+ * The returned array is modified in subsequent calls to {@link #readDelta}.
+ * @return The time (in milliseconds) spent at different cpu speeds since the last call to
+ * {@link #readDelta}.
+ */
+ public long[] readDelta() {
+ try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
+ String line;
+ int speedIndex = 0;
+ while ((line = reader.readLine()) != null) {
+ splitter.setString(line);
+ Long.parseLong(splitter.next());
+
+ // The proc file reports time in 1/100 sec, so convert to milliseconds.
+ long time = Long.parseLong(splitter.next()) * 10;
+ mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
+ mLastSpeedTimes[speedIndex] = time;
+ speedIndex++;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read cpu-freq", e);
+ Arrays.fill(mDeltaSpeedTimes, 0);
+ }
+ return mDeltaSpeedTimes;
+ }
+}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
new file mode 100644
index 0000000..b236378
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.util.SparseLongArray;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Reads /proc/uid_cputime/show_uid_stat which has the line format:
+ *
+ * uid: user_time_micro_seconds system_time_micro_seconds
+ *
+ * This provides the time a UID's processes spent executing in user-space and kernel-space.
+ * The file contains a monotonically increasing count of time for a single boot. This class
+ * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
+ * delta.
+ */
+public class KernelUidCpuTimeReader {
+ private static final String TAG = "KernelUidCpuTimeReader";
+ private static final String sProcFile = "/proc/uid_cputime/show_uid_stat";
+ private static final String sRemoveUidProcFile = "/proc/uid_cputime/remove_uid_range";
+
+ /**
+ * Callback interface for processing each line of the proc file.
+ */
+ public interface Callback {
+ void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
+ }
+
+ private SparseLongArray mLastUserTimeUs = new SparseLongArray();
+ private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
+
+ /**
+ * Reads the proc file, calling into the callback with a delta of time for each UID.
+ * @param callback The callback to invoke for each line of the proc file. If null,
+ * the data is consumed and subsequent calls to readDelta will provide
+ * a fresh delta.
+ */
+ public void readDelta(@Nullable Callback callback) {
+ try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
+ String line;
+ while ((line = reader.readLine()) != null) {
+ splitter.setString(line);
+ final String uidStr = splitter.next();
+ final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
+ final long userTimeUs = Long.parseLong(splitter.next(), 10);
+ final long systemTimeUs = Long.parseLong(splitter.next(), 10);
+
+ if (callback != null) {
+ long userTimeDeltaUs = userTimeUs;
+ long systemTimeDeltaUs = systemTimeUs;
+ int index = mLastUserTimeUs.indexOfKey(uid);
+ if (index >= 0) {
+ userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
+ systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
+
+ if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0) {
+ // The UID must have been removed from accounting, then added back.
+ userTimeDeltaUs = userTimeUs;
+ systemTimeDeltaUs = systemTimeUs;
+ }
+ }
+
+ if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) {
+ callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
+ }
+ }
+ mLastUserTimeUs.put(uid, userTimeUs);
+ mLastSystemTimeUs.put(uid, systemTimeUs);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read uid_cputime", e);
+ }
+ }
+
+ /**
+ * Removes the UID from the kernel module and from internal accounting data.
+ * @param uid The UID to remove.
+ */
+ public void removeUid(int uid) {
+ int index = mLastUserTimeUs.indexOfKey(uid);
+ if (index >= 0) {
+ mLastUserTimeUs.removeAt(index);
+ mLastSystemTimeUs.removeAt(index);
+ }
+
+ try (FileWriter writer = new FileWriter(sRemoveUidProcFile)) {
+ writer.write(Integer.toString(uid) + "-" + Integer.toString(uid));
+ writer.flush();
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to remove uid from uid_cputime module", e);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 2983047..8393e2a 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -170,21 +170,6 @@ public class ProcessCpuTracker {
private byte[] mBuffer = new byte[4096];
- /**
- * The time in microseconds that the CPU has been running at each speed.
- */
- private long[] mCpuSpeedTimes;
-
- /**
- * The relative time in microseconds that the CPU has been running at each speed.
- */
- private long[] mRelCpuSpeedTimes;
-
- /**
- * The different speeds that the CPU can be running at.
- */
- private long[] mCpuSpeeds;
-
public static class Stats {
public final int pid;
public final int uid;
@@ -590,70 +575,6 @@ public class ProcessCpuTracker {
}
}
- /**
- * Returns the delta time (in clock ticks, or 1/100 sec) spent at each CPU
- * speed, since the last call to this method. If this is the first call, it
- * will return 1 for each value.
- */
- public long[] getLastCpuSpeedTimes() {
- if (mCpuSpeedTimes == null) {
- mCpuSpeedTimes = getCpuSpeedTimes(null);
- mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length];
- for (int i = 0; i < mCpuSpeedTimes.length; i++) {
- mRelCpuSpeedTimes[i] = 1; // Initialize
- }
- } else {
- getCpuSpeedTimes(mRelCpuSpeedTimes);
- for (int i = 0; i < mCpuSpeedTimes.length; i++) {
- long temp = mRelCpuSpeedTimes[i];
- mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i];
- mCpuSpeedTimes[i] = temp;
- }
- }
- return mRelCpuSpeedTimes;
- }
-
- private long[] getCpuSpeedTimes(long[] out) {
- long[] tempTimes = out;
- long[] tempSpeeds = mCpuSpeeds;
- final int MAX_SPEEDS = 60;
- if (out == null) {
- tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
- tempSpeeds = new long[MAX_SPEEDS];
- }
- int speed = 0;
- String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0');
- // Note: file may be null on kernels without cpufreq (i.e. the emulator's)
- if (file != null) {
- StringTokenizer st = new StringTokenizer(file, "\n ");
- while (st.hasMoreElements()) {
- String token = st.nextToken();
- try {
- long val = Long.parseLong(token);
- tempSpeeds[speed] = val;
- token = st.nextToken();
- val = Long.parseLong(token);
- tempTimes[speed] = val;
- speed++;
- if (speed == MAX_SPEEDS) break; // No more
- if (localLOGV && out == null) {
- Slog.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1]
- + "\t" + tempTimes[speed - 1]);
- }
- } catch (NumberFormatException nfe) {
- Slog.i(TAG, "Unable to parse time_in_state");
- }
- }
- }
- if (out == null) {
- out = new long[speed];
- mCpuSpeeds = new long[speed];
- System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed);
- System.arraycopy(tempTimes, 0, out, 0, speed);
- }
- return out;
- }
-
final public int getLastUserTime() {
return mRelUserTime;
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3d23986..e5ef60c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1097,8 +1097,11 @@ public class LockPatternUtils {
Log.w(TAG, "Only device owner may call setCredentialRequiredForDecrypt()");
return;
}
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0);
+
+ if (isDeviceEncryptionEnabled()){
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0);
+ }
}
private boolean isDoNotAskCredentialsOnBootSet() {
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 348b0ec..e69f64e 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -102,8 +102,8 @@ public:
canvas->translate(bounds.fLeft, bounds.fTop);
canvas->scale(scale, scale);
- bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
- bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
+ bounds.fRight = (bounds.fRight-bounds.fLeft) / scale;
+ bounds.fBottom = (bounds.fBottom-bounds.fTop) / scale;
bounds.fLeft = bounds.fTop = 0;
ALOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 26ce967..323f832 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -94,8 +94,7 @@ SkScalar calculateStretch(SkScalar boundsLimit, SkScalar startingPoint,
SkScalar spaceRemaining = boundsLimit - startingPoint;
SkScalar stretchySpaceRemaining =
spaceRemaining - SkIntToScalar(numFixedPixelsRemaining);
- return SkScalarMulDiv(srcSpace, stretchySpaceRemaining,
- numStrechyPixelsRemaining);
+ return srcSpace * stretchySpaceRemaining / numStrechyPixelsRemaining;
}
void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4c034b3..79532e4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2404,8 +2404,7 @@
<permission android:name="android.permission.REMOVE_DRM_CERTIFICATES"
android:protectionLevel="signature|system" />
- <!-- Must be required by a {@link android.service.carrier.CarrierMessagingService}.
- Any service that filters for this intent must be a carrier privileged app. -->
+ <!-- @deprecated Use {@link android.Manifest.permission#BIND_CARRIER_SERVICES} instead -->
<permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
android:protectionLevel="signature|system" />
@@ -2427,13 +2426,12 @@
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature" />
- <!-- The system process that pulls carrier configuration from carrier apps will
- have this permission. Carrier apps that provide
- {@link android.service.carrier.CarrierConfigService} should require this
- permission for clients binding to their service. -->
- <permission android:name="android.permission.BIND_CARRIER_CONFIG_SERVICE"
- android:label="@string/permlab_bindCarrierConfigService"
- android:description="@string/permdesc_bindCarrierConfigService"
+ <!-- The system process that is allowed to bind to services in carrier apps will
+ have this permission. Carrier apps should use this permission to protect
+ their services that only the system is allowed to bind to. -->
+ <permission android:name="android.permission.BIND_CARRIER_SERVICES"
+ android:label="@string/permlab_bindCarrierServices"
+ android:description="@string/permdesc_bindCarrierServices"
android:protectionLevel="signature|system" />
<!-- Allows an application to query whether DO_NOT_ASK_CREDENTIALS_ON_BOOT
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 65cb046..f5d945a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -14,35 +14,30 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="560.0dp"
- android:height="560.0dp"
- android:viewportWidth="560.0"
- android:viewportHeight="560.0">
+ android:width="480dp"
+ android:height="480dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
<path
- android:pathData="M264.079987,240.736l0.0,9.82c7.31,-7.15 17.139999,-11.56 28.07,-11.56c22.639999,0.0 40.799999,18.48 40.799999,41.12c0.0,22.48 -18.16,40.880 -40.799999,40.880c-10.93,0.0 -20.280,-4.09 -27.59,-10.93L264.559998,339.0l-11.32,0.0l0.0,-98.269997L264.079987,240.731zM265.809998,264.869995c-0.47,0.79 -1.26,2.04 -1.26,4.79l0.0,21.07c0.0,1.97 0.47,3.07 1.1,4.17c5.19,8.88 14.78,14.94 25.63,14.94c16.43,0.0 29.950,-13.44 29.950,-29.870c0.0,-16.280 -13.52,-29.799999 -29.950,-29.799999C280.51,250.169998 271.0,256.059998 265.809998,264.869995z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M445.731,240.736l0.0,9.82c7.31,-7.15 17.139999,-11.56 28.07,-11.56c22.639999,0.0 40.799999,18.48 40.799999,41.12c0.0,22.48 -18.16,40.880 -40.799999,40.880c-10.93,0.0 -20.280,-4.09 -27.59,-10.93L446.210052,339.0l-11.32,0.0l0.0,-98.269997L445.731,240.731zM447.459991,264.869995c-0.47,0.79 -1.26,2.04 -1.26,4.79l0.0,21.07c0.0,1.97 0.47,3.07 1.1,4.17c5.19,8.88 14.78,14.94 25.63,14.94c16.43,0.0 29.950,-13.44 29.950,-29.870c0.0,-16.280 -13.52,-29.799999 -29.950,-29.799999C462.160004,250.169998 452.649994,256.059998 447.459991,264.869995z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M169.490005,279.880005c0.0,22.639999 -18.32,41.12 -40.810,41.12c-22.639999,0.0 -41.040,-18.48 -41.040,-41.12c0.0,-22.48 18.389999,-40.880 41.040,-40.880C151.169998,239.0 169.490005,257.399994 169.490005,279.880005zM158.089996,280.040009c0.0,-16.43 -13.13,-29.870 -29.41,-29.870c-16.51,0.0 -29.4,13.44 -29.4,29.870c0.0,16.280 12.89,29.799999 29.4,29.799999C144.960007,309.8387 158.089996,296.309998 158.089996,280.040009z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M24.0,2.0C11.8,2.0 2.0,11.8 2.0,24.0c0.0,6.1 2.5,11.6 6.4,15.6L39.6,8.4C35.6,4.5 30.1,2.0 24.0,2.0z"
+ android:fillColor="#F57C00"/>
<path
- android:pathData="M423.790009,279.880005c0.0,22.639999 -18.32,41.12 -40.810,41.12c-22.639999,0.0 -41.040,-18.48 -41.040,-41.12c0.0,-22.48 18.389999,-40.880 41.040,-40.880C405.470,239.0 423.790009,257.399994 423.790009,279.880005zM412.395,280.040009c0.0,-16.43 -13.13,-29.870 -29.41,-29.870c-16.51,0.0 -29.4,13.44 -29.4,29.870c0.0,16.280 12.89,29.799999 29.4,29.799999C399.26,309.8387 412.395,296.309998 412.395,280.040009z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M39.6,8.4L8.4,39.6c4.0,4.0 9.5,6.4 15.6,6.4c12.2,0.0 22.0,-9.8 22.0,-22.0C46.0,17.9 43.5,12.4 39.6,8.4z"
+ android:fillColor="#FF9800"/>
<path
- android:pathData="M229.02,221.0l11.17,0.0l0.0,11.48l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M45.9,25.9L34.0,14.0L14.0,34.0l11.9,11.9C36.5,45.0 45.0,36.5 45.9,25.9z"
+ android:fillAlpha="0.33"
+ android:fillColor="#F57C00"/>
<path
- android:pathData="M229.02,240.65l11.17,0.0l0.0,78.62l-11.17,0.0z"
+ android:pathData="M24.0,24.0c0.0,0.0 0.0,2.2 0.0,5.0s0.0,5.0 0.0,5.0l10.0,-10.0L34.0,14.0L24.0,24.0z"
android:fillColor="#FFFFFF"/>
<path
- android:pathData="M65.4,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M24.0,24.0L14.0,14.0l0.0,10.0l10.0,10.0c0.0,0.0 0.0,-2.2 0.0,-5.0S24.0,24.0 24.0,24.0z"
+ android:fillColor="#EEEEEE"/>
<path
- android:pathData="M180.58,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z"
+ android:fillColor="#DDDDDD"/>
<path
- android:pathData="M204.8,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z"
+ android:fillColor="#DDDDDD"/>
</vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index d89d1f9..8f5109d 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -19,9 +19,6 @@ Copyright (C) 2014 The Android Open Source Project
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:pathData="M19.000000,10.000000c0.000000,3.866000 -3.134000,7.000000 -7.000000,7.000000s-7.000000,-3.134000 -7.000000,-7.000000c0.000000,-2.318000 1.131000,-4.367000 2.867000,-5.641000L5.778000,2.270000l0.824000,-0.825000l2.290000,2.290000C9.830000,3.269000 10.882000,3.000000 12.000000,3.000000c1.118000,0.000000 2.170000,0.269000 3.107000,0.734000l2.290000,-2.290000l0.824000,0.825000l-2.089000,2.090000C17.868000,5.633000 19.000000,7.682000 19.000000,10.000000zM10.000000,8.000000c0.000000,-0.552000 -0.447000,-1.000000 -1.000000,-1.000000S8.000000,7.448000 8.000000,8.000000s0.447000,1.000000 1.000000,1.000000S10.000000,8.552000 10.000000,8.000000zM16.000000,8.000000c0.000000,-0.552000 -0.447000,-1.000000 -1.000000,-1.000000s-1.000000,0.448000 -1.000000,1.000000s0.447000,1.000000 1.000000,1.000000S16.000000,8.552000 16.000000,8.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M11,18l2,0l0,5l-2,0z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M12.0,12.0l-10.0,-10.0 0.0,10.0 0.0,10.0 10.0,0.0 10.0,0.0 0.0,-10.0 0.0,-10.0z"/>
</vector>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1c0122d..0e6b2df 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1408,9 +1408,9 @@
<string name="permdesc_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_bindCarrierConfigService">bind to a carrier config service</string>
+ <string name="permlab_bindCarrierServices">bind to carrier services</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_bindCarrierConfigService">Allows the holder to bind to a carrier config service. Should never be needed for normal apps.</string>
+ <string name="permdesc_bindCarrierServices">Allows the holder to bind to carrier services. Should never be needed for normal apps.</string>
<!-- Policy administration -->