diff options
44 files changed, 944 insertions, 656 deletions
diff --git a/api/current.txt b/api/current.txt index 3b57f18..a400fa6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -20,8 +20,8 @@ package android { field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; - field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE"; - field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; + field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; + field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN"; field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE"; @@ -15730,7 +15730,7 @@ package android.media { method public void restoreKeys(byte[], byte[]); method public void setOnEventListener(android.media.MediaDrm.OnEventListener); method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler); - method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler); + method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler); method public void setPropertyByteArray(java.lang.String, byte[]); method public void setPropertyString(java.lang.String, java.lang.String); field public static final int EVENT_KEY_EXPIRED = 3; // 0x3 @@ -15738,11 +15738,6 @@ package android.media { field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1 field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5 field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4 - field public static final int KEY_STATUS_EXPIRED = 1; // 0x1 - field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4 - field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 - field public static final int KEY_STATUS_PENDING = 3; // 0x3 - field public static final int KEY_STATUS_USABLE = 0; // 0x0 field public static final int KEY_TYPE_OFFLINE = 2; // 0x2 field public static final int KEY_TYPE_RELEASE = 3; // 0x3 field public static final int KEY_TYPE_STREAMING = 1; // 0x1 @@ -15751,9 +15746,6 @@ package android.media { field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId"; field public static final java.lang.String PROPERTY_VENDOR = "vendor"; field public static final java.lang.String PROPERTY_VERSION = "version"; - field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0 - field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2 - field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1 } public final class MediaDrm.CryptoSession { @@ -15767,11 +15759,19 @@ package android.media { method public byte[] getData(); method public java.lang.String getDefaultUrl(); method public int getRequestType(); + field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0 + field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2 + field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1 } public static final class MediaDrm.KeyStatus { method public byte[] getKeyId(); method public int getStatusCode(); + field public static final int STATUS_EXPIRED = 1; // 0x1 + field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4 + field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 + field public static final int STATUS_PENDING = 3; // 0x3 + field public static final int STATUS_USABLE = 0; // 0x0 } public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { @@ -15786,8 +15786,8 @@ package android.media { method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long); } - public static abstract interface MediaDrm.OnKeysChangeListener { - method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean); + public static abstract interface MediaDrm.OnKeyStatusChangeListener { + method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean); } public static final class MediaDrm.ProvisionRequest { diff --git a/api/system-current.txt b/api/system-current.txt index dbe0d4f..14b56c7 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -28,8 +28,8 @@ package android { field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; - field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE"; - field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; + field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; + field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE"; field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; @@ -16967,7 +16967,7 @@ package android.media { method public void restoreKeys(byte[], byte[]); method public void setOnEventListener(android.media.MediaDrm.OnEventListener); method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler); - method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler); + method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler); method public void setPropertyByteArray(java.lang.String, byte[]); method public void setPropertyString(java.lang.String, java.lang.String); method public void unprovisionDevice(); @@ -16976,11 +16976,6 @@ package android.media { field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1 field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5 field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4 - field public static final int KEY_STATUS_EXPIRED = 1; // 0x1 - field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4 - field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 - field public static final int KEY_STATUS_PENDING = 3; // 0x3 - field public static final int KEY_STATUS_USABLE = 0; // 0x0 field public static final int KEY_TYPE_OFFLINE = 2; // 0x2 field public static final int KEY_TYPE_RELEASE = 3; // 0x3 field public static final int KEY_TYPE_STREAMING = 1; // 0x1 @@ -16989,9 +16984,6 @@ package android.media { field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId"; field public static final java.lang.String PROPERTY_VENDOR = "vendor"; field public static final java.lang.String PROPERTY_VERSION = "version"; - field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0 - field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2 - field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1 } public final class MediaDrm.CryptoSession { @@ -17005,11 +16997,19 @@ package android.media { method public byte[] getData(); method public java.lang.String getDefaultUrl(); method public int getRequestType(); + field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0 + field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2 + field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1 } public static final class MediaDrm.KeyStatus { method public byte[] getKeyId(); method public int getStatusCode(); + field public static final int STATUS_EXPIRED = 1; // 0x1 + field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4 + field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 + field public static final int STATUS_PENDING = 3; // 0x3 + field public static final int STATUS_USABLE = 0; // 0x0 } public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { @@ -17024,8 +17024,8 @@ package android.media { method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long); } - public static abstract interface MediaDrm.OnKeysChangeListener { - method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean); + public static abstract interface MediaDrm.OnKeyStatusChangeListener { + method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean); } public static final class MediaDrm.ProvisionRequest { diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 4a8cf08..0dad4dc 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -71,6 +71,8 @@ public final class Sm { runHasAdoptable(); } else if ("get-primary-storage-uuid".equals(op)) { runGetPrimaryStorageUuid(); + } else if ("set-force-adoptable".equals(op)) { + runSetForceAdoptable(); } else if ("partition".equals(op)) { runPartition(); } else if ("mount".equals(op)) { @@ -116,14 +118,19 @@ public final class Sm { } public void runHasAdoptable() { - System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false) - || SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)); + System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false)); } public void runGetPrimaryStorageUuid() throws RemoteException { System.out.println(mSm.getPrimaryStorageUuid()); } + public void runSetForceAdoptable() throws RemoteException { + final boolean forceAdoptable = Boolean.parseBoolean(nextArg()); + mSm.setDebugFlags(forceAdoptable ? StorageManager.DEBUG_FORCE_ADOPTABLE : 0, + StorageManager.DEBUG_FORCE_ADOPTABLE); + } + public void runPartition() throws RemoteException { final String diskId = nextArg(); final String type = nextArg(); @@ -177,6 +184,7 @@ public final class Sm { System.err.println(" sm list-volumes [public|private|emulated|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); + System.err.println(" sm set-force-adoptable [true|false]"); System.err.println(""); System.err.println(" sm partition DISK [public|private|mixed] [ratio]"); System.err.println(" sm mount VOLUME"); 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 --> diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index 0da4275..bd8eae0 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -432,7 +432,8 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb @Override public int getChangingConfigurations() { - return mChangingConfigurations | mDrawableState.getChangingConfigurations(); + return mChangingConfigurations + | (mDrawableState != null ? mDrawableState.getChangingConfigurations() : 0); } public boolean canConstantState() { diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index ba7bd74..f893fdd 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -242,7 +242,7 @@ public class AudioTrack /** * The audio channel mask used for calling native AudioTrack */ - private int mChannels = AudioFormat.CHANNEL_OUT_MONO; + private int mChannelMask = AudioFormat.CHANNEL_OUT_MONO; /** * The type of the audio stream to play. See @@ -485,7 +485,7 @@ public class AudioTrack session[0] = sessionId; // native initialization int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes, - mSampleRate, mChannels, mChannelIndexMask, mAudioFormat, + mSampleRate, mChannelMask, mChannelIndexMask, mAudioFormat, mNativeBufferSizeInBytes, mDataLoadMode, session); if (initResult != SUCCESS) { loge("Error code "+initResult+" when initializing AudioTrack."); @@ -699,7 +699,7 @@ public class AudioTrack // This is where constructor IllegalArgumentException-s are thrown // postconditions: // mChannelCount is valid - // mChannels is valid + // mChannelMask is valid // mAudioFormat is valid // mSampleRate is valid // mDataLoadMode is valid @@ -722,12 +722,12 @@ public class AudioTrack case AudioFormat.CHANNEL_OUT_MONO: case AudioFormat.CHANNEL_CONFIGURATION_MONO: mChannelCount = 1; - mChannels = AudioFormat.CHANNEL_OUT_MONO; + mChannelMask = AudioFormat.CHANNEL_OUT_MONO; break; case AudioFormat.CHANNEL_OUT_STEREO: case AudioFormat.CHANNEL_CONFIGURATION_STEREO: mChannelCount = 2; - mChannels = AudioFormat.CHANNEL_OUT_STEREO; + mChannelMask = AudioFormat.CHANNEL_OUT_STEREO; break; default: if (channelConfig == AudioFormat.CHANNEL_INVALID && channelIndexMask != 0) { @@ -738,7 +738,7 @@ public class AudioTrack // input channel configuration features unsupported channels throw new IllegalArgumentException("Unsupported channel configuration."); } - mChannels = channelConfig; + mChannelMask = channelConfig; mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig); } // check the channel index configuration (if present) diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index acff301..52ba9ec 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -110,10 +110,10 @@ public final class MediaDrm { private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES; private EventHandler mEventHandler; - private EventHandler mOnKeysChangeEventHandler; + private EventHandler mOnKeyStatusChangeEventHandler; private EventHandler mOnExpirationUpdateEventHandler; private OnEventListener mOnEventListener; - private OnKeysChangeListener mOnKeysChangeListener; + private OnKeyStatusChangeListener mOnKeyStatusChangeListener; private OnExpirationUpdateListener mOnExpirationUpdateListener; private long mNativeContext; @@ -297,8 +297,8 @@ public final class MediaDrm { * @param handler the handler on which the listener should be invoked, or * null if the listener should be invoked on the calling thread's looper. */ - public void setOnKeysChangeListener( - @Nullable OnKeysChangeListener listener, @Nullable Handler handler) { + public void setOnKeyStatusChangeListener( + @Nullable OnKeyStatusChangeListener listener, @Nullable Handler handler) { if (listener != null) { Looper looper = handler != null ? handler.getLooper() : Looper.myLooper(); if (looper != null) { @@ -307,14 +307,14 @@ public final class MediaDrm { } } } - mOnKeysChangeListener = listener; + mOnKeyStatusChangeListener = listener; } /** * Interface definition for a callback to be invoked when the keys in a drm * session change states. */ - public interface OnKeysChangeListener + public interface OnKeyStatusChangeListener { /** * Called when the keys in a session change status, such as when the license @@ -328,64 +328,64 @@ public final class MediaDrm { * which may trigger an attempt to resume playback on the media stream * if it is currently blocked waiting for a key. */ - void onKeysChange( + void onKeyStatusChange( @NonNull MediaDrm md, @NonNull byte[] sessionId, @NonNull List<KeyStatus> keyInformation, boolean hasNewUsableKey); } /** - * The key is currently usable to decrypt media data - */ - public static final int KEY_STATUS_USABLE = 0; - - /** - * The key is no longer usable to decrypt media data because its - * expiration time has passed. - */ - public static final int KEY_STATUS_EXPIRED = 1; - - /** - * The key is not currently usable to decrypt media data because its - * output requirements cannot currently be met. - */ - public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; - - /** - * The status of the key is not yet known and is being determined. - * The status will be updated with the actual status when it has - * been determined. - */ - public static final int KEY_STATUS_PENDING = 3; - - /** - * The key is not currently usable to decrypt media data because of an - * internal error in processing unrelated to input parameters. This error - * is not actionable by an app. - */ - public static final int KEY_STATUS_INTERNAL_ERROR = 4; - - /** @hide */ - @IntDef({ - KEY_STATUS_USABLE, - KEY_STATUS_EXPIRED, - KEY_STATUS_OUTPUT_NOT_ALLOWED, - KEY_STATUS_PENDING, - KEY_STATUS_INTERNAL_ERROR, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface KeyStatusCode {} - - /** * Defines the status of a key. * A KeyStatus for each key in a session is provided to the - * {@link OnKeysChangeListener#onKeysChange} + * {@link OnKeyStatusChangeListener#onKeyStatusChange} * listener. */ public static final class KeyStatus { private final byte[] mKeyId; private final int mStatusCode; + /** + * The key is currently usable to decrypt media data + */ + public static final int STATUS_USABLE = 0; + + /** + * The key is no longer usable to decrypt media data because its + * expiration time has passed. + */ + public static final int STATUS_EXPIRED = 1; + + /** + * The key is not currently usable to decrypt media data because its + * output requirements cannot currently be met. + */ + public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; + + /** + * The status of the key is not yet known and is being determined. + * The status will be updated with the actual status when it has + * been determined. + */ + public static final int STATUS_PENDING = 3; + + /** + * The key is not currently usable to decrypt media data because of an + * internal error in processing unrelated to input parameters. This error + * is not actionable by an app. + */ + public static final int STATUS_INTERNAL_ERROR = 4; + + /** @hide */ + @IntDef({ + STATUS_USABLE, + STATUS_EXPIRED, + STATUS_OUTPUT_NOT_ALLOWED, + STATUS_PENDING, + STATUS_INTERNAL_ERROR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface KeyStatusCode {} + KeyStatus(@NonNull byte[] keyId, @KeyStatusCode int statusCode) { mKeyId = keyId; mStatusCode = statusCode; @@ -393,6 +393,9 @@ public final class MediaDrm { /** * Returns the status code for the key + * @return one of {@link #STATUS_USABLE}, {@link #STATUS_EXPIRED}, + * {@link #STATUS_OUTPUT_NOT_ALLOWED}, {@link #STATUS_PENDING} + * or {@link #STATUS_INTERNAL_ERROR}. */ @KeyStatusCode public int getStatusCode() { return mStatusCode; } @@ -484,7 +487,7 @@ public final class MediaDrm { private static final int DRM_EVENT = 200; private static final int EXPIRATION_UPDATE = 201; - private static final int KEYS_CHANGE = 202; + private static final int KEY_STATUS_CHANGE = 202; private class EventHandler extends Handler { @@ -522,8 +525,8 @@ public final class MediaDrm { } return; - case KEYS_CHANGE: - if (mOnKeysChangeListener != null) { + case KEY_STATUS_CHANGE: + if (mOnKeyStatusChangeListener != null) { if (msg.obj != null && msg.obj instanceof Parcel) { Parcel parcel = (Parcel)msg.obj; byte[] sessionId = parcel.createByteArray(); @@ -531,9 +534,9 @@ public final class MediaDrm { List<KeyStatus> keyStatusList = keyStatusListFromParcel(parcel); boolean hasNewUsableKey = (parcel.readInt() != 0); - Log.i(TAG, "Drm keys change"); - mOnKeysChangeListener.onKeysChange(mMediaDrm, sessionId, keyStatusList, - hasNewUsableKey); + Log.i(TAG, "Drm key status changed"); + mOnKeyStatusChangeListener.onKeyStatusChange(mMediaDrm, sessionId, + keyStatusList, hasNewUsableKey); } } } @@ -641,30 +644,6 @@ public final class MediaDrm { public @interface KeyType {} /** - * Key request type is initial license request - */ - public static final int REQUEST_TYPE_INITIAL = 0; - - /** - * Key request type is license renewal - */ - public static final int REQUEST_TYPE_RENEWAL = 1; - - /** - * Key request type is license release - */ - public static final int REQUEST_TYPE_RELEASE = 2; - - /** @hide */ - @IntDef({ - REQUEST_TYPE_INITIAL, - REQUEST_TYPE_RENEWAL, - REQUEST_TYPE_RELEASE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface RequestType {} - - /** * Contains the opaque data an app uses to request keys from a license server */ public static final class KeyRequest { @@ -672,6 +651,30 @@ public final class MediaDrm { private String mDefaultUrl; private int mRequestType; + /** + * Key request type is initial license request + */ + public static final int REQUEST_TYPE_INITIAL = 0; + + /** + * Key request type is license renewal + */ + public static final int REQUEST_TYPE_RENEWAL = 1; + + /** + * Key request type is license release + */ + public static final int REQUEST_TYPE_RELEASE = 2; + + /** @hide */ + @IntDef({ + REQUEST_TYPE_INITIAL, + REQUEST_TYPE_RENEWAL, + REQUEST_TYPE_RELEASE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RequestType {} + KeyRequest() {} /** @@ -707,6 +710,8 @@ public final class MediaDrm { /** * Get the type of the request + * @return one of {@link #REQUEST_TYPE_INITIAL}, + * {@link #REQUEST_TYPE_RENEWAL} or {@link #REQUEST_TYPE_RELEASE} */ @RequestType public int getRequestType() { return mRequestType; } diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index e3a6a83..3ee1959 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -2270,8 +2270,8 @@ public class MediaPlayer implements SubtitleController.Listener private void scanInternalSubtitleTracks() { if (mSubtitleController == null) { - Log.e(TAG, "Should have subtitle controller already set"); - return; + Log.w(TAG, "setSubtitleAnchor in MediaPlayer"); + setSubtitleAnchor(); } TrackInfo[] tracks = getInbandTrackInfo(); diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index f8146a7..d456dc1 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -99,7 +99,7 @@ struct EventTypes { struct EventWhat { jint kWhatDrmEvent; jint kWhatExpirationUpdate; - jint kWhatKeysChange; + jint kWhatKeyStatusChange; } gEventWhat; struct KeyTypes { @@ -221,7 +221,7 @@ void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra, jwhat = gEventWhat.kWhatExpirationUpdate; break; case DrmPlugin::kDrmPluginEventKeysChange: - jwhat = gEventWhat.kWhatKeysChange; + jwhat = gEventWhat.kWhatKeyStatusChange; break; default: ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType); @@ -609,8 +609,8 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { gEventWhat.kWhatDrmEvent = env->GetStaticIntField(clazz, field); GET_STATIC_FIELD_ID(field, clazz, "EXPIRATION_UPDATE", "I"); gEventWhat.kWhatExpirationUpdate = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "KEYS_CHANGE", "I"); - gEventWhat.kWhatKeysChange = env->GetStaticIntField(clazz, field); + GET_STATIC_FIELD_ID(field, clazz, "KEY_STATUS_CHANGE", "I"); + gEventWhat.kWhatKeyStatusChange = env->GetStaticIntField(clazz, field); GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I"); gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field); @@ -619,13 +619,6 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I"); gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I"); - gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I"); - gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I"); - gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field); - GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I"); gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field); GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I"); @@ -636,6 +629,13 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;"); GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I"); + GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I"); + gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field); + GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I"); + gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field); + GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I"); + gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field); + FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest"); GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B"); GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;"); diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp index 6c1bd97..8038cdf 100644 --- a/media/jni/soundpool/SoundPool.cpp +++ b/media/jni/soundpool/SoundPool.cpp @@ -229,7 +229,7 @@ bool SoundPool::unload(int sampleID) { ALOGV("unload: sampleID=%d", sampleID); Mutex::Autolock lock(&mLock); - return mSamples.removeItem(sampleID); + return mSamples.removeItem(sampleID) >= 0; // removeItem() returns index or BAD_VALUE } int SoundPool::play(int sampleID, float leftVolume, float rightVolume, diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java index cc20d39..883c8c6 100644 --- a/obex/javax/obex/ClientOperation.java +++ b/obex/javax/obex/ClientOperation.java @@ -784,12 +784,12 @@ public final class ClientOperation implements Operation, BaseStream { mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE; } - while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { + while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) { if (!sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL)) { break; } } - while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) { + while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) { mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL, null, mReplyHeader, mPrivateInput, false); // Regardless of the SRM state, wait for the response. diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index dda9358..fd0ba73 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -95,6 +95,8 @@ <uses-permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/> <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" /> + <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> + <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <application android:label="@string/app_label"> <provider diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 9d6d937..e47c7a0 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -184,16 +184,17 @@ <activity android:name=".tuner.TunerActivity" android:enabled="false" - android:icon="@*android:drawable/stat_sys_adb" + android:icon="@drawable/tuner" android:theme="@android:style/Theme.Material.Settings" android:label="@string/system_ui_tuner" + android:process=":tuner" android:exported="true"> <intent-filter> <action android:name="com.android.settings.action.EXTRA_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="com.android.settings.category" - android:value="com.android.settings.category.device" /> + android:value="com.android.settings.category.system" /> </activity> <!-- Alternate Recents --> @@ -319,6 +320,19 @@ <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <activity android:name=".egg.ShruggyActivity" + android:theme="@android:style/Theme.NoDisplay" + android:exported="true" + android:launchMode="singleInstance" + android:screenOrientation="locked" + android:process=":sweetsweetdesserts" + android:excludeFromRecents="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.android.internal.category.PLATLOGO" /> </intent-filter> </activity> diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml index dc1e633..7b8975a 100644 --- a/packages/SystemUI/res/drawable-nodpi/icon.xml +++ b/packages/SystemUI/res/drawable-nodpi/icon.xml @@ -14,47 +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="48dp" - android:height="48dp" - android:viewportWidth="560.0" - android:viewportHeight="560.0"> + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> <path - android:pathData="M280.000000,288.000000m-260.000000,0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,520.000000 0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,-520.000000 0.000000" - android:fillColor="#14000000"/> + 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="M280.000000,285.000000m-255.000000,0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,510.000000 0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,-510.000000 0.000000" - android:fillColor="#26000000"/> + 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="M280.000000,282.000000m-252.000000,0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,504.000000 0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,-504.000000 0.000000" - android:fillColor="#26000000"/> + 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="M280.000000,280.000000m-250.000000,0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,500.000000 0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,-500.000000 0.000000" - android:fillColor="#9C27B0"/> - <path - android:pathData="M265.786011,244.938004l0.000000,8.768000c6.527000,-6.384000 15.303000,-10.321000 25.063000,-10.321000c20.214001,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.215000,36.500000 -36.429001,36.500000c-9.759000,0.000000 -18.107000,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L265.786011,244.937988L265.786011,244.938004zM267.330994,266.490997c-0.420000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.197000,13.339000 22.882999,13.339000c14.671000,0.000000 26.742001,-11.999000 26.742001,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.742001,-26.607000C280.454987,253.365997 271.963989,258.625000 267.330994,266.490997z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M427.973999,244.938004l0.000000,8.768000c6.526000,-6.384000 15.304000,-10.321000 25.062000,-10.321000c20.215000,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.214001,36.500000 -36.429001,36.500000c-9.758000,0.000000 -18.106001,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L427.973999,244.937988L427.973999,244.938004zM429.518005,266.490997c-0.419000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.196000,13.339000 22.884001,13.339000c14.670000,0.000000 26.740999,-11.999000 26.740999,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.740999,-26.607000C442.643005,253.365997 434.152008,258.625000 429.518005,266.490997z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M181.330994,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.438000,36.715000c-20.214001,0.000000 -36.643002,-16.500999 -36.643002,-36.715000c0.000000,-20.070999 16.419001,-36.500000 36.643002,-36.500000C164.973007,243.393005 181.330994,259.821014 181.330994,279.893005zM171.151993,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.259001,-26.669001c-14.741000,0.000000 -26.250000,12.000000 -26.250000,26.669001c0.000000,14.536000 11.509000,26.607000 26.250000,26.607000C159.429001,306.634003 171.151993,294.562012 171.151993,280.036011z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M408.384003,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.437000,36.715000c-20.215000,0.000000 -36.644001,-16.500999 -36.644001,-36.715000c0.000000,-20.070999 16.420000,-36.500000 36.644001,-36.500000C392.026001,243.393005 408.384003,259.821014 408.384003,279.893005zM398.204987,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.257999,-26.669001c-14.742000,0.000000 -26.250999,12.000000 -26.250999,26.669001c0.000000,14.536000 11.509000,26.607000 26.250999,26.607000C386.481995,306.634003 398.204987,294.562012 398.204987,280.036011z" + 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="M234.481995,227.320999l9.973000,0.000000l0.000000,10.250000l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M234.481995,244.865997l9.973000,0.000000l0.000000,70.195999l-9.973000,0.000000z" - 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="M88.392998,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> + android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z" + android:fillColor="#DDDDDD"/> <path - android:pathData="M191.231995,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M212.856995,227.320999l9.974000,0.000000l0.000000,87.740997l-9.974000,0.000000z" - android:fillColor="#FFFFFF"/> + android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z" + android:fillColor="#DDDDDD"/> </vector> diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml new file mode 100644 index 0000000..e27423f --- /dev/null +++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml @@ -0,0 +1,27 @@ +<!-- + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="48.0dp" + android:height="48.0dp" + android:viewportWidth="48.0" + android:viewportHeight="48.0"> + <path + android:fillColor="#FF000000" + android:pathData="M29.9,24.8c0.0,-0.3 0.1,-0.5 0.1,-0.8s0.0,-0.5 -0.1,-0.8l1.7,-1.3c0.2,-0.1 0.2,-0.3 0.1,-0.5l-1.6,-2.8c-0.1,-0.2 -0.3,-0.2 -0.5,-0.2l-2.0,0.8c-0.4,-0.3 -0.9,-0.6 -1.4,-0.8L26.0,16.3c0.0,-0.2 -0.2,-0.3 -0.4,-0.3l-3.2,0.0c-0.2,0.0 -0.4,0.1 -0.4,0.3l-0.3,2.1c-0.5,0.2 -0.9,0.5 -1.4,0.8l-2.0,-0.8c-0.2,-0.1 -0.4,0.0 -0.5,0.2l-1.6,2.8c-0.1,0.2 -0.1,0.4 0.1,0.5l1.7,1.3c0.0,0.3 -0.1,0.5 -0.1,0.8s0.0,0.5 0.1,0.8l-1.7,1.3c-0.2,0.1 -0.2,0.3 -0.1,0.5l1.6,2.8c0.1,0.2 0.3,0.2 0.5,0.2l2.0,-0.8c0.4,0.3 0.9,0.6 1.4,0.8l0.3,2.1c0.0,0.2 0.2,0.3 0.4,0.3l3.2,0.0c0.2,0.0 0.4,-0.1 0.4,-0.3l0.3,-2.1c0.5,-0.2 0.9,-0.5 1.4,-0.8l2.0,0.8c0.2,0.1 0.4,0.0 0.5,-0.2l1.6,-2.8c0.1,-0.2 0.1,-0.4 -0.1,-0.5L29.9,24.8zM24.0,26.8c-1.5,0.0 -2.8,-1.3 -2.8,-2.8s1.3,-2.8 2.8,-2.8s2.8,1.3 2.8,2.8S25.5,26.8 24.0,26.8z"/> + <path + android:fillColor="#FF000000" + android:pathData="M18.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S18.6,38.0 18.0,38.0zM24.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S24.6,38.0 24.0,38.0zM30.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S30.6,38.0 30.0,38.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,28.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM42.0,34.0L6.0,34.0L6.0,14.0l36.0,0.0L42.0,34.0zM9.0,12.0L7.0,12.0l0.0,-2.0l2.0,0.0L9.0,12.0zM13.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,12.0zM17.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L17.0,12.0z"/> +</vector> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index aac0311..f1bbb0d 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1023,7 +1023,7 @@ <string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string> <!-- Name of special SystemUI debug settings --> - <string name="system_ui_tuner">SystemUI Tuner</string> + <string name="system_ui_tuner">System UI tuner</string> <!-- Name of quick settings --> <string name="quick_settings">Quick Settings</string> @@ -1033,4 +1033,9 @@ <!-- Name of a quick settings tile controlled by broadcast --> <string name="broadcast_tile">Broadcast Tile</string> + + <!-- For preview release. DO NOT TRANSLATE --> + <string name="regrettable_lack_of_easter_egg"> + ¯\\_(ツ)_/¯ + </string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java new file mode 100644 index 0000000..7459957 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java @@ -0,0 +1,34 @@ +/* + * 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.systemui.egg; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; +import com.android.systemui.R; + +public class ShruggyActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Toast.makeText(this, getString(R.string.regrettable_lack_of_easter_egg), + Toast.LENGTH_SHORT).show(); + Log.v("SystemUI", "Hey, it's just a preview; what did you expect?"); + finish(); + } +} diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index c32de41..e00cf5b 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -16,8 +16,10 @@ package com.android.server; +import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readStringAttribute; +import static com.android.internal.util.XmlUtils.writeBooleanAttribute; import static com.android.internal.util.XmlUtils.writeIntAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; @@ -37,6 +39,7 @@ import android.content.res.ObbInfo; import android.mtp.MtpStorage; import android.net.Uri; import android.os.Binder; +import android.os.DropBoxManager; import android.os.Environment; import android.os.Environment.UserEnvironment; import android.os.FileUtils; @@ -174,6 +177,7 @@ class MountService extends IMountService.Stub private static final boolean WATCHDOG_ENABLE = false; private static final String TAG = "MountService"; + private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark"; private static final String VOLD_TAG = "VoldConnector"; @@ -233,6 +237,7 @@ class MountService extends IMountService.Stub public static final int VOLUME_DESTROYED = 659; public static final int MOVE_STATUS = 660; + public static final int BENCHMARK_RESULT = 661; /* * 700 series - fstrim @@ -247,6 +252,7 @@ class MountService extends IMountService.Stub private static final String TAG_VOLUMES = "volumes"; private static final String ATTR_VERSION = "version"; private static final String ATTR_PRIMARY_STORAGE_UUID = "primaryStorageUuid"; + private static final String ATTR_FORCE_ADOPTABLE = "forceAdoptable"; private static final String TAG_VOLUME = "volume"; private static final String ATTR_TYPE = "type"; private static final String ATTR_FS_UUID = "fsUuid"; @@ -276,6 +282,8 @@ class MountService extends IMountService.Stub private ArrayMap<String, VolumeRecord> mRecords = new ArrayMap<>(); @GuardedBy("mLock") private String mPrimaryStorageUuid; + @GuardedBy("mLock") + private boolean mForceAdoptable; /** Map from disk ID to latches */ @GuardedBy("mLock") @@ -810,7 +818,8 @@ class MountService extends IMountService.Stub if (cooked.length != 3) break; final String id = cooked[1]; int flags = Integer.parseInt(cooked[2]); - if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)) { + if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false) + || mForceAdoptable) { flags |= DiskInfo.FLAG_ADOPTABLE; } mDisks.put(id, new DiskInfo(id, flags)); @@ -927,6 +936,12 @@ class MountService extends IMountService.Stub break; } + case VoldResponseCode.BENCHMARK_RESULT: { + final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class); + dropBox.addText(TAG_STORAGE_BENCHMARK, raw); + break; + } + case VoldResponseCode.FstrimCompleted: { EventLogTags.writeFstrimFinish(SystemClock.elapsedRealtime()); break; @@ -1199,6 +1214,7 @@ class MountService extends IMountService.Stub private void readSettingsLocked() { mRecords.clear(); mPrimaryStorageUuid = getDefaultPrimaryStorageUuid(); + mForceAdoptable = false; FileInputStream fis = null; try { @@ -1220,6 +1236,7 @@ class MountService extends IMountService.Stub mPrimaryStorageUuid = readStringAttribute(in, ATTR_PRIMARY_STORAGE_UUID); } + mForceAdoptable = readBooleanAttribute(in, ATTR_FORCE_ADOPTABLE, false); } else if (TAG_VOLUME.equals(tag)) { final VolumeRecord rec = readVolumeRecord(in); @@ -1249,6 +1266,7 @@ class MountService extends IMountService.Stub out.startTag(null, TAG_VOLUMES); writeIntAttribute(out, ATTR_VERSION, VERSION_FIX_PRIMARY); writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid); + writeBooleanAttribute(out, ATTR_FORCE_ADOPTABLE, mForceAdoptable); final int size = mRecords.size(); for (int i = 0; i < size; i++) { final VolumeRecord rec = mRecords.valueAt(i); @@ -1406,6 +1424,19 @@ class MountService extends IMountService.Stub } @Override + public long benchmark(String volId) { + enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS); + waitForReady(); + + try { + final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId); + return Long.parseLong(res.getMessage()); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override public void partitionPublic(String diskId) { enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS); waitForReady(); @@ -1520,6 +1551,21 @@ class MountService extends IMountService.Stub } @Override + public void setDebugFlags(int flags, int mask) { + enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); + waitForReady(); + + synchronized (mLock) { + if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) { + mForceAdoptable = (flags & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0; + } + + writeSettingsLocked(); + resetIfReadyAndConnected(); + } + } + + @Override public String getPrimaryStorageUuid() { enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); waitForReady(); @@ -3014,6 +3060,7 @@ class MountService extends IMountService.Stub pw.println(); pw.println("Primary storage UUID: " + mPrimaryStorageUuid); + pw.println("Force adoptable: " + mForceAdoptable); } synchronized (mObbMounts) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 8051104..a8ab667 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2441,7 +2441,6 @@ public final class ActivityManagerService extends ActivityManagerNative } } - long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); synchronized(bstats) { synchronized(mPidsSelfLocked) { @@ -2472,7 +2471,7 @@ public final class ActivityManagerService extends ActivityManagerNative pr.info.uid, pr.processName); } ps.addCpuTimeLocked(st.rel_utime - otherUTime, - st.rel_stime - otherSTime, cpuSpeedTimes); + st.rel_stime - otherSTime); pr.curCpuTime += st.rel_utime + st.rel_stime; } else { BatteryStatsImpl.Uid.Proc ps = st.batteryStats; @@ -2481,7 +2480,7 @@ public final class ActivityManagerService extends ActivityManagerNative bstats.mapUid(st.uid), st.name); } ps.addCpuTimeLocked(st.rel_utime - otherUTime, - st.rel_stime - otherSTime, cpuSpeedTimes); + st.rel_stime - otherSTime); } } final int userTime = mProcessCpuTracker.getLastUserTime(); @@ -2492,7 +2491,7 @@ public final class ActivityManagerService extends ActivityManagerNative final int idleTime = mProcessCpuTracker.getLastIdleTime(); bstats.finishAddingCpuLocked(perc, remainUTime, remainSTime, totalUTime, totalSTime, userTime, systemTime, - iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes); + iowaitTime, irqTime, softIrqTime, idleTime); } } } @@ -16144,10 +16143,7 @@ public final class ActivityManagerService extends ActivityManagerNative final int uid = intentExtras != null ? intentExtras.getInt(Intent.EXTRA_UID) : -1; if (uid >= 0) { - BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); - synchronized (bs) { - bs.removeUidStatsLocked(uid); - } + mBatteryStatsService.removeUid(uid); mAppOpsService.uidRemoved(uid); } break; diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 58665d7..a61223a 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -64,6 +64,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub implements PowerManagerInternal.LowPowerModeListener { static final String TAG = "BatteryStatsService"; + private boolean mFirstExternalStatsUpdate = true; static IBatteryStats sService; final BatteryStatsImpl mStats; final BatteryStatsHandler mHandler; @@ -177,6 +178,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub // These are for direct use by the activity manager... + /** + * Remove a UID from the BatteryStats and BatteryStats' external dependencies. + */ + void removeUid(int uid) { + synchronized (mStats) { + mStats.removeUidStatsLocked(uid); + } + } + void addIsolatedUid(int isolatedUid, int appUid) { synchronized (mStats) { mStats.addIsolatedUidLocked(isolatedUid, appUid); @@ -1150,11 +1160,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub mStats.addHistoryEventLocked(elapsedRealtime, uptime, BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0); } + mStats.updateCpuTimeLocked(mFirstExternalStatsUpdate); mStats.updateKernelWakelocksLocked(); mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime()); mStats.updateWifiStateLocked(wifiEnergyInfo); mStats.updateBluetoothStateLocked(bluetoothEnergyInfo); } + + if (mFirstExternalStatsUpdate) { + // We have read the stats for the first time, which means we have a baseline + // from which to calculate delta. + mFirstExternalStatsUpdate = false; + } } } } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index b505f7e..7024ec8 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -17,9 +17,12 @@ package com.android.server.pm; import android.annotation.Nullable; +import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageParser; +import android.os.PowerManager; import android.os.UserHandle; +import android.os.WorkSource; import android.util.ArraySet; import android.util.Log; import android.util.Slog; @@ -50,8 +53,14 @@ final class PackageDexOptimizer { private final PackageManagerService mPackageManagerService; private ArraySet<PackageParser.Package> mDeferredDexOpt; + private final PowerManager.WakeLock mDexoptWakeLock; + private volatile boolean mSystemReady; + PackageDexOptimizer(PackageManagerService packageManagerService) { this.mPackageManagerService = packageManagerService; + PowerManager powerManager = (PowerManager)packageManagerService.mContext.getSystemService( + Context.POWER_SERVICE); + mDexoptWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*dexopt*"); } /** @@ -71,7 +80,18 @@ final class PackageDexOptimizer { done = null; } synchronized (mPackageManagerService.mInstallLock) { - return performDexOptLI(pkg, instructionSets, forceDex, defer, done); + final boolean useLock = mSystemReady; + if (useLock) { + mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid)); + mDexoptWakeLock.acquire(); + } + try { + return performDexOptLI(pkg, instructionSets, forceDex, defer, done); + } finally { + if (useLock) { + mDexoptWakeLock.release(); + } + } } } @@ -242,4 +262,8 @@ final class PackageDexOptimizer { } mDeferredDexOpt.add(pkg); } + + void systemReady() { + mSystemReady = true; + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8e0cdf1..509289b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -13486,6 +13486,7 @@ public class PackageManagerService extends IPackageManager.Stub { storage.registerListener(mStorageListener); mInstallerService.systemReady(); + mPackageDexOptimizer.systemReady(); } @Override diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 025ede5..91639c5 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -189,16 +189,16 @@ void versionStylesForCompat(const std::shared_ptr<ResourceTable>& table) { } struct CompileItem { - Source source; ResourceName name; ConfigDescription config; + Source source; std::string extension; }; struct LinkItem { - Source source; ResourceName name; ConfigDescription config; + Source source; std::string originalPath; ZipFile* apk; std::u16string originalPackage; @@ -236,7 +236,8 @@ std::string buildFileReference(const LinkItem& item) { return buildFileReference(item.name, item.config, getExtension<char>(item.originalPath)); } -bool addFileReference(const std::shared_ptr<ResourceTable>& table, const CompileItem& item) { +template <typename T> +bool addFileReference(const std::shared_ptr<ResourceTable>& table, const T& item) { StringPool& pool = table->getValueStringPool(); StringPool::Ref ref = pool.makeRef(util::utf8ToUtf16(buildFileReference(item)), StringPool::Context{ 0, item.config }); @@ -334,9 +335,40 @@ bool compileXml(const AaptOptions& options, const std::shared_ptr<ResourceTable> return true; } -bool linkXml(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver, - const LinkItem& item, const void* data, size_t dataLen, ZipFile* outApk, - std::queue<LinkItem>* outQueue) { +/** + * Determines if a layout should be auto generated based on SDK level. We do not + * generate a layout if there is already a layout defined whose SDK version is greater than + * the one we want to generate. + */ +bool shouldGenerateVersionedResource(const std::shared_ptr<const ResourceTable>& table, + const ResourceName& name, const ConfigDescription& config, + int sdkVersionToGenerate) { + assert(sdkVersionToGenerate > config.sdkVersion); + const ResourceTableType* type; + const ResourceEntry* entry; + std::tie(type, entry) = table->findResource(name); + assert(type && entry); + + auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), config, + [](const ResourceConfigValue& lhs, const ConfigDescription& config) -> bool { + return lhs.config < config; + }); + + assert(iter != entry->values.end()); + ++iter; + + if (iter == entry->values.end()) { + return true; + } + + ConfigDescription newConfig = config; + newConfig.sdkVersion = sdkVersionToGenerate; + return newConfig < iter->config; +} + +bool linkXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table, + const std::shared_ptr<IResolver>& resolver, const LinkItem& item, + const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue) { std::shared_ptr<android::ResXMLTree> tree = std::make_shared<android::ResXMLTree>(); if (tree->setTo(data, dataLen, false) != android::NO_ERROR) { return false; @@ -376,9 +408,21 @@ bool linkXml(const AaptOptions& options, const std::shared_ptr<IResolver>& resol if (minStrippedSdk.value() > 0) { // Something was stripped, so let's generate a new file // with the version of the smallest SDK version stripped. - LinkItem newWork = item; - newWork.config.sdkVersion = minStrippedSdk.value(); - outQueue->push(newWork); + // We can only generate a versioned layout if there doesn't exist a layout + // with sdk version greater than the current one but less than the one we + // want to generate. + if (shouldGenerateVersionedResource(table, item.name, item.config, + minStrippedSdk.value())) { + LinkItem newWork = item; + newWork.config.sdkVersion = minStrippedSdk.value(); + outQueue->push(newWork); + + if (!addFileReference(table, newWork)) { + Logger::error(options.output) << "failed to add auto-versioned resource '" + << newWork.name << "'." << std::endl; + return false; + } + } } if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressDeflated, @@ -604,7 +648,7 @@ static void addApkFilesToLinkQueue(const std::u16string& package, const Source& newSource.path += "/"; newSource.path += pathUtf8; outLinkQueue->push(LinkItem{ - newSource, name, value.config, pathUtf8, apk.get(), + name, value.config, newSource, pathUtf8, apk.get(), table->getPackage() }); // Now rewrite the file path. if (mangle) { @@ -743,8 +787,8 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT void* uncompressedData = item.apk->uncompress(entry); assert(uncompressedData); - if (!linkXml(options, resolver, item, uncompressedData, entry->getUncompressedLen(), - &outApk, &linkQueue)) { + if (!linkXml(options, outTable, resolver, item, uncompressedData, + entry->getUncompressedLen(), &outApk, &linkQueue)) { Logger::error(options.output) << "failed to link '" << item.originalPath << "'." << std::endl; return false; @@ -862,9 +906,9 @@ bool compile(const AaptOptions& options, const std::shared_ptr<ResourceTable>& t } compileQueue.push(CompileItem{ - source, ResourceName{ table->getPackage(), *type, pathData.name }, pathData.config, + source, pathData.extension }); } diff --git a/tools/aapt2/data/Makefile b/tools/aapt2/data/Makefile index 6b5fafa..ce5201b 100644 --- a/tools/aapt2/data/Makefile +++ b/tools/aapt2/data/Makefile @@ -49,7 +49,7 @@ $(info PRIVATE_INTERMEDIATE_TABLES = $(PRIVATE_INTERMEDIATE_TABLES)) # returns: out/values-v4.apk: res/values-v4/styles.xml res/values-v4/colors.xml define make-collect-rule $(LOCAL_OUT)/$1.apk: $(filter $(LOCAL_RESOURCE_DIR)/$1/%,$(PRIVATE_RESOURCES)) - $(AAPT) compile --package $(LOCAL_PACKAGE) --binding $(LOCAL_GEN) -o $$@ $$^ + $(AAPT) compile --package $(LOCAL_PACKAGE) -o $$@ $$^ endef # Collect: out/values-v4.apk <- res/values-v4/styles.xml res/values-v4/colors.xml |