diff options
53 files changed, 930 insertions, 211 deletions
diff --git a/api/current.txt b/api/current.txt index a129a63..462ca0a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -66,6 +66,7 @@ package android { field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST"; field public static final java.lang.String FLASHLIGHT = "android.permission.FLASHLIGHT"; field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; + field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE"; field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS"; field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH"; @@ -9445,6 +9446,7 @@ package android.content.pm { method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager); field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 + field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 diff --git a/api/system-current.txt b/api/system-current.txt index c2fd0d1..d6e3c03 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -95,6 +95,7 @@ package android { field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK"; field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES"; field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; + field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS"; field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE"; field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE"; @@ -9783,6 +9784,7 @@ package android.content.pm { method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager); field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 + field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 0dad4dc..0a1ba4d 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -81,6 +81,8 @@ public final class Sm { runUnmount(); } else if ("format".equals(op)) { runFormat(); + } else if ("benchmark".equals(op)) { + runBenchmark(); } else if ("forget".equals(op)) { runForget(); } else { @@ -89,9 +91,12 @@ public final class Sm { } public void runListDisks() throws RemoteException { + final boolean onlyAdoptable = "adoptable".equals(nextArg()); final DiskInfo[] disks = mSm.getDisks(); for (DiskInfo disk : disks) { - System.out.println(disk.getId()); + if (!onlyAdoptable || disk.isAdoptable()) { + System.out.println(disk.getId()); + } } } @@ -161,6 +166,11 @@ public final class Sm { mSm.format(volId); } + public void runBenchmark() throws RemoteException { + final String volId = nextArg(); + mSm.benchmark(volId); + } + public void runForget() throws RemoteException{ final String fsUuid = nextArg(); if ("all".equals(fsUuid)) { @@ -180,7 +190,7 @@ public final class Sm { } private static int showUsage() { - System.err.println("usage: sm list-disks"); + System.err.println("usage: sm list-disks [adoptable]"); System.err.println(" sm list-volumes [public|private|emulated|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); @@ -190,6 +200,7 @@ public final class Sm { System.err.println(" sm mount VOLUME"); System.err.println(" sm unmount VOLUME"); System.err.println(" sm format VOLUME"); + System.err.println(" sm benchmark VOLUME"); System.err.println(""); System.err.println(" sm forget [UUID|all]"); System.err.println(""); diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 40126d6..ee0fc91 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.ComponentName; import android.graphics.Matrix; import android.graphics.Rect; +import android.os.BadParcelableException; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; @@ -31,8 +32,12 @@ public class AssistStructure implements Parcelable { static final String TAG = "AssistStructure"; static final boolean DEBUG_PARCEL = false; + static final boolean DEBUG_PARCEL_CHILDREN = false; static final boolean DEBUG_PARCEL_TREE = false; + static final int VALIDATE_WINDOW_TOKEN = 0x11111111; + static final int VALIDATE_VIEW_TOKEN = 0x22222222; + boolean mHaveData; ComponentName mActivityComponent; @@ -173,6 +178,26 @@ public class AssistStructure implements Parcelable { mCurViewStackEntry = entry; } + void writeView(ViewNode child, Parcel out, PooledStringWriter pwriter, int levelAdj) { + if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition() + + ", windows=" + mNumWrittenWindows + + ", views=" + mNumWrittenViews + + ", level=" + (mCurViewStackPos+levelAdj)); + out.writeInt(VALIDATE_VIEW_TOKEN); + int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix); + mNumWrittenViews++; + // If the child has children, push it on the stack to write them next. + if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) { + if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG, + "Preparing to write " + child.mChildren.length + + " children: @ #" + mNumWrittenViews + + ", level " + (mCurViewStackPos+levelAdj)); + out.writeInt(child.mChildren.length); + int pos = ++mCurViewStackPos; + pushViewStackEntry(child, pos); + } + } + boolean writeNextEntryToParcel(AssistStructure as, Parcel out, PooledStringWriter pwriter) { // Write next view node if appropriate. if (mCurViewStackEntry != null) { @@ -182,20 +207,7 @@ public class AssistStructure implements Parcelable { + mCurViewStackEntry.curChild + " in " + mCurViewStackEntry.node); ViewNode child = mCurViewStackEntry.node.mChildren[mCurViewStackEntry.curChild]; mCurViewStackEntry.curChild++; - if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition() - + ", windows=" + mNumWrittenWindows - + ", views=" + mNumWrittenViews); - out.writeInt(1); - int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix); - mNumWrittenViews++; - // If the child has children, push it on the stack to write them next. - if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) { - if (DEBUG_PARCEL_TREE) Log.d(TAG, "Preparing to write " - + child.mChildren.length + " children under " + child); - out.writeInt(child.mChildren.length); - int pos = ++mCurViewStackPos; - pushViewStackEntry(child, pos); - } + writeView(child, out, pwriter, 1); return true; } @@ -223,13 +235,13 @@ public class AssistStructure implements Parcelable { if (DEBUG_PARCEL) Log.d(TAG, "write window #" + pos + ": at " + out.dataPosition() + ", windows=" + mNumWrittenWindows + ", views=" + mNumWrittenViews); - out.writeInt(1); + out.writeInt(VALIDATE_WINDOW_TOKEN); win.writeSelfToParcel(out, pwriter, mTmpMatrix); mNumWrittenWindows++; ViewNode root = win.mRoot; mCurViewStackPos = 0; - if (DEBUG_PARCEL_TREE) Log.d(TAG, "Pushing initial root view " + root); - pushViewStackEntry(root, 0); + if (DEBUG_PARCEL_TREE) Log.d(TAG, "Writing initial root view " + root); + writeView(root, out, pwriter, 0); return true; } @@ -271,11 +283,16 @@ public class AssistStructure implements Parcelable { + ", views=" + mNumReadViews); } - Parcel readParcel() { + Parcel readParcel(int validateToken, int level) { if (DEBUG_PARCEL) Log.d(TAG, "readParcel: at " + mCurParcel.dataPosition() + ", avail=" + mCurParcel.dataAvail() + ", windows=" + mNumReadWindows - + ", views=" + mNumReadViews); - if (mCurParcel.readInt() != 0) { + + ", views=" + mNumReadViews + ", level=" + level); + int token = mCurParcel.readInt(); + if (token != 0) { + if (token != validateToken) { + throw new BadParcelableException("Got token " + Integer.toHexString(token) + + ", expected token " + Integer.toHexString(validateToken)); + } return mCurParcel; } // We have run out of partial data, need to read another batch. @@ -406,7 +423,7 @@ public class AssistStructure implements Parcelable { } WindowNode(ParcelTransferReader reader) { - Parcel in = reader.readParcel(); + Parcel in = reader.readParcel(VALIDATE_WINDOW_TOKEN, 0); reader.mNumReadWindows++; mX = in.readInt(); mY = in.readInt(); @@ -414,7 +431,7 @@ public class AssistStructure implements Parcelable { mHeight = in.readInt(); mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mDisplayId = in.readInt(); - mRoot = new ViewNode(reader); + mRoot = new ViewNode(reader, 0); } void writeSelfToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) { @@ -548,8 +565,8 @@ public class AssistStructure implements Parcelable { ViewNode() { } - ViewNode(ParcelTransferReader reader) { - final Parcel in = reader.readParcel(); + ViewNode(ParcelTransferReader reader, int nestingLevel) { + final Parcel in = reader.readParcel(VALIDATE_VIEW_TOKEN, nestingLevel); reader.mNumReadViews++; final PooledStringReader preader = reader.mStringReader; mClassName = preader.readString(); @@ -604,9 +621,13 @@ public class AssistStructure implements Parcelable { } if ((flags&FLAGS_HAS_CHILDREN) != 0) { final int NCHILDREN = in.readInt(); + if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG, + "Preparing to read " + NCHILDREN + + " children: @ #" + reader.mNumReadViews + + ", level " + nestingLevel); mChildren = new ViewNode[NCHILDREN]; for (int i=0; i<NCHILDREN; i++) { - mChildren[i] = new ViewNode(reader); + mChildren[i] = new ViewNode(reader, nestingLevel + 1); } } } diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java index e09ab56..2ba8774 100644 --- a/core/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java @@ -79,6 +79,10 @@ public final class BluetoothLeScanner { * delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * An app must hold + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission + * in order to get results. * * @param callback Callback used to deliver scan results. * @throws IllegalArgumentException If {@code callback} is null. @@ -95,6 +99,10 @@ public final class BluetoothLeScanner { * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * An app must hold + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission + * in order to get results. * * @param filters {@link ScanFilter}s for finding exact BLE devices. * @param settings Settings for the scan. diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 2828d83..d514513 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -145,12 +145,10 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_COSTS_MONEY = 1<<0; /** - * Flag for {@link #protectionLevel}, corresponding - * to the <code>hide</code> value of - * {@link android.R.attr#permissionFlags}. - * @hide + * Flag for {@link #flags}, indicating that this permission has been + * installed into the system's globally defined permissions. */ - public static final int PROTECTION_FLAG_HIDE = 1<<1; + public static final int FLAG_INSTALLED = 1<<30; /** * Additional flags about this permission as given by @@ -210,6 +208,15 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) { protLevel += "|pre23"; } + if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) { + protLevel += "|installer"; + } + if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) { + protLevel += "|verifier"; + } + if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) { + protLevel += "|preinstalled"; + } return protLevel; } diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 864225a..af4c2bc 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.NonNull; import android.provider.DocumentsContract.Document; import android.system.ErrnoException; import android.system.Os; @@ -69,6 +70,8 @@ public class FileUtils { /** Regular expression for safe filenames: no spaces or metacharacters */ private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); + private static final File[] EMPTY = new File[0]; + /** * Set owner and mode of of given {@link File}. * @@ -634,4 +637,13 @@ public class FileUtils { return new File(parent, name + "." + ext); } } + + public static @NonNull File[] listFilesOrEmpty(File dir) { + File[] res = dir.listFiles(); + if (res != null) { + return res; + } else { + return EMPTY; + } + } } diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl index b768852..d3eec1e 100644 --- a/core/java/android/os/IDeviceIdleController.aidl +++ b/core/java/android/os/IDeviceIdleController.aidl @@ -29,5 +29,6 @@ interface IDeviceIdleController { boolean isPowerSaveWhitelistApp(String name); void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason); long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason); + long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason); void exitIdle(String reason); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fff355b..a79970c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7578,14 +7578,6 @@ public final class Settings { public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; /** - * Global override to disable VoLTE (independent of user setting) - * <p> - * Type: int (1 for disable VoLTE, 0 to use user configuration) - * @hide - */ - public static final String VOLTE_FEATURE_DISABLED = "volte_feature_disabled"; - - /** * Whether user can enable/disable LTE as a preferred network. A carrier might control * this via gservices, OMA-DM, carrier app, etc. * <p> diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java index e3ce6f2..a12b15e 100644 --- a/core/java/android/widget/AppSecurityPermissions.java +++ b/core/java/android/widget/AppSecurityPermissions.java @@ -533,6 +533,12 @@ public class AppSecurityPermissions { int existingReqFlags) { final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; final boolean isNormal = (base == PermissionInfo.PROTECTION_NORMAL); + + // We do not show normal permissions in the UI. + if (isNormal) { + return false; + } + final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS) || ((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_PRE23) != 0); final boolean isRequired = @@ -546,7 +552,7 @@ public class AppSecurityPermissions { // Dangerous and normal permissions are always shown to the user if the permission // is required, or it was previously granted - if ((isNormal || isDangerous) && (isRequired || wasGranted || isGranted)) { + if (isDangerous && (isRequired || wasGranted || isGranted)) { return true; } diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index dac02fa..6a561e6 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -731,7 +731,8 @@ public class RelativeLayout extends ViewGroup { // Negative values in a mySize value in RelativeLayout // measurement is code for, "we got an unspecified mode in the // RelativeLayout's measure spec." - if (mySize < 0 && !mAllowBrokenMeasureSpecs) { + final boolean isUnspecified = mySize < 0; + if (isUnspecified && !mAllowBrokenMeasureSpecs) { if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) { // Constraints fixed both edges, so child has an exact size. childSpecSize = Math.max(0, childEnd - childStart); @@ -767,7 +768,7 @@ public class RelativeLayout extends ViewGroup { if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) { // Constraints fixed both edges, so child must be an exact size. - childSpecMode = MeasureSpec.EXACTLY; + childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY; childSpecSize = Math.max(0, maxAvailable); } else { if (childSize >= 0) { @@ -784,7 +785,7 @@ public class RelativeLayout extends ViewGroup { } else if (childSize == LayoutParams.MATCH_PARENT) { // Child wanted to be as big as possible. Give all available // space. - childSpecMode = MeasureSpec.EXACTLY; + childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY; childSpecSize = Math.max(0, maxAvailable); } else if (childSize == LayoutParams.WRAP_CONTENT) { // Child wants to wrap content. Use AT_MOST to communicate diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index cbe535f..91ae27b 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -27,7 +27,20 @@ import android.view.View; */ public class MetricsLogger implements MetricsConstants { // Temporary constants go here, to await migration to MetricsConstants. - // next value is 227; + // next value is 238; + + public static final int TUNER = 227; + public static final int TUNER_QS = 228; + public static final int TUNER_DEMO_MODE = 229; + + public static final int TUNER_QS_REORDER = 230; + public static final int TUNER_QS_ADD = 231; + public static final int TUNER_QS_REMOVE = 232; + public static final int TUNER_STATUS_BAR_ENABLE = 233; + public static final int TUNER_STATUS_BAR_DISABLE = 234; + public static final int TUNER_DEMO_MODE_ENABLED = 235; + public static final int TUNER_DEMO_MODE_ON = 236; + public static final int TUNER_BATTERY_PERCENTAGE = 237; public static void visible(Context context, int category) throws IllegalArgumentException { if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) { diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 264b8c1..9caf78a 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; /** * A helper class for retrieving the power usage information for all applications and services. @@ -267,15 +268,20 @@ public final class BatteryStatsHelper { public static String makemAh(double power) { if (power == 0) return "0"; - else if (power < .00001) return String.format("%.8f", power); - else if (power < .0001) return String.format("%.7f", power); - else if (power < .001) return String.format("%.6f", power); - else if (power < .01) return String.format("%.5f", power); - else if (power < .1) return String.format("%.4f", power); - else if (power < 1) return String.format("%.3f", power); - else if (power < 10) return String.format("%.2f", power); - else if (power < 100) return String.format("%.1f", power); - else return String.format("%.0f", power); + + final String format; + if (power < .00001) format = "%.8f"; + else if (power < .0001) format = "%.7f"; + else if (power < .001) format = "%.6f"; + else if (power < .01) format = "%.5f"; + else if (power < .1) format = "%.4f"; + else if (power < 1) format = "%.3f"; + else if (power < 10) format = "%.2f"; + else if (power < 100) format = "%.1f"; + else format = "%.0f"; + + // Use English locale because this is never used in UI (only in checkin and dump). + return String.format(Locale.ENGLISH, format, power); } /** diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 60f47d6..e7c58f4 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -2560,14 +2560,24 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); } + boolean ensureStartClockTime(final long currentTime) { + final long ABOUT_ONE_YEAR = 365*24*60*60*1000L; + if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) { + // If the start clock time has changed by more than a year, then presumably + // the previous time was completely bogus. So we are going to figure out a + // new time based on how much time has elapsed since we started counting. + mStartClockTime = currentTime - (SystemClock.elapsedRealtime()-(mRealtimeStart/1000)); + return true; + } + return false; + } + public void noteCurrentTimeChangedLocked() { final long currentTime = System.currentTimeMillis(); final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); - if (isStartClockTimeValid()) { - mStartClockTime = currentTime; - } + ensureStartClockTime(currentTime); } public void noteProcessStartLocked(String name, int uid) { @@ -4306,19 +4316,11 @@ public final class BatteryStatsImpl extends BatteryStats { } } - boolean isStartClockTimeValid() { - return mStartClockTime > 365*24*60*60*1000L; - } - @Override public long getStartClockTime() { - if (!isStartClockTimeValid()) { - // If the last clock time we got was very small, then we hadn't had a real - // time yet, so try to get it again. - mStartClockTime = System.currentTimeMillis(); - if (isStartClockTimeValid()) { - recordCurrentTimeChangeLocked(mStartClockTime, SystemClock.elapsedRealtime(), - SystemClock.uptimeMillis()); - } + final long currentTime = System.currentTimeMillis(); + if (ensureStartClockTime(currentTime)) { + recordCurrentTimeChangeLocked(currentTime, SystemClock.elapsedRealtime(), + SystemClock.uptimeMillis()); } return mStartClockTime; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 92862f5..3e22e09 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1749,6 +1749,10 @@ <!-- ==================================== --> <eat-comment /> + <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. --> + <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows applications to RW to diagnostic resources. <p>Not for use by third-party applications. --> <permission android:name="android.permission.DIAGNOSTIC" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index be2b962..0533317 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1001,7 +1001,7 @@ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puedes cambiar esta opción más tarde en Ajustes > Aplicaciones."</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permitir siempre"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"No permitir nunca"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string> + <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM retirada"</string> <string name="sim_removed_message" msgid="5450336489923274918">"La red móvil no estará disponible hasta que reinicies el dispositivo con una tarjeta SIM válida insertada."</string> <string name="sim_done_button" msgid="827949989369963775">"Listo"</string> <string name="sim_added_title" msgid="3719670512889674693">"Tarjeta SIM añadida"</string> diff --git a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml new file mode 100644 index 0000000..bad49c3 --- /dev/null +++ b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 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 my 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. +*/ + --> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcOperatorErrorAlertMessages"> + <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item> + </string-array> + <string-array name="wfcOperatorErrorNotificationMessages"> + <item msgid="483847327467331298">"Faça registro na sua operadora"</item> + </string-array> + <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string> +</resources> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index be72354..df9f2805 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -1042,7 +1042,7 @@ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string> <string name="usb_notification_message" msgid="7347368030849048437">"Нэмэлт сонголтыг харахын тулд дарна."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебаг хийхийг идэвхгүй болгох бол хүрнэ үү."</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебагийг идэвхгүй болгох бол хүрнэ үү."</string> <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Гар сонгох"</string> <string name="show_ime" msgid="9157568568695230830">"Оруулах аргыг харуулах"</string> diff --git a/core/res/res/values-pt-rBR-watch/strings.xml b/core/res/res/values-pt-rBR-watch/strings.xml new file mode 100644 index 0000000..120e4a5 --- /dev/null +++ b/core/res/res/values-pt-rBR-watch/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="android_upgrading_apk" msgid="1090732262010398759">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string> +</resources> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 549c5ef7..2bde626 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -21,7 +21,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="5973789783504771878">"kilobajt"</string> + <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string> <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 06b6389..54848e9 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -408,6 +408,7 @@ <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer> <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_5">36</integer> <string translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string> + <string translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string> <bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index fe82b8c..8070986 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -337,6 +337,7 @@ <java-symbol type="integer" name="config_wifi_active_rx_cur_ma" /> <java-symbol type="integer" name="config_wifi_tx_cur_ma" /> <java-symbol type="integer" name="config_wifi_operating_voltage_mv" /> + <java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" /> <java-symbol type="bool" name="editable_voicemailnumber" /> diff --git a/docs/html/design/wear/structure.jd b/docs/html/design/wear/structure.jd index c1d9ef9..768aa7f 100644 --- a/docs/html/design/wear/structure.jd +++ b/docs/html/design/wear/structure.jd @@ -166,8 +166,11 @@ href="#2DPicker">2D picker</a> is always available.</p> <li>A map that asks the user to drop a pin should exit when the pin is dropped.</li> <li>A short game can exit when the game finishes.</li> <li>A drawing app can finish after 5 seconds of inactivity.</li> + + <p class="note">An app generally should not exit in {@link android.app.Activity#onPause onPause()}. This is because events such as <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up">Heads-up Notifications</a> can trigger the {@link android.app.Activity#onPause() onPause()} callback.</p> </ul> + <h3>Manually exiting</h3> <p>Even with logical exit points like these, some cases may exist where the user may want to diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index a1b8a3b..025029e 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -23,9 +23,11 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.Activity; import android.content.ContentUris; import android.content.Context; +import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Environment; +import android.os.Process; import android.provider.MediaStore; import android.provider.Settings; import android.provider.Settings.System; @@ -359,7 +361,10 @@ public class RingtoneManager { * If {@link RingtoneManager#RingtoneManager(Activity)} was not used, the * caller should manage the returned cursor through its activity's life * cycle to prevent leaking the cursor. - * + * <p> + * Note that the list of ringtones available will differ depending on whether the caller + * has the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission. + * * @return A {@link Cursor} of all the ringtones available. * @see #ID_COLUMN_INDEX * @see #TITLE_COLUMN_INDEX @@ -455,8 +460,10 @@ public class RingtoneManager { /** * Returns a valid ringtone URI. No guarantees on which it returns. If it - * cannot find one, returns null. - * + * cannot find one, returns null. If it can only find one on external storage and the caller + * doesn't have the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission, + * returns null. + * * @param context The context to use for querying. * @return A ringtone URI, or null if one cannot be found. */ @@ -495,6 +502,12 @@ public class RingtoneManager { } private Cursor getMediaRingtones() { + if (PackageManager.PERMISSION_GRANTED != mContext.checkPermission( + android.Manifest.permission.READ_EXTERNAL_STORAGE, + Process.myPid(), Process.myUid())) { + Log.w(TAG, "No READ_EXTERNAL_STORAGE permission, ignoring ringtones on ext storage"); + return null; + } // Get the external media cursor. First check to see if it is mounted. final String status = Environment.getExternalStorageState(); diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 86e8560..053d43b6 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.app.ActivityManager; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -1200,12 +1201,15 @@ public abstract class TvInputService extends Service { // We make the overlay view non-focusable and non-touchable so that // the application that owns the window token can decide whether to consume or // dispatch the input events. - int flag = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; + int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + if (ActivityManager.isHighEndGfx()) { + flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + } mWindowParams = new WindowManager.LayoutParams( frame.right - frame.left, frame.bottom - frame.top, - frame.left, frame.top, type, flag, PixelFormat.TRANSPARENT); + frame.left, frame.top, type, flags, PixelFormat.TRANSPARENT); mWindowParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; mWindowParams.gravity = Gravity.START | Gravity.TOP; diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 6e5dc3f..fea7f94 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -405,5 +405,13 @@ android:exported="true" android:singleUser="true" android:permission="android.permission.BIND_DREAM_SERVICE" /> + + <receiver + android:name=".tuner.TunerService$ClearReceiver" + android:exported="false"> + <intent-filter> + <action android:name="com.android.systemui.action.CLEAR_TUNER" /> + </intent-filter> + </receiver> </application> </manifest> diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml index e27423f..0596aa4 100644 --- a/packages/SystemUI/res/drawable-nodpi/tuner.xml +++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml @@ -1,7 +1,7 @@ <!-- - Copyright (C) 2015 The Android Open Source Project + Copyright (C) 2015 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); + 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 @@ -14,14 +14,11 @@ 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"> + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.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"/> + android:fillColor="#FFFFFFFF" + android:pathData="M22.7,19.0l-9.1,-9.1c0.9,-2.0 0.4,-5.0 -1.5,-6.9 -2.0,-2.0 -5.0,-2.4 -7.4,-1.3L9.0,6.0 6.0,9.0 1.6,4.7C0.4,7.0 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1.0,0.4 1.4,0.0l2.3,-2.3c0.5,-0.4 0.5,-1.0 0.1,-1.4z"/> </vector> diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 1488ad6..444f0f0 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -26,7 +26,7 @@ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView android:id="@+id/keyguard_indication_text" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_gravity="bottom|center_horizontal" diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index 7262ed2..8c8a3dd 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -44,14 +44,31 @@ android:scaleType="centerInside"/> </com.android.systemui.statusbar.phone.MultiUserSwitch> - <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/settings_button" - style="@android:style/Widget.Material.Button.Borderless" - android:layout_toStartOf="@id/multi_user_switch" + <com.android.keyguard.AlphaOptimizedLinearLayout + android:id="@+id/settings_button_container" android:layout_width="48dp" android:layout_height="@dimen/status_bar_header_height" - android:background="@drawable/ripple_drawable" - android:src="@drawable/ic_settings" - android:contentDescription="@string/accessibility_desc_settings" /> + android:paddingStart="12dp" + android:clipChildren="false" + android:clipToPadding="false" + android:layout_toStartOf="@id/multi_user_switch"> + + <com.android.systemui.statusbar.phone.SettingsButton android:id="@+id/settings_button" + style="@android:style/Widget.Material.Button.Borderless" + android:layout_width="24dp" + android:layout_height="@dimen/status_bar_header_height" + android:background="@drawable/ripple_drawable" + android:src="@drawable/ic_settings" + android:contentDescription="@string/accessibility_desc_settings" /> + <com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/tuner_icon" + android:layout_width="12dp" + android:layout_height="@dimen/status_bar_header_height" + android:tint="#4DFFFFFF" + android:tintMode="src_in" + android:visibility="invisible" + android:src="@drawable/tuner" /> + + </com.android.keyguard.AlphaOptimizedLinearLayout> <LinearLayout android:id="@+id/system_icons_super_container" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index fcf7e3e..3eac84f 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1032,7 +1032,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">System UI tuner</string> + <string name="system_ui_tuner">System UI Tuner</string> <!-- Preference to show/hide embedded battery percentage [CHAR LIMIT=50] --> <string name="show_battery_percentage">Show embedded battery percentage</string> @@ -1099,4 +1099,25 @@ <!-- Accessibility label for managed profile icon (not shown on screen) [CHAR LIMIT=NONE] --> <string name="accessibility_managed_profile">Work profile</string> + <!-- Title of warning when entering System UI tuner for first time [CHAR LIMIT=NONE] --> + <string name="tuner_warning_title">Fun for some but not for all</string> + + <!-- Warning for users entering the System UI tuner for the first time [CHAR LIMIT=NONE]--> + <string name="tuner_warning">System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution.</string> + + <!-- Warning for users entering the System UI tuner [CHAR LIMIT=NONE]--> + <string name="tuner_persistent_warning">These experimental features may change, break, or disappear in future releases. Proceed with caution.</string> + + <!-- Generic "got it" acceptance of dialog or cling [CHAR LIMIT=NONE] --> + <string name="got_it">Got it</string> + + <!-- Toast describing tuner has been enabled [CHAR LIMIT=NONE] --> + <string name="tuner_toast">Congrats! System UI Tuner has been added to Settings</string> + + <!-- Option to remove the tuner from settings [CHAR LIMIT=NONE] --> + <string name="remove_from_settings">Remove from Settings</string> + + <!-- Dialog asking if the tuner should really be removed from settings [CHAR LIMIT=NONE]--> + <string name="remove_from_settings_prompt">Remove System UI Tuner from Settings and stop using all of its features?"</string> + </resources> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 8c1acc3..3a41c3c 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -76,4 +76,8 @@ android:key="demo_mode" android:title="@string/demo_mode" /> + <Preference + android:summary="@string/tuner_persistent_warning" + android:selectable="false" /> + </PreferenceScreen> diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java index d406f5b..11996d0 100644 --- a/packages/SystemUI/src/com/android/systemui/DemoMode.java +++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java @@ -20,6 +20,8 @@ import android.os.Bundle; public interface DemoMode { + public static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed"; + void dispatchDemoCommand(String command, Bundle args); public static final String ACTION_DEMO = "com.android.systemui.demo"; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index f62dc59..a2e6632 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -729,11 +729,15 @@ public abstract class BaseStatusBar extends SystemUI implements } protected void setNotificationShown(StatusBarNotification n) { - mNotificationListener.setNotificationsShown(new String[] { n.getKey() }); + setNotificationsShown(new String[]{n.getKey()}); } protected void setNotificationsShown(String[] keys) { - mNotificationListener.setNotificationsShown(keys); + try { + mNotificationListener.setNotificationsShown(keys); + } catch (RuntimeException e) { + Log.d(TAG, "failed setNotificationsShown: ", e); + } } protected boolean isCurrentProfile(int userId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index d829299..e1ba2d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -198,6 +198,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true; + public static final String ACTION_FAKE_ARTWORK = "fake_artwork"; + private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; private static final int MSG_CLOSE_PANELS = 1001; private static final int MSG_OPEN_SETTINGS_PANEL = 1002; @@ -890,11 +892,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); + context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); + + IntentFilter demoFilter = new IntentFilter(); if (DEBUG_MEDIA_FAKE_ARTWORK) { - filter.addAction("fake_artwork"); + demoFilter.addAction(ACTION_FAKE_ARTWORK); } - filter.addAction(ACTION_DEMO); - context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); + demoFilter.addAction(ACTION_DEMO); + context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter, + android.Manifest.permission.DUMP, null); // listen for USER_SETUP_COMPLETE setting (per-user) resetUserSetupObserver(); @@ -2852,7 +2858,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScreenOn = true; notifyNavigationBarScreenOn(true); } - else if (ACTION_DEMO.equals(action)) { + } + }; + + private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + if (DEBUG) Log.v(TAG, "onReceive: " + intent); + String action = intent.getAction(); + if (ACTION_DEMO.equals(action)) { Bundle bundle = intent.getExtras(); if (bundle != null) { String command = bundle.getString("command", "").trim().toLowerCase(); @@ -2864,7 +2877,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } } - } else if ("fake_artwork".equals(action)) { + } else if (ACTION_FAKE_ARTWORK.equals(action)) { if (DEBUG_MEDIA_FAKE_ARTWORK) { updateMediaMetaData(true); } @@ -3188,6 +3201,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mHandlerThread = null; } mContext.unregisterReceiver(mBroadcastReceiver); + mContext.unregisterReceiver(mDemoReceiver); mAssistManager.destroy(); final SignalClusterView signalCluster = @@ -3211,7 +3225,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void dispatchDemoCommand(String command, Bundle args) { if (!mDemoModeAllowed) { mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(), - "sysui_demo_allowed", 0) != 0; + DEMO_MODE_ALLOWED, 0) != 0; } if (!mDemoModeAllowed) return; if (command.equals(COMMAND_ENTER)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java new file mode 100644 index 0000000..a1e9ece --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java @@ -0,0 +1,174 @@ +/* + * 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.statusbar.phone; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; + +import com.android.keyguard.AlphaOptimizedImageButton; + +public class SettingsButton extends AlphaOptimizedImageButton { + + private static final long LONG_PRESS_LENGTH = 1000; + private static final long ACCEL_LENGTH = 750; + private static final long FULL_SPEED_LENGTH = 375; + private static final long RUN_DURATION = 350; + + private boolean mUpToSpeed; + private ObjectAnimator mAnimator; + + private float mSlop; + + public SettingsButton(Context context, AttributeSet attrs) { + super(context, attrs); + mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); + } + + public boolean isAnimating() { + return mAnimator != null && mAnimator.isRunning(); + } + + public boolean isTunerClick() { + return mUpToSpeed; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + postDelayed(mLongPressCallback, LONG_PRESS_LENGTH); + break; + case MotionEvent.ACTION_UP: + if (mUpToSpeed) { + startExitAnimation(); + } else { + cancelLongClick(); + } + break; + case MotionEvent.ACTION_CANCEL: + cancelLongClick(); + break; + case MotionEvent.ACTION_MOVE: + float x = event.getX(); + float y = event.getY(); + if ((x < -mSlop) || (y < -mSlop) || (x > getWidth() + mSlop) + || (y > getHeight() + mSlop)) { + cancelLongClick(); + } + break; + } + return super.onTouchEvent(event); + } + + private void cancelLongClick() { + cancelAnimation(); + mUpToSpeed = false; + removeCallbacks(mLongPressCallback); + } + + private void cancelAnimation() { + if (mAnimator != null) { + mAnimator.removeAllListeners(); + mAnimator.cancel(); + mAnimator = null; + } + } + + private void startExitAnimation() { + animate() + .translationX(((View) getParent().getParent()).getWidth() - getX()) + .alpha(0) + .setDuration(RUN_DURATION) + .setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.accelerate_cubic)) + .setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + setAlpha(1f); + setTranslationX(0); + cancelLongClick(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + }) + .start(); + } + + protected void startAccelSpin() { + cancelAnimation(); + mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360); + mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.accelerate_quad)); + mAnimator.setDuration(ACCEL_LENGTH); + mAnimator.addListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + startContinuousSpin(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + }); + mAnimator.start(); + } + + protected void startContinuousSpin() { + cancelAnimation(); + mUpToSpeed = true; + mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360); + mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.linear)); + mAnimator.setDuration(FULL_SPEED_LENGTH); + mAnimator.setRepeatCount(Animation.INFINITE); + mAnimator.start(); + } + + private final Runnable mLongPressCallback = new Runnable() { + @Override + public void run() { + startAccelSpin(); + } + }; +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index a81f06e..5d58cd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -37,6 +37,7 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; +import android.widget.Toast; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.BatteryMeterView; @@ -48,6 +49,7 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.UserInfoController; +import com.android.systemui.tuner.TunerService; import java.text.NumberFormat; @@ -73,7 +75,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private TextView mDateExpanded; private LinearLayout mSystemIcons; private View mSignalCluster; - private View mSettingsButton; + private SettingsButton mSettingsButton; + private View mSettingsContainer; private View mQsDetailHeader; private TextView mQsDetailHeaderTitle; private Switch mQsDetailHeaderSwitch; @@ -142,7 +145,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); mDateCollapsed = (TextView) findViewById(R.id.date_collapsed); mDateExpanded = (TextView) findViewById(R.id.date_expanded); - mSettingsButton = findViewById(R.id.settings_button); + mSettingsButton = (SettingsButton) findViewById(R.id.settings_button); + mSettingsContainer = findViewById(R.id.settings_button_container); mSettingsButton.setOnClickListener(this); mQsDetailHeader = findViewById(R.id.qs_detail_header); mQsDetailHeader.setAlpha(0); @@ -323,13 +327,15 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mDateCollapsed.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE); mDateExpanded.setVisibility(mExpanded && mAlarmShowing ? View.INVISIBLE : View.VISIBLE); mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE); - mSettingsButton.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE); + mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE); mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE); if (mSignalCluster != null) { updateSignalClusterDetachment(); } mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE); mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE); + mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility( + TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE); } private void updateSignalClusterDetachment() { @@ -352,7 +358,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private void updateSystemIconsLayoutParams() { RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); int rule = mExpanded - ? mSettingsButton.getId() + ? mSettingsContainer.getId() : mMultiUserSwitch.getId(); if (rule != lp.getRules()[RelativeLayout.START_OF]) { lp.addRule(RelativeLayout.START_OF, rule); @@ -495,6 +501,20 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL @Override public void onClick(View v) { if (v == mSettingsButton) { + if (mSettingsButton.isTunerClick()) { + if (TunerService.isTunerEnabled(mContext)) { + TunerService.showResetRequest(mContext, new Runnable() { + @Override + public void run() { + // Relaunch settings so that the tuner disappears. + startSettingsActivity(); + } + }); + } else { + Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show(); + TunerService.setTunerEnabled(mContext, true); + } + } startSettingsActivity(); } else if (v == mSystemIconsSuperContainer) { startBatteryActivity(); @@ -567,10 +587,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } target.batteryY = mSystemIconsSuperContainer.getTop() + mSystemIconsContainer.getTop(); target.batteryLevelAlpha = getAlphaForVisibility(mBatteryLevel); - target.settingsAlpha = getAlphaForVisibility(mSettingsButton); + target.settingsAlpha = getAlphaForVisibility(mSettingsContainer); target.settingsTranslation = mExpanded ? 0 - : mMultiUserSwitch.getLeft() - mSettingsButton.getLeft(); + : mMultiUserSwitch.getLeft() - mSettingsContainer.getLeft(); target.signalClusterAlpha = mSignalClusterDetached ? 0f : 1f; target.settingsRotation = !mExpanded ? 90f : 0f; } @@ -622,9 +642,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mSignalCluster.setTranslationX(0f); mSignalCluster.setTranslationY(0f); } - mSettingsButton.setTranslationY(mSystemIconsSuperContainer.getTranslationY()); - mSettingsButton.setTranslationX(values.settingsTranslation); - mSettingsButton.setRotation(values.settingsRotation); + if (!mSettingsButton.isAnimating()) { + mSettingsContainer.setTranslationY(mSystemIconsSuperContainer.getTranslationY()); + mSettingsContainer.setTranslationX(values.settingsTranslation); + mSettingsButton.setRotation(values.settingsRotation); + } applyAlpha(mEmergencyCallsOnly, values.emergencyCallsOnlyAlpha); if (!mShowingDetail && !mDetailTransitioning) { // Otherwise it needs to stay invisible @@ -633,7 +655,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL applyAlpha(mDateCollapsed, values.dateCollapsedAlpha); applyAlpha(mDateExpanded, values.dateExpandedAlpha); applyAlpha(mBatteryLevel, values.batteryLevelAlpha); - applyAlpha(mSettingsButton, values.settingsAlpha); + applyAlpha(mSettingsContainer, values.settingsAlpha); applyAlpha(mSignalCluster, values.signalClusterAlpha); if (!mExpanded) { mTime.setScaleX(1f); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index 3f5ca58..a2b062c 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -28,13 +28,14 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; import android.provider.Settings; +import android.view.MenuItem; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.DemoMode; import com.android.systemui.R; public class DemoModeFragment extends PreferenceFragment implements OnPreferenceChangeListener { - private static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed"; private static final String DEMO_MODE_ON = "sysui_tuner_demo_on"; private static final String[] STATUS_ICONS = { @@ -75,10 +76,33 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference updateDemoModeEnabled(); updateDemoModeOn(); ContentResolver contentResolver = getContext().getContentResolver(); - contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ALLOWED), false, - mDemoModeObserver); + contentResolver.registerContentObserver(Settings.Global.getUriFor( + DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver); contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false, mDemoModeObserver); + setHasOptionsMenu(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + getFragmentManager().popBackStack(); + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onResume() { + super.onResume(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, true); + } + + @Override + public void onPause() { + super.onPause(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, false); } @Override @@ -89,7 +113,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference private void updateDemoModeEnabled() { boolean enabled = Settings.Global.getInt(getContext().getContentResolver(), - DEMO_MODE_ALLOWED, 0) != 0; + DemoMode.DEMO_MODE_ALLOWED, 0) != 0; mEnabledSwitch.setChecked(enabled); mOnSwitch.setEnabled(enabled); } @@ -102,15 +126,18 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference @Override public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = newValue == Boolean.TRUE; if (preference == mEnabledSwitch) { - if (newValue != Boolean.TRUE) { + if (!enabled) { // Make sure we aren't in demo mode when disabling it. mOnSwitch.setChecked(false); stopDemoMode(); } - setGlobal(DEMO_MODE_ALLOWED, newValue == Boolean.TRUE ? 1 : 0); + MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ENABLED, enabled); + setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0); } else if (preference == mOnSwitch) { - if (newValue == Boolean.TRUE) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ON, enabled); + if (enabled) { startDemoMode(); } else { stopDemoMode(); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java index a5b244e..37ac098 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java @@ -40,6 +40,7 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ScrollView; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; @@ -79,12 +80,25 @@ public class QsTuner extends Fragment implements Callback { menu.add(0, MENU_RESET, 0, com.android.internal.R.string.reset); } + public void onResume() { + super.onResume(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, true); + } + + public void onPause() { + super.onPause(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, false); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_RESET: mTileHost.reset(); break; + case android.R.id.home: + getFragmentManager().popBackStack(); + break; } return super.onOptionsItemSelected(item); } @@ -205,6 +219,8 @@ public class QsTuner extends Fragment implements Callback { if (oldTile.equals(newTile)) { return; } + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REORDER, oldTile + "," + + newTile); List<String> order = new ArrayList<>(mTileSpecs); int index = order.indexOf(oldTile); if (index < 0) { @@ -217,12 +233,14 @@ public class QsTuner extends Fragment implements Callback { } public void remove(String tile) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REMOVE, tile); List<String> tiles = new ArrayList<>(mTileSpecs); tiles.remove(tile); setTiles(tiles); } public void add(String tile) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_ADD, tile); List<String> tiles = new ArrayList<>(mTileSpecs); tiles.add(tile); setTiles(tiles); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java index d4cc56d..e5b550e 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java @@ -23,6 +23,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService.Tunable; @@ -50,11 +51,14 @@ public class StatusBarSwitch extends SwitchPreference implements Tunable { if (!value) { // If not enabled add to blacklist. if (!mBlacklist.contains(getKey())) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_DISABLE, + getKey()); mBlacklist.add(getKey()); setList(mBlacklist); } } else { if (mBlacklist.remove(getKey())) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_ENABLE, getKey()); setList(mBlacklist); } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 4a8c2e4..71b5de5 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -17,7 +17,10 @@ package com.android.systemui.tuner; import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING; +import android.app.AlertDialog; import android.app.FragmentTransaction; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.database.ContentObserver; import android.net.Uri; import android.os.Bundle; @@ -28,19 +31,29 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.preference.SwitchPreference; +import android.provider.Settings; import android.provider.Settings.System; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService.Tunable; public class TunerFragment extends PreferenceFragment { + private static final String TAG = "TunerFragment"; + private static final String KEY_QS_TUNER = "qs_tuner"; private static final String KEY_DEMO_MODE = "demo_mode"; private static final String KEY_BATTERY_PCT = "battery_pct"; + public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning"; + + private static final int MENU_REMOVE = Menu.FIRST + 1; + private final SettingObserver mSettingObserver = new SettingObserver(); private SwitchPreference mBatteryPct; @@ -73,6 +86,19 @@ public class TunerFragment extends PreferenceFragment { } }); mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT); + if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING, + 0) == 0) { + new AlertDialog.Builder(getContext()) + .setTitle(R.string.tuner_warning_title) + .setMessage(R.string.tuner_warning) + .setPositiveButton(R.string.got_it, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Settings.Secure.putInt(getContext().getContentResolver(), + SETTING_SEEN_TUNER_WARNING, 1); + } + }).show(); + } } @Override @@ -83,6 +109,7 @@ public class TunerFragment extends PreferenceFragment { System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver); registerPrefs(getPreferenceScreen()); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true); } @Override @@ -91,6 +118,7 @@ public class TunerFragment extends PreferenceFragment { getContext().getContentResolver().unregisterContentObserver(mSettingObserver); unregisterPrefs(getPreferenceScreen()); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false); } private void registerPrefs(PreferenceGroup group) { @@ -120,11 +148,24 @@ public class TunerFragment extends PreferenceFragment { } @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings); + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: getActivity().finish(); return true; + case MENU_REMOVE: + TunerService.showResetRequest(getContext(), new Runnable() { + @Override + public void run() { + getActivity().finish(); + } + }); + return true; } return super.onOptionsItemSelected(item); } @@ -152,6 +193,7 @@ public class TunerFragment extends PreferenceFragment { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean v = (Boolean) newValue; + MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v); System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java index de5aaf6..d3f33ab 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java @@ -16,8 +16,15 @@ package com.android.systemui.tuner; import android.app.ActivityManager; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; @@ -25,9 +32,13 @@ import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; +import com.android.systemui.BatteryMeterView; +import com.android.systemui.DemoMode; +import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.SystemUIApplication; import com.android.systemui.settings.CurrentUserTracker; +import com.android.systemui.statusbar.phone.SystemUIDialog; import java.util.ArrayList; import java.util.HashMap; @@ -36,6 +47,8 @@ import java.util.List; public class TunerService extends SystemUI { + public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER"; + private final Observer mObserver = new Observer(); // Map of Uris we listen on to their settings keys. private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>(); @@ -118,6 +131,19 @@ public class TunerService extends SystemUI { } } + public void clearAll() { + // A couple special cases. + Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null); + Settings.System.putString(mContentResolver, BatteryMeterView.SHOW_PERCENT_SETTING, null); + Intent intent = new Intent(DemoMode.ACTION_DEMO); + intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT); + mContext.sendBroadcast(intent); + + for (String key : mTunableLookup.keySet()) { + Settings.Secure.putString(mContentResolver, key, null); + } + } + // Only used in other processes, such as the tuner. private static TunerService sInstance; @@ -141,6 +167,44 @@ public class TunerService extends SystemUI { return sInstance; } + public static final void showResetRequest(final Context context, final Runnable onDisabled) { + SystemUIDialog dialog = new SystemUIDialog(context); + dialog.setMessage(R.string.remove_from_settings_prompt); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), + (OnClickListener) null); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, + context.getString(R.string.guest_exit_guest_dialog_remove), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Tell the tuner (in main SysUI process) to clear all its settings. + context.sendBroadcast(new Intent(TunerService.ACTION_CLEAR)); + // Disable access to tuner. + TunerService.setTunerEnabled(context, false); + // Make them sit through the warning dialog again. + Settings.Secure.putInt(context.getContentResolver(), + TunerFragment.SETTING_SEEN_TUNER_WARNING, 0); + if (onDisabled != null) { + onDisabled.run(); + } + } + }); + dialog.show(); + } + + public static final void setTunerEnabled(Context context, boolean enabled) { + context.getPackageManager().setComponentEnabledSetting( + new ComponentName(context, TunerActivity.class), + enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + + public static final boolean isTunerEnabled(Context context) { + return context.getPackageManager().getComponentEnabledSetting( + new ComponentName(context, TunerActivity.class)) + == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + } + private class Observer extends ContentObserver { public Observer() { super(new Handler(Looper.getMainLooper())); @@ -157,4 +221,13 @@ public class TunerService extends SystemUI { public interface Tunable { void onTuningChanged(String key, String newValue); } + + public static class ClearReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_CLEAR.equals(intent.getAction())) { + get(context).clearAll(); + } + } + } } diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java index ebc810f..4569dae 100644 --- a/services/core/java/com/android/server/AssetAtlasService.java +++ b/services/core/java/com/android/server/AssetAtlasService.java @@ -93,7 +93,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub { // Defines the number of int fields used to represent a single entry // in the atlas map. This number defines the size of the array returned // by the getMap(). See the mAtlasMap field for more information - private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 4; + private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 3; // Specifies how our GraphicBuffer will be used. To get proper swizzling // the buffer will be written to using OpenGL (from JNI) so we can leave diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index c7c9d29..7561c7d 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -253,6 +253,8 @@ public class DeviceIdleController extends SystemService "max_temp_app_whitelist_duration"; private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION = "mms_temp_app_whitelist_duration"; + private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION = + "sms_temp_app_whitelist_duration"; /** * This is the time, after becoming inactive, at which we start looking at the @@ -357,6 +359,13 @@ public class DeviceIdleController extends SystemService */ public long MMS_TEMP_APP_WHITELIST_DURATION; + /** + * Amount of time we would like to whitelist an app that is receiving an SMS. + * @see Settings.Global#DEVICE_IDLE_CONSTANTS + * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION + */ + public long SMS_TEMP_APP_WHITELIST_DURATION; + private final ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -410,6 +419,8 @@ public class DeviceIdleController extends SystemService KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L); MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L); + SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( + KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L); } } @@ -465,6 +476,10 @@ public class DeviceIdleController extends SystemService pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw); pw.println(); + + pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); + TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw); + pw.println(); } } @@ -617,6 +632,13 @@ public class DeviceIdleController extends SystemService return duration; } + @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, + int userId, String reason) throws RemoteException { + long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION; + addPowerSaveTempWhitelistApp(packageName, duration, userId, reason); + return duration; + } + @Override public void exitIdle(String reason) { getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index cb294fd..32fd56a 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -3799,7 +3799,8 @@ public class AccountManagerService * access accounts of the specified account. */ boolean isPermitted = - isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS); + isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS, + Manifest.permission.GET_ACCOUNTS_PRIVILEGED); boolean isAccountManagedByCaller = isAccountManagedByCaller(accountType, callingUid); Log.w(TAG, String.format( "isReadAccountPermitted: isPermitted: %s, isAM: %s", diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index f04790e..0d1d1ea 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -495,6 +495,16 @@ final class DefaultPermissionGrantPolicy { } } + // Voice recognition + Intent voiceRecoIntent = new Intent("android.speech.RecognitionService"); + voiceRecoIntent.addCategory(Intent.CATEGORY_DEFAULT); + PackageParser.Package voiceRecoPackage = getDefaultSystemHandlerServicePackageLPr( + voiceRecoIntent, userId); + if (voiceRecoPackage != null + && doesPackageSupportRuntimePermissions(voiceRecoPackage)) { + grantRuntimePermissionsLPw(voiceRecoPackage, MICROPHONE_PERMISSIONS, userId); + } + // Location if (locationPackageNames != null) { for (String packageName : locationPackageNames) { @@ -627,6 +637,26 @@ final class DefaultPermissionGrantPolicy { return null; } + private PackageParser.Package getDefaultSystemHandlerServicePackageLPr( + Intent intent, int userId) { + List<ResolveInfo> handlers = mService.queryIntentServices(intent, + intent.resolveType(mService.mContext.getContentResolver()), + PackageManager.GET_DISABLED_COMPONENTS, userId); + if (handlers == null) { + return null; + } + final int handlerCount = handlers.size(); + for (int i = 0; i < handlerCount; i++) { + ResolveInfo handler = handlers.get(i); + PackageParser.Package handlerPackage = getSystemPackageLPr( + handler.serviceInfo.packageName); + if (handlerPackage != null) { + return handlerPackage; + } + } + return null; + } + private List<PackageParser.Package> getHeadlessSyncAdapterPackagesLPr( String[] syncAdapterPackageNames, int userId) { List<PackageParser.Package> syncAdapterPackages = new ArrayList<>(); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c139389..0b74996 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7321,6 +7321,9 @@ public class PackageManagerService extends IPackageManager.Stub { for (i=0; i<N; i++) { PackageParser.Permission p = pkg.permissions.get(i); + // Assume by default that we did not install this permission into the system. + p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; + // Now that permission groups have a special meaning, we ignore permission // groups for legacy apps to prevent unexpected behavior. In particular, // permissions for one app being granted to someone just becuase they happen @@ -7350,6 +7353,7 @@ public class PackageManagerService extends IPackageManager.Stub { bp.perm = p; bp.uid = pkg.applicationInfo.uid; bp.sourcePackage = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; } else if (!currentOwnerIsSystem) { String msg = "New decl " + p.owner + " of permission " + p.info.name + " is system; overriding " + bp.sourcePackage; @@ -7375,6 +7379,7 @@ public class PackageManagerService extends IPackageManager.Stub { bp.perm = p; bp.uid = pkg.applicationInfo.uid; bp.sourcePackage = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { if (r == null) { r = new StringBuilder(256); @@ -14688,12 +14693,12 @@ public class PackageManagerService extends IPackageManager.Stub { pw.println(" s[hared-users]: dump shared user IDs"); pw.println(" m[essages]: print collected runtime messages"); pw.println(" v[erifiers]: print package verifier info"); + pw.println(" d[omain-preferred-apps]: print domains preferred apps"); + pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); pw.println(" version: print database version info"); pw.println(" write: write current settings now"); - pw.println(" <package.name>: info about given package"); pw.println(" installs: details about install sessions"); - pw.println(" d[omain-preferred-apps]: print domains preferred apps"); - pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); + pw.println(" <package.name>: info about given package"); return; } else if ("--checkin".equals(opt)) { checkin = true; @@ -15600,12 +15605,8 @@ public class PackageManagerService extends IPackageManager.Stub { * recycled. */ private void reconcileUsers(String volumeUuid) { - final File[] files = Environment.getDataUserDirectory(volumeUuid).listFiles(); - if (ArrayUtils.isEmpty(files)) { - Slog.d(TAG, "No users found on " + volumeUuid); - return; - } - + final File[] files = FileUtils + .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid)); for (File file : files) { if (!file.isDirectory()) continue; @@ -15661,12 +15662,8 @@ public class PackageManagerService extends IPackageManager.Stub { * another volume. */ private void reconcileApps(String volumeUuid) { - final File[] files = Environment.getDataAppDirectory(volumeUuid).listFiles(); - if (ArrayUtils.isEmpty(files)) { - Slog.d(TAG, "No apps found on " + volumeUuid); - return; - } - + final File[] files = FileUtils + .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); for (File file : files) { final boolean isPackage = (isApkFile(file) || file.isDirectory()) && !PackageInstallerService.isStageName(file.getName()); @@ -15797,7 +15794,12 @@ public class PackageManagerService extends IPackageManager.Stub { } // Now that we're guarded by frozen state, kill app during move - killApplication(packageName, appId, "move pkg"); + final long token = Binder.clearCallingIdentity(); + try { + killApplication(packageName, appId, "move pkg"); + } finally { + Binder.restoreCallingIdentity(token); + } final Bundle extras = new Bundle(); extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 92b9da6..736b153 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4120,6 +4120,28 @@ final class Settings { pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC); pw.println(); + if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) { + final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions; + pw.print(prefix); pw.println(" declared permissions:"); + for (int i=0; i<perms.size(); i++) { + PackageParser.Permission perm = perms.get(i); + if (permissionNames != null + && !permissionNames.contains(perm.info.name)) { + continue; + } + pw.print(prefix); pw.print(" "); pw.print(perm.info.name); + pw.print(": prot="); + pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel)); + if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) { + pw.print(", COSTS_MONEY"); + } + if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { + pw.print(", INSTALLED"); + } + pw.println(); + } + } + if (ps.sharedUser == null || permissionNames != null) { PermissionsState permissionsState = ps.getPermissionsState(); dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); @@ -4155,14 +4177,14 @@ final class Settings { if (cmp != null && cmp.size() > 0) { pw.print(prefix); pw.println(" disabledComponents:"); for (String s : cmp) { - pw.print(prefix); pw.print(" "); pw.println(s); + pw.print(prefix); pw.print(" "); pw.println(s); } } cmp = ps.getEnabledComponents(user.id); if (cmp != null && cmp.size() > 0) { pw.print(prefix); pw.println(" enabledComponents:"); for (String s : cmp) { - pw.print(prefix); pw.print(" "); pw.println(s); + pw.print(prefix); pw.print(" "); pw.println(s); } } } @@ -4267,11 +4289,14 @@ final class Settings { pw.print(" type="); pw.print(p.type); pw.print(" prot="); pw.println(PermissionInfo.protectionToString(p.protectionLevel)); - if (p.packageSetting != null) { - pw.print(" packageSetting="); pw.println(p.packageSetting); - } if (p.perm != null) { pw.print(" perm="); pw.println(p.perm); + if (p.perm.info.flags != PermissionInfo.FLAG_INSTALLED) { + pw.print(" flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags)); + } + } + if (p.packageSetting != null) { + pw.print(" packageSetting="); pw.println(p.packageSetting); } if (READ_EXTERNAL_STORAGE.equals(p.name)) { pw.print(" enforced="); @@ -4372,24 +4397,32 @@ final class Settings { continue; } pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); - pw.print(", granted="); pw.print(permissionState.isGranted()); - pw.print(", flags="); pw.println(permissionFlagsToString( - permissionState.getFlags())); + pw.print(": granted="); pw.print(permissionState.isGranted()); + pw.println(permissionFlagsToString(", flags=", + permissionState.getFlags())); } } } - private static String permissionFlagsToString(int flags) { - StringBuilder flagsString = new StringBuilder(); - flagsString.append("[ "); + private static String permissionFlagsToString(String prefix, int flags) { + StringBuilder flagsString = null; while (flags != 0) { + if (flagsString == null) { + flagsString = new StringBuilder(); + flagsString.append(prefix); + flagsString.append("[ "); + } final int flag = 1 << Integer.numberOfTrailingZeros(flags); flags &= ~flag; flagsString.append(PackageManager.permissionFlagToString(flag)); flagsString.append(' '); } - flagsString.append(']'); - return flagsString.toString(); + if (flagsString != null) { + flagsString.append(']'); + return flagsString.toString(); + } else { + return ""; + } } void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, @@ -4403,8 +4436,8 @@ final class Settings { continue; } pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); - pw.print(", granted="); pw.print(permissionState.isGranted()); - pw.print(", flags="); pw.println(permissionFlagsToString( + pw.print(": granted="); pw.print(permissionState.isGranted()); + pw.println(permissionFlagsToString(", flags=", permissionState.getFlags())); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4f2b1f9..d9828cc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -10029,70 +10029,70 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; if (DEBUG_LAYOUT_REPEATS) { debugLayoutRepeats( - "dream and commitFinishDrawingLocked true", - displayContent.pendingLayoutChanges); + "dream and commitFinishDrawingLocked true", + displayContent.pendingLayoutChanges); } } if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, - "First draw done in potential wallpaper target " + w); + "First draw done in potential wallpaper target " + w); mInnerFields.mWallpaperMayChange = true; displayContent.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; if (DEBUG_LAYOUT_REPEATS) { debugLayoutRepeats( - "wallpaper and commitFinishDrawingLocked true", - displayContent.pendingLayoutChanges); + "wallpaper and commitFinishDrawingLocked true", + displayContent.pendingLayoutChanges); } } } winAnimator.setSurfaceBoundariesLocked(recoveringMemory); + } - final AppWindowToken atoken = w.mAppToken; - if (DEBUG_STARTING_WINDOW && atoken != null - && w == atoken.startingWindow) { - Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" - + w.isOnScreen() + " allDrawn=" + atoken.allDrawn - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); + final AppWindowToken atoken = w.mAppToken; + if (DEBUG_STARTING_WINDOW && atoken != null + && w == atoken.startingWindow) { + Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + + w.isOnScreen() + " allDrawn=" + atoken.allDrawn + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); + } + if (atoken != null + && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { + if (atoken.lastTransactionSequence != mTransactionSequence) { + atoken.lastTransactionSequence = mTransactionSequence; + atoken.numInterestingWindows = atoken.numDrawnWindows = 0; + atoken.startingDisplayed = false; } - if (atoken != null - && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { - if (atoken.lastTransactionSequence != mTransactionSequence) { - atoken.lastTransactionSequence = mTransactionSequence; - atoken.numInterestingWindows = atoken.numDrawnWindows = 0; - atoken.startingDisplayed = false; - } - if ((w.isOnScreenIgnoringKeyguard() - || winAnimator.mAttrType == TYPE_BASE_APPLICATION) - && !w.mExiting && !w.mDestroying) { - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { - Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() - + ", isAnimating=" + winAnimator.isAnimating()); - if (!w.isDrawnLw()) { - Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl - + " pv=" + w.mPolicyVisibility - + " mDrawState=" + winAnimator.drawStateToString() - + " ah=" + w.mAttachedHidden - + " th=" + atoken.hiddenRequested - + " a=" + winAnimator.mAnimating); - } + if ((w.isOnScreenIgnoringKeyguard() + || winAnimator.mAttrType == TYPE_BASE_APPLICATION) + && !w.mExiting && !w.mDestroying) { + if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { + Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() + + ", isAnimating=" + winAnimator.isAnimating()); + if (!w.isDrawnLw()) { + Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl + + " pv=" + w.mPolicyVisibility + + " mDrawState=" + winAnimator.drawStateToString() + + " ah=" + w.mAttachedHidden + + " th=" + atoken.hiddenRequested + + " a=" + winAnimator.mAnimating); } - if (w != atoken.startingWindow) { - if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { - atoken.numInterestingWindows++; - if (w.isDrawnLw()) { - atoken.numDrawnWindows++; - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, - "tokenMayBeDrawn: " + atoken - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen - + " mAppFreezing=" + w.mAppFreezing); - updateAllDrawn = true; - } + } + if (w != atoken.startingWindow) { + if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { + atoken.numInterestingWindows++; + if (w.isDrawnLw()) { + atoken.numDrawnWindows++; + if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, + "tokenMayBeDrawn: " + atoken + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + + " mAppFreezing=" + w.mAppFreezing); + updateAllDrawn = true; } - } else if (w.isDrawnLw()) { - atoken.startingDisplayed = true; } + } else if (w.isDrawnLw()) { + atoken.startingDisplayed = true; } } } diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 4498b84..f8ae03f 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -21,6 +21,7 @@ import android.app.usage.UsageStatsManager; import android.os.Build; import android.util.AtomicFile; import android.util.Slog; +import android.util.TimeUtils; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -191,7 +192,11 @@ class UsageStatsDatabase { for (File f : files) { final AtomicFile af = new AtomicFile(f); - mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); + try { + mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); + } catch (IOException e) { + Slog.e(TAG, "failed to index file: " + f, e); + } } } } @@ -273,14 +278,21 @@ class UsageStatsDatabase { public void onTimeChanged(long timeDiffMillis) { synchronized (mLock) { + StringBuilder logBuilder = new StringBuilder(); + logBuilder.append("Time changed by "); + TimeUtils.formatDuration(timeDiffMillis, logBuilder); + logBuilder.append("."); + + int filesDeleted = 0; + int filesMoved = 0; + for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) { final int fileCount = files.size(); for (int i = 0; i < fileCount; i++) { final AtomicFile file = files.valueAt(i); final long newTime = files.keyAt(i) + timeDiffMillis; if (newTime < 0) { - Slog.i(TAG, "Deleting file " + file.getBaseFile().getAbsolutePath() - + " for it is in the future now."); + filesDeleted++; file.delete(); } else { try { @@ -295,14 +307,17 @@ class UsageStatsDatabase { } final File newFile = new File(file.getBaseFile().getParentFile(), newName); - Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to " - + newFile.getAbsolutePath()); + filesMoved++; file.getBaseFile().renameTo(newFile); } } files.clear(); } + logBuilder.append(" files deleted: ").append(filesDeleted); + logBuilder.append(" files moved: ").append(filesMoved); + Slog.i(TAG, logBuilder.toString()); + // Now re-index the new files. indexFilesLocked(); } @@ -506,7 +521,14 @@ class UsageStatsDatabase { if (path.endsWith(BAK_SUFFIX)) { f = new File(path.substring(0, path.length() - BAK_SUFFIX.length())); } - long beginTime = UsageStatsXml.parseBeginTime(f); + + long beginTime; + try { + beginTime = UsageStatsXml.parseBeginTime(f); + } catch (IOException e) { + beginTime = 0; + } + if (beginTime < expiryTime) { new AtomicFile(f).delete(); } diff --git a/services/usage/java/com/android/server/usage/UsageStatsXml.java b/services/usage/java/com/android/server/usage/UsageStatsXml.java index 186813e..543f361 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXml.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXml.java @@ -33,11 +33,11 @@ public class UsageStatsXml { private static final String VERSION_ATTR = "version"; static final String CHECKED_IN_SUFFIX = "-c"; - public static long parseBeginTime(AtomicFile file) { + public static long parseBeginTime(AtomicFile file) throws IOException { return parseBeginTime(file.getBaseFile()); } - public static long parseBeginTime(File file) { + public static long parseBeginTime(File file) throws IOException { String name = file.getName(); // Eat as many occurrences of -c as possible. This is due to a bug where -c @@ -47,7 +47,12 @@ public class UsageStatsXml { while (name.endsWith(CHECKED_IN_SUFFIX)) { name = name.substring(0, name.length() - CHECKED_IN_SUFFIX.length()); } - return Long.parseLong(name); + + try { + return Long.parseLong(name); + } catch (NumberFormatException e) { + throw new IOException(e); + } } public static void read(AtomicFile file, IntervalStats statsOut) throws IOException { diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 6300a9a..965341e 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -231,6 +231,8 @@ public class UsbHostManager { mNewConfigurations = null; mNewInterfaces = null; mNewEndpoints = null; + mNewConfiguration = null; + mNewInterface = null; } } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index e861668..e9c41a1 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -273,6 +273,14 @@ public class CarrierConfigManager { */ public static final String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string"; + /** + * The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in + * Settings->More->Emergency broadcasts menu even though developer options is turned on. + * @hide + */ + public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = + "carrier_force_disable_etws_cmas_test_bool"; + /* The following 3 fields are related to carrier visual voicemail. */ /** @@ -381,6 +389,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false); + sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true); sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f390075..d915e5d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1302,7 +1302,7 @@ public class WifiManager { * Return the results of the latest access point scan. * @return the list of access points found in the most recent scan. An app must hold * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION} permission + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get valid results. */ public List<ScanResult> getScanResults() { |
