diff options
Diffstat (limited to 'core')
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> * <service android:name=".MyMessagingService" * android:label="@string/service_name" - * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE"> + * android:permission="android.permission.BIND_CARRIER_SERVICES"> * <intent-filter> * <action android:name="android.service.carrier.CarrierMessagingService" /> * </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 --> |