diff options
10 files changed, 266 insertions, 87 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 5f515ebb10e6..56e919adff15 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -3282,12 +3282,13 @@ public abstract class BatteryStats implements Parcelable { final long wifiIdleTimeMs = getWifiControllerActivity(CONTROLLER_IDLE_TIME, which); final long wifiRxTimeMs = getWifiControllerActivity(CONTROLLER_RX_TIME, which); final long wifiTxTimeMs = getWifiControllerActivity(CONTROLLER_TX_TIME, which); + final long wifiPowerDrainMaMs = getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which); final long wifiTotalTimeMs = wifiIdleTimeMs + wifiRxTimeMs + wifiTxTimeMs; sb.setLength(0); sb.append(prefix); sb.append(" WiFi Idle time: "); formatTimeMs(sb, wifiIdleTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(wifiIdleTimeMs, wifiTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); @@ -3295,7 +3296,7 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); sb.append(" WiFi Rx time: "); formatTimeMs(sb, wifiRxTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(wifiRxTimeMs, wifiTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); @@ -3303,16 +3304,16 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); sb.append(" WiFi Tx time: "); formatTimeMs(sb, wifiTxTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(wifiTxTimeMs, wifiTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); sb.setLength(0); sb.append(prefix); - sb.append(" WiFi Power drain: ").append(BatteryStatsHelper.makemAh( - getWifiControllerActivity(CONTROLLER_POWER_DRAIN, which) / (double)(1000*60*60))); - sb.append(" mAh"); + sb.append(" WiFi Power drain: ").append( + BatteryStatsHelper.makemAh(wifiPowerDrainMaMs / (double) (1000*60*60))); + sb.append("mAh"); pw.println(sb.toString()); final long bluetoothIdleTimeMs = @@ -3325,7 +3326,7 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); sb.append(" Bluetooth Idle time: "); formatTimeMs(sb, bluetoothIdleTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(bluetoothIdleTimeMs, bluetoothTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); @@ -3333,7 +3334,7 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); sb.append(" Bluetooth Rx time: "); formatTimeMs(sb, bluetoothRxTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(bluetoothRxTimeMs, bluetoothTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); @@ -3341,7 +3342,7 @@ public abstract class BatteryStats implements Parcelable { sb.setLength(0); sb.append(prefix); sb.append(" Bluetooth Tx time: "); formatTimeMs(sb, bluetoothTxTimeMs); - sb.append(" ("); + sb.append("("); sb.append(formatRatioLocked(bluetoothTxTimeMs, bluetoothTotalTimeMs)); sb.append(")"); pw.println(sb.toString()); @@ -3351,7 +3352,7 @@ public abstract class BatteryStats implements Parcelable { sb.append(" Bluetooth Power drain: ").append(BatteryStatsHelper.makemAh( getBluetoothControllerActivity(CONTROLLER_POWER_DRAIN, which) / (double)(1000*60*60))); - sb.append(" mAh"); + sb.append("mAh"); pw.println(sb.toString()); pw.println(); @@ -3656,6 +3657,27 @@ public abstract class BatteryStats implements Parcelable { pw.println(sb.toString()); } + final long uidWifiIdleTimeMs = u.getWifiControllerActivity(CONTROLLER_IDLE_TIME, which); + final long uidWifiRxTimeMs = u.getWifiControllerActivity(CONTROLLER_RX_TIME, which); + final long uidWifiTxTimeMs = u.getWifiControllerActivity(CONTROLLER_TX_TIME, which); + final long uidWifiTotalTimeMs = uidWifiIdleTimeMs + uidWifiRxTimeMs + uidWifiTxTimeMs; + if (uidWifiTotalTimeMs > 0) { + sb.setLength(0); + sb.append(prefix).append(" WiFi Idle time: "); + formatTimeMs(sb, uidWifiIdleTimeMs); + sb.append("(").append(formatRatioLocked(uidWifiIdleTimeMs, uidWifiTotalTimeMs)) + .append(")\n"); + + sb.append(prefix).append(" WiFi Rx time: "); formatTimeMs(sb, uidWifiRxTimeMs); + sb.append("(").append(formatRatioLocked(uidWifiRxTimeMs, uidWifiTotalTimeMs)) + .append(")\n"); + + sb.append(prefix).append(" WiFi Tx time: "); formatTimeMs(sb, uidWifiTxTimeMs); + sb.append("(").append(formatRatioLocked(uidWifiTxTimeMs, uidWifiTotalTimeMs)) + .append(")"); + pw.println(sb.toString()); + } + if (u.hasUserActivity()) { boolean hasData = false; for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 2709f252483b..ca57d1a6a929 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -1704,12 +1704,26 @@ public class ScrollView extends FrameLayout { super.draw(canvas); if (mEdgeGlowTop != null) { final int scrollY = mScrollY; + final boolean clipToPadding = getClipToPadding(); if (!mEdgeGlowTop.isFinished()) { final int restoreCount = canvas.save(); - final int width = getWidth() - mPaddingLeft - mPaddingRight; - - canvas.translate(mPaddingLeft, Math.min(0, scrollY)); - mEdgeGlowTop.setSize(width, getHeight()); + final int width; + final int height; + final float translateX; + final float translateY; + if (clipToPadding) { + width = getWidth() - mPaddingLeft - mPaddingRight; + height = getHeight() - mPaddingTop - mPaddingBottom; + translateX = mPaddingLeft; + translateY = mPaddingTop; + } else { + width = getWidth(); + height = getHeight(); + translateX = 0; + translateY = 0; + } + canvas.translate(translateX, Math.min(0, scrollY) + translateY); + mEdgeGlowTop.setSize(width, height); if (mEdgeGlowTop.draw(canvas)) { postInvalidateOnAnimation(); } @@ -1717,11 +1731,23 @@ public class ScrollView extends FrameLayout { } if (!mEdgeGlowBottom.isFinished()) { final int restoreCount = canvas.save(); - final int width = getWidth() - mPaddingLeft - mPaddingRight; - final int height = getHeight(); - - canvas.translate(-width + mPaddingLeft, - Math.max(getScrollRange(), scrollY) + height); + final int width; + final int height; + final float translateX; + final float translateY; + if (clipToPadding) { + width = getWidth() - mPaddingLeft - mPaddingRight; + height = getHeight() - mPaddingTop - mPaddingBottom; + translateX = mPaddingLeft; + translateY = mPaddingTop; + } else { + width = getWidth(); + height = getHeight(); + translateX = 0; + translateY = 0; + } + canvas.translate(-width + translateX, + Math.max(getScrollRange(), scrollY) + height + translateY); canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width, height); if (mEdgeGlowBottom.draw(canvas)) { diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml index 112afa647850..8bf635e68cf9 100644 --- a/core/res/res/values/themes_micro.xml +++ b/core/res/res/values/themes_micro.xml @@ -14,7 +14,7 @@ limitations under the License. --> <resources> - <style name="Theme.Micro" parent="Theme.Material.NoActionBar"> + <style name="Theme.MicroBase" parent="Theme.Material.NoActionBar"> <item name="alertDialogTheme">@style/Theme.Micro.Dialog.Alert</item> <item name="alertDialogStyle">@style/AlertDialog.Micro</item> <item name="dialogTheme">@style/Theme.Micro.Dialog</item> @@ -29,7 +29,10 @@ <item name="windowOverscan">true</item> </style> - <style name="Theme.Micro.Light" parent="Theme.Material.Light.NoActionBar"> + <style name="Theme.Micro" parent="Theme.MicroBase"> + </style> + + <style name="Theme.Micro.LightBase" parent="Theme.Material.Light.NoActionBar"> <item name="alertDialogTheme">@style/Theme.Micro.Dialog.Alert</item> <item name="alertDialogStyle">@style/AlertDialog.Micro</item> <item name="dialogTheme">@style/Theme.Micro.Dialog</item> @@ -44,7 +47,11 @@ <item name="windowOverscan">true</item> </style> - <style name="Theme.Micro.Dialog" parent="Theme.Material.Light.Dialog"> + <!-- Indirection needed for overlays to make sure there is a common base parent --> + <style name="Theme.Micro.Light" parent="Theme.Micro.LightBase"> + </style> + + <style name="Theme.Micro.DialogBase" parent="Theme.Material.Light.Dialog"> <item name="windowTitleStyle">@android:style/DialogWindowTitle.Micro</item> <item name="windowIsFloating">false</item> <item name="windowFullscreen">true</item> @@ -54,6 +61,10 @@ <item name="windowOverscan">true</item> </style> + <!-- Indirection needed for overlays to make sure there is a common base parent --> + <style name="Theme.Micro.Dialog" parent="Theme.Micro.DialogBase"> + </style> + <style name="Theme.Micro.Dialog.Alert"> <item name="windowTitleStyle">@style/DialogWindowTitle.Micro</item> <item name="alertDialogStyle">@style/AlertDialog.Micro</item> diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd index 5fd6bb822d5a..b8a60333408b 100644 --- a/docs/html/preview/api-overview.jd +++ b/docs/html/preview/api-overview.jd @@ -165,11 +165,11 @@ method to re-authenticate the user within your app. <p>To see an app implementation of this feature, refer to the <a href="https://github.com/googlesamples/android-ConfirmCredentials" class="external-link"> - Confirm Device Credentials sample</a>.</p> + Confirm Credentials sample</a>.</p> <h2 id="direct-share">Direct Share</h2> -<img src="{@docRoot}preview/images/direct-share-screen_2x.png" +<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="335" /> diff --git a/docs/html/preview/testing/performance.jd b/docs/html/preview/testing/performance.jd index 4ac5a90505df..003b619f44b6 100644 --- a/docs/html/preview/testing/performance.jd +++ b/docs/html/preview/testing/performance.jd @@ -554,10 +554,10 @@ Number Slow draw: 23342 </h4> <p> - Tool suites like <a href= - "https://developer.android.com/tools/testing-support-library/index.html">UIAutomator</a>, - and <a href="https://code.google.com/p/android-test-kit/">Espresso</a> are built to help - automate the action of a user moving through your application. These are simple + Tool suites, like <a href= + "{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a> and + <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a>, are + built to help automate the action of a user moving through your application. These are simple frameworks which mimic user interaction with your device. To use these frameworks, you effectively create unique scripts, which run through a set of user-actions, and play them out on the device itself. @@ -585,7 +585,7 @@ Number Slow draw: 23342 <p> It’s worth noting that UI testing frameworks (like <a href= - "https://developer.android.com/tools/testing-support-library/index.html">UIAutomator</a>) + "{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>) run on the target device/emulator directly. While performance gathering information done by <em>dumpsys gfxinfo</em> is driven by a host machine, sending commands over ADB. To help bridge the automation of these separate entities, <a href= @@ -595,7 +595,7 @@ Number Slow draw: 23342 </p> <p> - Building a set of scripts for proper Automation of UI Performance testing, at a minimum, + Building a set of scripts for proper automation of UI Performance testing, at a minimum, should be able to utilize monkeyRunner to accomplish the following tasks: </p> @@ -603,7 +603,7 @@ Number Slow draw: 23342 <li>Load & Launch a desired APK to a target device, devices, or emulator. </li> - <li>Launch a UIAutomator UI test, and allow it to be executed + <li>Launch a UI Automator UI test, and allow it to be executed </li> <li>Collect performance information through <em>dumpsys gfxinfo</em><em>.</em> diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 3300cdbb3eb2..2d15d1369721 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -36,6 +36,7 @@ import android.app.NotificationManager; import android.app.NotificationManager.Policy; import android.app.PendingIntent; import android.app.StatusBarManager; +import android.app.backup.BackupManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; @@ -113,12 +114,16 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; @@ -330,6 +335,37 @@ public class NotificationManagerService extends SystemService { } + private void readPolicyXml(InputStream stream, boolean forRestore) + throws XmlPullParserException, NumberFormatException, IOException { + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(stream, StandardCharsets.UTF_8.name()); + + int type; + String tag; + int version = DB_VERSION; + while ((type = parser.next()) != END_DOCUMENT) { + tag = parser.getName(); + if (type == START_TAG) { + if (TAG_NOTIFICATION_POLICY.equals(tag)) { + version = Integer.parseInt( + parser.getAttributeValue(null, ATTR_VERSION)); + } else if (TAG_BLOCKED_PKGS.equals(tag)) { + while ((type = parser.next()) != END_DOCUMENT) { + tag = parser.getName(); + if (TAG_PACKAGE.equals(tag)) { + mBlockedPackages.add( + parser.getAttributeValue(null, ATTR_NAME)); + } else if (TAG_BLOCKED_PKGS.equals(tag) && type == END_TAG) { + break; + } + } + } + } + mZenModeHelper.readXml(parser, forRestore); + mRankingHelper.readXml(parser, forRestore); + } + } + private void loadPolicyFile() { if (DBG) Slog.d(TAG, "loadPolicyFile"); synchronized(mPolicyFile) { @@ -338,33 +374,7 @@ public class NotificationManagerService extends SystemService { FileInputStream infile = null; try { infile = mPolicyFile.openRead(); - final XmlPullParser parser = Xml.newPullParser(); - parser.setInput(infile, StandardCharsets.UTF_8.name()); - - int type; - String tag; - int version = DB_VERSION; - while ((type = parser.next()) != END_DOCUMENT) { - tag = parser.getName(); - if (type == START_TAG) { - if (TAG_NOTIFICATION_POLICY.equals(tag)) { - version = Integer.parseInt( - parser.getAttributeValue(null, ATTR_VERSION)); - } else if (TAG_BLOCKED_PKGS.equals(tag)) { - while ((type = parser.next()) != END_DOCUMENT) { - tag = parser.getName(); - if (TAG_PACKAGE.equals(tag)) { - mBlockedPackages.add( - parser.getAttributeValue(null, ATTR_NAME)); - } else if (TAG_BLOCKED_PKGS.equals(tag) && type == END_TAG) { - break; - } - } - } - } - mZenModeHelper.readXml(parser); - mRankingHelper.readXml(parser); - } + readPolicyXml(infile, false /*forRestore*/); } catch (FileNotFoundException e) { // No data yet } catch (IOException e) { @@ -396,21 +406,26 @@ public class NotificationManagerService extends SystemService { } try { - final XmlSerializer out = new FastXmlSerializer(); - out.setOutput(stream, StandardCharsets.UTF_8.name()); - out.startDocument(null, true); - out.startTag(null, TAG_NOTIFICATION_POLICY); - out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION)); - mZenModeHelper.writeXml(out); - mRankingHelper.writeXml(out); - out.endTag(null, TAG_NOTIFICATION_POLICY); - out.endDocument(); + writePolicyXml(stream, false /*forBackup*/); mPolicyFile.finishWrite(stream); } catch (IOException e) { Slog.w(TAG, "Failed to save policy file, restoring backup", e); mPolicyFile.failWrite(stream); } } + BackupManager.dataChanged(getContext().getPackageName()); + } + + private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException { + final XmlSerializer out = new FastXmlSerializer(); + out.setOutput(stream, StandardCharsets.UTF_8.name()); + out.startDocument(null, true); + out.startTag(null, TAG_NOTIFICATION_POLICY); + out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION)); + mZenModeHelper.writeXml(out, forBackup); + mRankingHelper.writeXml(out, forBackup); + out.endTag(null, TAG_NOTIFICATION_POLICY); + out.endDocument(); } /** Use this when you actually want to post a notification or toast. @@ -722,6 +737,7 @@ public class NotificationManagerService extends SystemService { } mListeners.onPackagesChanged(queryReplace, pkgList); mConditionProviders.onPackagesChanged(queryReplace, pkgList); + mRankingHelper.onPackagesChanged(queryReplace, pkgList); } } }; @@ -1671,13 +1687,40 @@ public class NotificationManagerService extends SystemService { // Backup/restore interface @Override public byte[] getBackupPayload(int user) { - // TODO: build a payload of whatever is appropriate + if (DBG) Slog.d(TAG, "getBackupPayload u=" + user); + if (user != UserHandle.USER_OWNER) { + Slog.w(TAG, "getBackupPayload: cannot backup policy for user " + user); + return null; + } + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + writePolicyXml(baos, true /*forBackup*/); + return baos.toByteArray(); + } catch (IOException e) { + Slog.w(TAG, "getBackupPayload: error writing payload for user " + user, e); + } return null; } @Override public void applyRestore(byte[] payload, int user) { - // TODO: apply the restored payload as new current state + if (DBG) Slog.d(TAG, "applyRestore u=" + user + " payload=" + + (payload != null ? new String(payload, StandardCharsets.UTF_8) : null)); + if (payload == null) { + Slog.w(TAG, "applyRestore: no payload to restore for user " + user); + return; + } + if (user != UserHandle.USER_OWNER) { + Slog.w(TAG, "applyRestore: cannot restore policy for user " + user); + return; + } + final ByteArrayInputStream bais = new ByteArrayInputStream(payload); + try { + readPolicyXml(bais, true /*forRestore*/); + savePolicyFile(); + } catch (NumberFormatException | XmlPullParserException | IOException e) { + Slog.w(TAG, "applyRestore: error reading payload", e); + } } @Override diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java index 88055ba5a1d5..e503ac856a5f 100644 --- a/services/core/java/com/android/server/notification/RankingHelper.java +++ b/services/core/java/com/android/server/notification/RankingHelper.java @@ -17,6 +17,8 @@ package com.android.server.notification; import android.app.Notification; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; import android.os.Message; import android.os.UserHandle; @@ -61,6 +63,7 @@ public class RankingHelper implements RankingConfig { private final ArrayMap<String, Record> mRecords = new ArrayMap<>(); // pkg|uid => Record private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp = new ArrayMap<>(); + private final ArrayMap<String, Record> mRestoredWithoutUids = new ArrayMap<>(); // pkg => Record private final Context mContext; private final Handler mRankingHandler; @@ -119,12 +122,15 @@ public class RankingHelper implements RankingConfig { } } - public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException { + public void readXml(XmlPullParser parser, boolean forRestore) + throws XmlPullParserException, IOException { + final PackageManager pm = mContext.getPackageManager(); int type = parser.getEventType(); if (type != XmlPullParser.START_TAG) return; String tag = parser.getName(); if (!TAG_RANKING.equals(tag)) return; mRecords.clear(); + mRestoredWithoutUids.clear(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) { @@ -132,21 +138,38 @@ public class RankingHelper implements RankingConfig { } if (type == XmlPullParser.START_TAG) { if (TAG_PACKAGE.equals(tag)) { - int uid = safeInt(parser, ATT_UID, UserHandle.USER_ALL); + int uid = safeInt(parser, ATT_UID, Record.UNKNOWN_UID); int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY); boolean peekable = safeBool(parser, ATT_PEEKABLE, DEFAULT_PEEKABLE); int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY); String name = parser.getAttributeValue(null, ATT_NAME); if (!TextUtils.isEmpty(name)) { + if (forRestore) { + try { + uid = pm.getPackageUid(name, UserHandle.USER_OWNER); + } catch (NameNotFoundException e) { + // noop + } + } + Record r = null; + if (uid == Record.UNKNOWN_UID) { + r = mRestoredWithoutUids.get(name); + if (r == null) { + r = new Record(); + mRestoredWithoutUids.put(name, r); + } + } else { + r = getOrCreateRecord(name, uid); + } if (priority != DEFAULT_PRIORITY) { - getOrCreateRecord(name, uid).priority = priority; + r.priority = priority; } if (peekable != DEFAULT_PEEKABLE) { - getOrCreateRecord(name, uid).peekable = peekable; + r.peekable = peekable; } if (vis != DEFAULT_VISIBILITY) { - getOrCreateRecord(name, uid).visibility = vis; + r.visibility = vis; } } } @@ -182,13 +205,16 @@ public class RankingHelper implements RankingConfig { } } - public void writeXml(XmlSerializer out) throws IOException { + public void writeXml(XmlSerializer out, boolean forBackup) throws IOException { out.startTag(null, TAG_RANKING); out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION)); final int N = mRecords.size(); for (int i = 0; i < N; i++) { final Record r = mRecords.valueAt(i); + if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_OWNER) { + continue; + } out.startTag(null, TAG_PACKAGE); out.attribute(null, ATT_NAME, r.pkg); if (r.priority != DEFAULT_PRIORITY) { @@ -200,7 +226,9 @@ public class RankingHelper implements RankingConfig { if (r.visibility != DEFAULT_VISIBILITY) { out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility)); } - out.attribute(null, ATT_UID, Integer.toString(r.uid)); + if (!forBackup) { + out.attribute(null, ATT_UID, Integer.toString(r.uid)); + } out.endTag(null, TAG_PACKAGE); } out.endTag(null, TAG_RANKING); @@ -364,15 +392,21 @@ public class RankingHelper implements RankingConfig { pw.print(prefix); pw.println("per-package config:"); } - final int N = mRecords.size(); + dumpRecords(pw, prefix, filter, mRecords); + dumpRecords(pw, prefix, filter, mRestoredWithoutUids); + } + + private static void dumpRecords(PrintWriter pw, String prefix, + NotificationManagerService.DumpFilter filter, ArrayMap<String, Record> records) { + final int N = records.size(); for (int i = 0; i < N; i++) { - final Record r = mRecords.valueAt(i); + final Record r = records.valueAt(i); if (filter == null || filter.matches(r.pkg)) { pw.print(prefix); pw.print(" "); pw.print(r.pkg); pw.print(" ("); - pw.print(r.uid); + pw.print(r.uid == Record.UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid)); pw.print(')'); if (r.priority != DEFAULT_PRIORITY) { pw.print(" priority="); @@ -391,11 +425,39 @@ public class RankingHelper implements RankingConfig { } } + public void onPackagesChanged(boolean queryReplace, String[] pkgList) { + if (queryReplace || pkgList == null || pkgList.length == 0 + || mRestoredWithoutUids.isEmpty()) { + return; // nothing to do + } + final PackageManager pm = mContext.getPackageManager(); + boolean updated = false; + for (String pkg : pkgList) { + final Record r = mRestoredWithoutUids.get(pkg); + if (r != null) { + try { + r.uid = pm.getPackageUid(r.pkg, UserHandle.USER_OWNER); + mRestoredWithoutUids.remove(pkg); + mRecords.put(recordKey(r.pkg, r.uid), r); + updated = true; + } catch (NameNotFoundException e) { + // noop + } + } + } + if (updated) { + updateConfig(); + } + } + private static class Record { + static int UNKNOWN_UID = UserHandle.USER_NULL; + String pkg; - int uid; + int uid = UNKNOWN_UID; int priority = DEFAULT_PRIORITY; boolean peekable = DEFAULT_PEEKABLE; int visibility = DEFAULT_VISIBILITY; } + } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 702c194b1dcb..755b2ead7808 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -256,17 +256,27 @@ public class ZenModeHelper { } } - public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException { + public void readXml(XmlPullParser parser, boolean forRestore) + throws XmlPullParserException, IOException { final ZenModeConfig config = ZenModeConfig.readXml(parser, mConfigMigration); if (config != null) { + if (forRestore) { + if (config.user != UserHandle.USER_OWNER) { + return; + } + config.manualRule = null; // don't restore the manual rule + } if (DEBUG) Log.d(TAG, "readXml"); setConfig(config, "readXml"); } } - public void writeXml(XmlSerializer out) throws IOException { + public void writeXml(XmlSerializer out, boolean forBackup) throws IOException { final int N = mConfigs.size(); for (int i = 0; i < N; i++) { + if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_OWNER) { + continue; + } mConfigs.valueAt(i).writeXml(out); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5d8979f434e7..6042c271c182 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -466,6 +466,8 @@ public class WindowManagerService extends IWindowManager.Stub boolean mShowingBootMessages = false; boolean mBootAnimationStopped = false; + /** Dump of the windows and app tokens at the time of the last ANR. Cleared after + * LAST_ANR_LIFETIME_DURATION_MSECS */ String mLastANRState; /** All DisplayContents in the world, kept here */ @@ -1025,7 +1027,7 @@ public class WindowManagerService extends IWindowManager.Stub private void placeWindowAfter(WindowState pos, WindowState window) { final WindowList windows = pos.getWindowList(); final int i = windows.indexOf(pos); - if (true || DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( + if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( TAG, "Adding window " + window + " at " + (i+1) + " of " + windows.size() + " (after " + pos + ")"); windows.add(i+1, window); @@ -1035,7 +1037,7 @@ public class WindowManagerService extends IWindowManager.Stub private void placeWindowBefore(WindowState pos, WindowState window) { final WindowList windows = pos.getWindowList(); int i = windows.indexOf(pos); - if (true || DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( + if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( TAG, "Adding window " + window + " at " + i + " of " + windows.size() + " (before " + pos + ")"); if (i < 0) { @@ -1133,7 +1135,7 @@ public class WindowManagerService extends IWindowManager.Stub //apptoken note that the window could be a floating window //that was created later or a window at the top of the list of //windows associated with this token. - if (true || DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, + if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " + N); windows.add(newIdx + 1, win); @@ -1255,7 +1257,7 @@ public class WindowManagerService extends IWindowManager.Stub break; } } - if (true || DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, + if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "Based on layer: Adding window " + win + " at " + (i + 1) + " of " + N); windows.add(i + 1, win); mWindowsChanged = true; @@ -3720,7 +3722,7 @@ public class WindowManagerService extends IWindowManager.Stub atoken.layoutConfigChanges = (configChanges & (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0; atoken.mLaunchTaskBehind = launchTaskBehind; - if (true || DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken + if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken + " to stack=" + stackId + " task=" + taskId + " at " + addPos); Task task = mTaskIdToTask.get(taskId); diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java index eaff6c74ad30..f81b001cdd18 100644 --- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java +++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java @@ -17,6 +17,7 @@ package com.android.compatibilitytest; import android.app.ActivityManager; +import android.app.UiAutomation; import android.app.UiModeManager; import android.app.ActivityManager.ProcessErrorStateInfo; import android.app.ActivityManager.RunningTaskInfo; @@ -82,10 +83,12 @@ public class AppCompatibility extends InstrumentationTestCase { if (workspaceLaunchTimeoutMsecs != null) { mWorkspaceLaunchTimeout = Integer.parseInt(workspaceLaunchTimeoutMsecs); } + getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_FREEZE_0); } @Override protected void tearDown() throws Exception { + getInstrumentation().getUiAutomation().setRotation(UiAutomation.ROTATION_UNFREEZE); super.tearDown(); } |