summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/BatteryStats.java42
-rw-r--r--core/java/android/widget/ScrollView.java44
-rw-r--r--core/res/res/values/themes_micro.xml17
-rw-r--r--docs/html/preview/api-overview.jd4
-rw-r--r--docs/html/preview/testing/performance.jd14
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java119
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java84
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java12
-rw-r--r--tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java3
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 &amp; 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();
}