summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java')
-rw-r--r--services/core/java/com/android/server/AppOpsService.java5
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java6
-rw-r--r--services/core/java/com/android/server/DeviceIdleController.java5
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java5
-rw-r--r--services/core/java/com/android/server/MountService.java4
-rw-r--r--services/core/java/com/android/server/WiredAccessoryManager.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerDebugConfig.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java46
-rw-r--r--services/core/java/com/android/server/am/CompatModePackages.java5
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java16
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java26
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java13
-rw-r--r--services/core/java/com/android/server/content/SyncStorageEngine.java11
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayAdapter.java255
-rw-r--r--services/core/java/com/android/server/display/OverlayDisplayWindow.java38
-rw-r--r--services/core/java/com/android/server/display/PersistentDataStore.java7
-rw-r--r--services/core/java/com/android/server/input/PersistentDataStore.java5
-rw-r--r--services/core/java/com/android/server/job/JobStore.java5
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java5
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java33
-rw-r--r--services/core/java/com/android/server/pm/Settings.java11
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java13
-rw-r--r--services/core/java/com/android/server/tv/PersistentDataStore.java5
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java81
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java43
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java29
-rw-r--r--services/core/java/com/android/server/wm/AppWindowAnimator.java65
-rw-r--r--services/core/java/com/android/server/wm/DisplaySettings.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java105
32 files changed, 606 insertions, 268 deletions
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 1366149..7d427d6 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -23,6 +23,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -915,7 +916,7 @@ public class AppOpsService extends IAppOpsService.Stub {
boolean success = false;
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -1075,7 +1076,7 @@ public class AppOpsService extends IAppOpsService.Stub {
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "app-ops");
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0961ffe..16b3dcf 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1982,7 +1982,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (msg.arg1 == 0) {
setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
} else {
- NetworkAgentInfo nai = null;
+ final NetworkAgentInfo nai;
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(msg.arg2);
}
@@ -1990,6 +1990,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
break;
}
+ nai.captivePortalDetected = true;
setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
}
@@ -2384,7 +2385,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Only prompt if the network is unvalidated and was explicitly selected by the user, and if
// we haven't already been told to switch to it regardless of whether it validated or not.
- if (nai == null || nai.everValidated ||
+ // Also don't prompt on captive portals because we're already prompting the user to sign in.
+ if (nai == null || nai.everValidated || nai.captivePortalDetected ||
!nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
return;
}
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 5dbf4c9..9b7b2d3 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -71,6 +71,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
/**
* Keeps track of device idleness and drives low power mode based on that.
@@ -679,7 +680,7 @@ public class DeviceIdleController extends SystemService {
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
readConfigFileLocked(parser);
} catch (XmlPullParserException e) {
} finally {
@@ -756,7 +757,7 @@ public class DeviceIdleController extends SystemService {
try {
synchronized (this) {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(memStream, "utf-8");
+ out.setOutput(memStream, StandardCharsets.UTF_8.name());
writeConfigFileLocked(out);
}
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index f5d323d..256a662 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -126,6 +126,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -3521,7 +3522,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
try {
fos = subtypesFile.startWrite();
final XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, NODE_SUBTYPES);
@@ -3567,7 +3568,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
try {
fis = subtypesFile.openRead();
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type = parser.getEventType();
// Skip parsing until START_TAG
while ((type = parser.next()) != XmlPullParser.START_TAG
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 003d0e7..c32de41 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -1204,7 +1204,7 @@ class MountService extends IMountService.Stub
try {
fis = mSettingsFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -1244,7 +1244,7 @@ class MountService extends IMountService.Stub
fos = mSettingsFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_VOLUMES);
writeIntAttribute(out, ATTR_VERSION, VERSION_FIX_PRIMARY);
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index 0de8c8d..e0e6070 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -216,9 +216,9 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
mWakeLock.acquire();
- Log.i(TAG, "MSG_NEW_DEVICE_STATE ");
+ Log.i(TAG, "MSG_NEW_DEVICE_STATE");
Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
- mHeadsetState, newName);
+ mHeadsetState, "");
mHandler.sendMessage(msg);
mHeadsetState = headsetState;
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index d64e39f..925fae0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -51,6 +51,7 @@ class ActivityManagerDebugConfig {
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
+ static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
static final boolean DEBUG_LRU = DEBUG_ALL || false;
static final boolean DEBUG_MU = DEBUG_ALL || false;
static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
@@ -82,6 +83,7 @@ class ActivityManagerDebugConfig {
static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
static final String POSTFIX_LOCKSCREEN = (APPEND_CATEGORY_NAME) ? "_LOCKSCREEN" : "";
+ static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LOCKTASK" : "";
static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
static final String POSTFIX_MU = "_MU";
static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : "";
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0ee1ae4..2158395 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -235,6 +235,7 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -264,6 +265,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_LRU = TAG + POSTFIX_LRU;
private static final String TAG_MU = TAG + POSTFIX_MU;
private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
@@ -7671,7 +7673,7 @@ public final class ActivityManagerService extends ActivityManagerNative
fos = mGrantFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_URI_GRANTS);
for (UriPermission.Snapshot perm : persist) {
@@ -7706,7 +7708,7 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
fis = mGrantFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -8761,6 +8763,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException("updateLockTaskPackage called from non-system process");
}
synchronized (this) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
mLockTaskPackages.put(userId, packages);
mStackSupervisor.onLockTaskPackagesUpdatedLocked();
}
@@ -8768,6 +8771,7 @@ public final class ActivityManagerService extends ActivityManagerNative
void startLockTaskModeLocked(TaskRecord task) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
return;
}
@@ -8784,6 +8788,7 @@ public final class ActivityManagerService extends ActivityManagerNative
task.mLockTaskUid = callingUid;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
// startLockTask() called by app and task mode is lockTaskModeDefault.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
StatusBarManagerInternal statusBarManager =
LocalServices.getService(StatusBarManagerInternal.class);
if (statusBarManager != null) {
@@ -8796,6 +8801,8 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new IllegalArgumentException("Invalid task, not in foreground");
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
+ "Locking fully");
mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
ActivityManager.LOCK_TASK_MODE_PINNED :
ActivityManager.LOCK_TASK_MODE_LOCKED,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 54ea6d7..f304828 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -117,6 +117,7 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -124,6 +125,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -1183,7 +1185,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
final TaskRecord task = r.task;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
- setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "lockTaskLaunchMode attribute");
+ setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE");
}
final ActivityStack stack = task.stack;
@@ -3327,6 +3329,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
+ private String lockTaskModeToString() {
+ switch (mLockTaskModeState) {
+ case LOCK_TASK_MODE_LOCKED:
+ return "LOCKED";
+ case LOCK_TASK_MODE_PINNED:
+ return "PINNED";
+ case LOCK_TASK_MODE_NONE:
+ return "NONE";
+ default: return "unknown=" + mLockTaskModeState;
+ }
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
@@ -3334,7 +3348,16 @@ public final class ActivityStackSupervisor implements DisplayListener {
pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
- pw.print(prefix); pw.println("mLockTaskModeTasks" + mLockTaskModeTasks);
+ pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
+ final SparseArray<String[]> packages = mService.mLockTaskPackages;
+ if (packages.size() > 0) {
+ pw.println(" mLockTaskPackages (userId:packages)=");
+ for (int i = 0; i < packages.size(); ++i) {
+ pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
+ pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
+ }
+ }
+ pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
@@ -3654,6 +3677,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
void removeLockedTaskLocked(final TaskRecord task) {
if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) {
// Last one.
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
+ " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
final Message lockTaskMsg = Message.obtain();
lockTaskMsg.arg1 = task.userId;
lockTaskMsg.what = LOCK_TASK_END_MSG;
@@ -3679,20 +3704,26 @@ public final class ActivityStackSupervisor implements DisplayListener {
removeLockedTaskLocked(lockedTask);
if (!mLockTaskModeTasks.isEmpty()) {
// There are locked tasks remaining, can only finish this task, not unlock it.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Tasks remaining, can't unlock");
lockedTask.performClearTaskLocked();
resumeTopActivitiesLocked();
return;
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
return;
}
// Should have already been checked, but do it again.
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Can't lock due to auth");
return;
}
if (isLockTaskModeViolation(task)) {
- Slog.e(TAG, "setLockTaskMode: Attempt to start an unauthorized lock task.");
+ Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
return;
}
@@ -3706,6 +3737,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
mHandler.sendMessage(lockTaskMsg);
}
// Add it or move it to the top.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
+ " Callers=" + Debug.getCallers(4));
mLockTaskModeTasks.remove(task);
mLockTaskModeTasks.add(task);
@@ -3759,6 +3792,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
stack.onLockTaskPackagesUpdatedLocked();
}
}
+ final ActivityRecord r = topRunningActivityLocked();
+ final TaskRecord task = r != null ? r.task : null;
+ if (mLockTaskModeTasks.isEmpty() && task != null
+ && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
+ // This task must have just been authorized.
+ setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated");
+ }
if (didSomething) {
resumeTopActivitiesLocked();
}
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 0fe9231..814e8b4 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -21,6 +21,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -86,7 +87,7 @@ public final class CompatModePackages {
try {
fis = mFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
@@ -362,7 +363,7 @@ public final class CompatModePackages {
try {
fos = mFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "compat-packages");
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5e9f2b0..f653e9e 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -63,6 +63,7 @@ import java.util.ArrayList;
final class TaskRecord {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
static final String ATTR_TASKID = "task_id";
@@ -134,12 +135,11 @@ final class TaskRecord {
/** Can't be put in lockTask mode. */
final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
- /** Can enter lockTask with user approval if not already in lockTask. */
+ /** Can enter lockTask with user approval. Can never start over existing lockTask task. */
final static int LOCK_TASK_AUTH_PINNABLE = 1;
/** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
- /** Enters LOCK_TASK_MODE_LOCKED via startLockTask(), enters LOCK_TASK_MODE_PINNED from
- * Overview. Can start over existing lockTask task. */
+ /** Can enter lockTask with user approval. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_WHITELISTED = 3;
int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
@@ -744,21 +744,31 @@ final class TaskRecord {
void setLockTaskAuth() {
switch (mLockTaskMode) {
case LOCK_TASK_LAUNCH_MODE_DEFAULT:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "WHITELISTED" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_NEVER:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_ALWAYS:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 47ddfec..6c83192 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -564,8 +564,6 @@ public class AudioService extends IAudioService.Stub {
return "card=" + card + ";device=" + device + ";";
}
- private final String DEVICE_NAME_A2DP = "a2dp-device";
-
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -4387,7 +4385,7 @@ public class AudioService extends IAudioService.Stub {
}
// must be called synchronized on mConnectedDevices
- private void makeA2dpDeviceAvailable(String address) {
+ private void makeA2dpDeviceAvailable(String address, String name) {
// enable A2DP before notifying A2DP connection to avoid unecessary processing in
// audio policy manager
VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
@@ -4395,12 +4393,12 @@ public class AudioService extends IAudioService.Stub {
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0);
setBluetoothA2dpOnInt(true);
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, name);
// Reset A2DP suspend state each time a new sink is connected
AudioSystem.setParameters("A2dpSuspended=false");
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
- new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_NAME_A2DP,
+ new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name,
address));
}
@@ -4414,7 +4412,7 @@ public class AudioService extends IAudioService.Stub {
mAvrcpAbsVolSupported = false;
}
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
synchronized (mCurAudioRoutes) {
@@ -4444,17 +4442,17 @@ public class AudioService extends IAudioService.Stub {
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcAvailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, "");
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
- new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_NAME_A2DP,
+ new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, "",
address));
}
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcUnavailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
}
@@ -4520,7 +4518,7 @@ public class AudioService extends IAudioService.Stub {
makeA2dpDeviceUnavailableNow(mDockAddress);
}
}
- makeA2dpDeviceAvailable(address);
+ makeA2dpDeviceAvailable(address, btDevice.getName());
synchronized (mCurAudioRoutes) {
String name = btDevice.getAliasName();
if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
@@ -4871,7 +4869,7 @@ public class AudioService extends IAudioService.Stub {
if (btDevice == null) {
return;
}
-
+
address = btDevice.getAddress();
BluetoothClass btClass = btDevice.getBluetoothClass();
if (btClass != null) {
@@ -4891,9 +4889,11 @@ public class AudioService extends IAudioService.Stub {
}
boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
+
+ String btDeviceName = btDevice.getName();
boolean success =
- handleDeviceConnection(connected, outDevice, address, "Bluetooth Headset") &&
- handleDeviceConnection(connected, inDevice, address, "Bluetooth Headset");
+ handleDeviceConnection(connected, outDevice, address, btDeviceName) &&
+ handleDeviceConnection(connected, inDevice, address, btDeviceName);
if (success) {
synchronized (mScoClients) {
if (connected) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 8a7c902..eac748f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -50,12 +50,11 @@ public class NetworkAgentInfo {
public final NetworkMisc networkMisc;
// Indicates if netd has been told to create this Network. Once created the appropriate routing
// rules are setup and routes are added so packets can begin flowing over the Network.
- // NOTE: This is a sticky bit; once set it is never cleared.
+ // This is a sticky bit; once set it is never cleared.
public boolean created;
// Set to true if this Network successfully passed validation or if it did not satisfy the
// default NetworkRequest in which case validation will not be attempted.
- // NOTE: This is a sticky bit; once set it is never cleared even if future validation attempts
- // fail.
+ // This is a sticky bit; once set it is never cleared even if future validation attempts fail.
public boolean everValidated;
// The result of the last validation attempt on this network (true if validated, false if not).
@@ -65,6 +64,10 @@ public class NetworkAgentInfo {
// TODO: Fix the network scoring code, remove this, and rename everValidated to validated.
public boolean lastValidated;
+ // Whether a captive portal was ever detected on this network.
+ // This is a sticky bit; once set it is never cleared.
+ public boolean captivePortalDetected;
+
// This represents the last score received from the NetworkAgent.
private int currentScore;
// Penalty applied to scores of Networks that have not been validated.
@@ -101,9 +104,6 @@ public class NetworkAgentInfo {
currentScore = score;
networkMonitor = new NetworkMonitor(context, handler, this, defaultRequest);
networkMisc = misc;
- created = false;
- everValidated = false;
- lastValidated = false;
}
public void addRequest(NetworkRequest networkRequest) {
@@ -166,6 +166,7 @@ public class NetworkAgentInfo {
"created{" + created + "} " +
"explicitlySelected{" + networkMisc.explicitlySelected + "} " +
"acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
+ "captivePortalDetected{" + captivePortalDetected + "} " +
"}";
}
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f154c73..d68b615 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -58,6 +58,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -1814,7 +1815,7 @@ public class SyncStorageEngine extends Handler {
Log.v(TAG_FILE, "Reading " + mAccountInfoFile.getBaseFile());
}
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
@@ -2153,7 +2154,7 @@ public class SyncStorageEngine extends Handler {
try {
fos = mAccountInfoFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -2445,7 +2446,7 @@ public class SyncStorageEngine extends Handler {
}
XmlPullParser parser;
parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
@@ -2581,7 +2582,7 @@ public class SyncStorageEngine extends Handler {
}
fos = mPendingFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
for (int i = 0; i < N; i++) {
PendingOperation pop = mPendingOperations.get(i);
@@ -2634,7 +2635,7 @@ public class SyncStorageEngine extends Handler {
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
writePendingOperationLocked(op, out);
out.endDocument();
mPendingFile.finishWrite(fos);
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 080665a..0462035 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -34,6 +34,8 @@ import android.view.SurfaceControl;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -47,6 +49,21 @@ import java.util.regex.Pattern;
* service as usual. The UI handler is only used by the {@link OverlayDisplayWindow}.
* </p><p>
* Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
+ * </p><p>
+ * This adapter is configured via the
+ * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
+ * formatted as follows:
+ * <pre>
+ * [mode1]|[mode2]|...,[flag1],[flag2],...
+ * </pre>
+ * with each mode specified as:
+ * <pre>
+ * [width]x[height]/[densityDpi]
+ * </pre>
+ * Supported flags:
+ * <ul>
+ * <li><pre>secure</pre>: creates a secure display</li>
+ * </ul>
* </p>
*/
final class OverlayDisplayAdapter extends DisplayAdapter {
@@ -58,8 +75,10 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
private static final int MAX_WIDTH = 4096;
private static final int MAX_HEIGHT = 4096;
- private static final Pattern SETTING_PATTERN =
- Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
+ private static final Pattern DISPLAY_PATTERN =
+ Pattern.compile("([^,]+)(,[a-z]+)*");
+ private static final Pattern MODE_PATTERN =
+ Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
// Unique id prefix for overlay displays.
private static final String UNIQUE_ID_PREFIX = "overlay:";
@@ -136,40 +155,49 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
int count = 0;
for (String part : value.split(";")) {
- Matcher matcher = SETTING_PATTERN.matcher(part);
- if (matcher.matches()) {
+ Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
+ if (displayMatcher.matches()) {
if (count >= 4) {
Slog.w(TAG, "Too many overlay display devices specified: " + value);
break;
}
- try {
- int width = Integer.parseInt(matcher.group(1), 10);
- int height = Integer.parseInt(matcher.group(2), 10);
- int densityDpi = Integer.parseInt(matcher.group(3), 10);
- String flagString = matcher.group(4);
- if (width >= MIN_WIDTH && width <= MAX_WIDTH
- && height >= MIN_HEIGHT && height <= MAX_HEIGHT
- && densityDpi >= DisplayMetrics.DENSITY_LOW
- && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
- int number = ++count;
- String name = getContext().getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_name,
- number);
- int gravity = chooseOverlayGravity(number);
- boolean secure = flagString != null && flagString.contains(",secure");
-
- Slog.i(TAG, "Showing overlay display device #" + number
- + ": name=" + name + ", width=" + width + ", height=" + height
- + ", densityDpi=" + densityDpi + ", secure=" + secure);
-
- mOverlays.add(new OverlayDisplayHandle(name,
- width, height, densityDpi, gravity, secure, number));
+ String modeString = displayMatcher.group(1);
+ String flagString = displayMatcher.group(2);
+ ArrayList<OverlayMode> modes = new ArrayList<>();
+ for (String mode : modeString.split("\\|")) {
+ Matcher modeMatcher = MODE_PATTERN.matcher(mode);
+ if (modeMatcher.matches()) {
+ try {
+ int width = Integer.parseInt(modeMatcher.group(1), 10);
+ int height = Integer.parseInt(modeMatcher.group(2), 10);
+ int densityDpi = Integer.parseInt(modeMatcher.group(3), 10);
+ if (width >= MIN_WIDTH && width <= MAX_WIDTH
+ && height >= MIN_HEIGHT && height <= MAX_HEIGHT
+ && densityDpi >= DisplayMetrics.DENSITY_LOW
+ && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
+ modes.add(new OverlayMode(width, height, densityDpi));
+ continue;
+ }
+ } catch (NumberFormatException ex) {
+ }
+ } else if (mode.isEmpty()) {
continue;
}
- } catch (NumberFormatException ex) {
}
- } else if (part.isEmpty()) {
- continue;
+ if (!modes.isEmpty()) {
+ int number = ++count;
+ String name = getContext().getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_name,
+ number);
+ int gravity = chooseOverlayGravity(number);
+ boolean secure = flagString != null && flagString.contains(",secure");
+
+ Slog.i(TAG, "Showing overlay display device #" + number
+ + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()));
+
+ mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number));
+ continue;
+ }
}
Slog.w(TAG, "Malformed overlay display devices setting: " + value);
}
@@ -189,36 +217,41 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
}
}
- private final class OverlayDisplayDevice extends DisplayDevice {
+ private abstract class OverlayDisplayDevice extends DisplayDevice {
private final String mName;
- private final int mWidth;
- private final int mHeight;
private final float mRefreshRate;
private final long mDisplayPresentationDeadlineNanos;
- private final int mDensityDpi;
private final boolean mSecure;
- private final Display.Mode mMode;
+ private final List<OverlayMode> mRawModes;
+ private final Display.Mode[] mModes;
+ private final int mDefaultMode;
private int mState;
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
+ private int mActiveMode;
public OverlayDisplayDevice(IBinder displayToken, String name,
- int width, int height, float refreshRate, long presentationDeadlineNanos,
- int densityDpi, boolean secure, int state,
+ List<OverlayMode> modes, int activeMode, int defaultMode,
+ float refreshRate, long presentationDeadlineNanos,
+ boolean secure, int state,
SurfaceTexture surfaceTexture, int number) {
super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
mName = name;
- mWidth = width;
- mHeight = height;
mRefreshRate = refreshRate;
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
- mDensityDpi = densityDpi;
mSecure = secure;
mState = state;
mSurfaceTexture = surfaceTexture;
- mMode = createMode(width, height, refreshRate);
+ mRawModes = modes;
+ mModes = new Display.Mode[modes.size()];
+ for (int i = 0; i < modes.size(); i++) {
+ OverlayMode mode = modes.get(i);
+ mModes[i] = createMode(mode.mWidth, mode.mHeight, refreshRate);
+ }
+ mActiveMode = activeMode;
+ mDefaultMode = defaultMode;
}
public void destroyLocked() {
@@ -248,17 +281,19 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
+ Display.Mode mode = mModes[mActiveMode];
+ OverlayMode rawMode = mRawModes.get(mActiveMode);
mInfo = new DisplayDeviceInfo();
mInfo.name = mName;
mInfo.uniqueId = getUniqueId();
- mInfo.width = mWidth;
- mInfo.height = mHeight;
- mInfo.modeId = mMode.getModeId();
- mInfo.defaultModeId = mMode.getModeId();
- mInfo.supportedModes = new Display.Mode[] { mMode };
- mInfo.densityDpi = mDensityDpi;
- mInfo.xDpi = mDensityDpi;
- mInfo.yDpi = mDensityDpi;
+ mInfo.width = mode.getPhysicalWidth();
+ mInfo.height = mode.getPhysicalHeight();
+ mInfo.modeId = mode.getModeId();
+ mInfo.defaultModeId = mModes[0].getModeId();
+ mInfo.supportedModes = mModes;
+ mInfo.densityDpi = rawMode.mDensityDpi;
+ mInfo.xDpi = rawMode.mDensityDpi;
+ mInfo.yDpi = rawMode.mDensityDpi;
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
@@ -271,6 +306,40 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
}
return mInfo;
}
+
+ @Override
+ public void requestModeInTransactionLocked(int id) {
+ int index = -1;
+ if (id == 0) {
+ // Use the default.
+ index = 0;
+ } else {
+ for (int i = 0; i < mModes.length; i++) {
+ if (mModes[i].getModeId() == id) {
+ index = i;
+ break;
+ }
+ }
+ }
+ if (index == -1) {
+ Slog.w(TAG, "Unable to locate mode " + id + ", reverting to default.");
+ index = mDefaultMode;
+ }
+ if (mActiveMode == index) {
+ return;
+ }
+ mActiveMode = index;
+ mInfo = null;
+ sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
+ onModeChangedLocked(index);
+ }
+
+ /**
+ * Called when the device switched to a new mode.
+ *
+ * @param index index of the mode in the list of modes
+ */
+ public abstract void onModeChangedLocked(int index);
}
/**
@@ -280,27 +349,32 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
* Guarded by the {@link DisplayManagerService.SyncRoot} lock.
*/
private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
+ private static final int DEFAULT_MODE_INDEX = 0;
+
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private final List<OverlayMode> mModes;
private final int mGravity;
private final boolean mSecure;
private final int mNumber;
private OverlayDisplayWindow mWindow;
private OverlayDisplayDevice mDevice;
+ private int mActiveMode;
- public OverlayDisplayHandle(String name, int width,
- int height, int densityDpi, int gravity, boolean secure, int number) {
+ public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity,
+ boolean secure, int number) {
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
+ mModes = modes;
mGravity = gravity;
mSecure = secure;
mNumber = number;
+ mActiveMode = 0;
+
+ showLocked();
+ }
+
+ private void showLocked() {
mUiHandler.post(mShowRunnable);
}
@@ -309,15 +383,28 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
mUiHandler.post(mDismissRunnable);
}
+ private void onActiveModeChangedLocked(int index) {
+ mUiHandler.removeCallbacks(mResizeRunnable);
+ mActiveMode = index;
+ if (mWindow != null) {
+ mUiHandler.post(mResizeRunnable);
+ }
+ }
+
// Called on the UI thread.
@Override
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
long presentationDeadlineNanos, int state) {
synchronized (getSyncRoot()) {
IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
- mDevice = new OverlayDisplayDevice(displayToken, mName,
- mWidth, mHeight, refreshRate, presentationDeadlineNanos,
- mDensityDpi, mSecure, state, surfaceTexture, mNumber);
+ mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
+ DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
+ mSecure, state, surfaceTexture, mNumber) {
+ @Override
+ public void onModeChangedLocked(int index) {
+ onActiveModeChangedLocked(index);
+ }
+ };
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
}
@@ -347,9 +434,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
public void dumpLocked(PrintWriter pw) {
pw.println(" " + mName + ":");
- pw.println(" mWidth=" + mWidth);
- pw.println(" mHeight=" + mHeight);
- pw.println(" mDensityDpi=" + mDensityDpi);
+ pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
+ pw.println(" mActiveMode=" + mActiveMode);
pw.println(" mGravity=" + mGravity);
pw.println(" mSecure=" + mSecure);
pw.println(" mNumber=" + mNumber);
@@ -366,8 +452,9 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
private final Runnable mShowRunnable = new Runnable() {
@Override
public void run() {
+ OverlayMode mode = mModes.get(mActiveMode);
OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
- mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure,
+ mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure,
OverlayDisplayHandle.this);
window.show();
@@ -392,5 +479,47 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
}
}
};
+
+ // Runs on the UI thread.
+ private final Runnable mResizeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ OverlayMode mode;
+ OverlayDisplayWindow window;
+ synchronized (getSyncRoot()) {
+ if (mWindow == null) {
+ return;
+ }
+ mode = mModes.get(mActiveMode);
+ window = mWindow;
+ }
+ window.resize(mode.mWidth, mode.mHeight, mode.mDensityDpi);
+ }
+ };
+ }
+
+ /**
+ * A display mode for an overlay display.
+ */
+ private static final class OverlayMode {
+ final int mWidth;
+ final int mHeight;
+ final int mDensityDpi;
+
+ OverlayMode(int width, int height, int densityDpi) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{")
+ .append("width=").append(mWidth)
+ .append(", height=").append(mHeight)
+ .append(", densityDpi=").append(mDensityDpi)
+ .append("}")
+ .toString();
+ }
}
}
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 786889a..f23caf2 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -60,9 +60,9 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
private final Context mContext;
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private int mWidth;
+ private int mHeight;
+ private int mDensityDpi;
private final int mGravity;
private final boolean mSecure;
private final Listener mListener;
@@ -97,19 +97,9 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
Listener listener) {
mContext = context;
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
mGravity = gravity;
mSecure = secure;
mListener = listener;
- mTitle = context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_title,
- mName, mWidth, mHeight, mDensityDpi);
- if (secure) {
- mTitle += context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
- }
mDisplayManager = (DisplayManager)context.getSystemService(
Context.DISPLAY_SERVICE);
@@ -119,6 +109,8 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
mDefaultDisplay = mWindowManager.getDefaultDisplay();
updateDefaultDisplayInfo();
+ resize(width, height, densityDpi, false /* doLayout */);
+
createWindow();
}
@@ -145,6 +137,26 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
}
}
+ public void resize(int width, int height, int densityDpi) {
+ resize(width, height, densityDpi, true /* doLayout */);
+ }
+
+ private void resize(int width, int height, int densityDpi, boolean doLayout) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ mTitle = mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_title,
+ mName, mWidth, mHeight, mDensityDpi);
+ if (mSecure) {
+ mTitle += mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
+ }
+ if (doLayout) {
+ relayout();
+ }
+ }
+
public void relayout() {
if (mWindowVisible) {
updateWindowParams();
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 67b3695..d676b35 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -35,6 +35,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import libcore.io.IoUtils;
@@ -195,7 +196,7 @@ final class PersistentDataStore {
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
@@ -215,7 +216,7 @@ final class PersistentDataStore {
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
@@ -284,4 +285,4 @@ final class PersistentDataStore {
serializer.endTag(null, "display-manager-state");
serializer.endDocument();
}
-} \ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index 92fa813..f6d7244 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -37,6 +37,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -214,7 +215,7 @@ final class PersistentDataStore {
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(InputManagerService.TAG, "Failed to load input manager persistent store data.", ex);
@@ -234,7 +235,7 @@ final class PersistentDataStore {
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index b64c677..24d4f15 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -41,6 +41,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -292,7 +293,7 @@ public class JobStore {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(baos, "utf-8");
+ out.setOutput(baos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -450,7 +451,7 @@ public class JobStore {
private List<JobStatus> readJobMapImpl(FileInputStream fis)
throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0ae6735..24ab3b8 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -170,6 +170,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -1290,7 +1291,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
try {
fis = mPolicyFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
int version = VERSION_INIT;
@@ -1425,7 +1426,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
fos = mPolicyFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_POLICY_LIST);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 290fb65..ec039b0 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -120,6 +120,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
@@ -391,7 +392,7 @@ public class NotificationManagerService extends SystemService {
try {
infile = mPolicyFile.openRead();
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(infile, null);
+ parser.setInput(infile, StandardCharsets.UTF_8.name());
int type;
String tag;
@@ -449,7 +450,7 @@ public class NotificationManagerService extends SystemService {
try {
final XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_BODY);
out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 09096ff..a1738a2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -105,6 +105,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
@@ -323,7 +324,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
try {
fis = mSessionsFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -410,7 +411,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
fos = mSessionsFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_SESSIONS);
final int size = mSessions.size();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 19210c9..944fa52 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4137,7 +4137,9 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
final int count = candidates.size();
- // First, try to use the domain prefered App
+ // First, try to use the domain prefered App. Partition the candidates into four lists:
+ // one for the final results, one for the "do not use ever", one for "undefined status"
+ // and finally one for "Browser App type".
for (int n=0; n<count; n++) {
ResolveInfo info = candidates.get(n);
String packageName = info.activityInfo.packageName;
@@ -4159,19 +4161,19 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
+ // Add all undefined Apps as we want them to appear in the Disambiguation dialog.
+ result.addAll(undefinedList);
// If there is nothing selected, add all candidates and remove the ones that the User
// has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and
- // also remove any undefined ones and Browser Apps ones.
- // If there is still none after this pass, add all undefined one and Browser Apps and
+ // also remove Browser Apps ones.
+ // If there is still none after this pass, add all Browser Apps and
// let the User decide with the Disambiguation dialog if there are several ones.
if (result.size() == 0) {
result.addAll(candidates);
}
result.removeAll(neverList);
result.removeAll(matchAllList);
- result.removeAll(undefinedList);
if (result.size() == 0) {
- result.addAll(undefinedList);
if ((flags & MATCH_ALL) != 0) {
result.addAll(matchAllList);
} else {
@@ -11459,6 +11461,21 @@ public class PackageManagerService extends IPackageManager.Stub {
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
}
+
+ // Prevent apps opting out from runtime permissions
+ if (replace) {
+ PackageParser.Package oldPackage = mPackages.get(pkgName);
+ final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
+ final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
+ if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
+ && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
+ res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
+ "Package " + pkg.packageName + " new target SDK " + newTargetSdk
+ + " doesn't support runtime permissions but the old"
+ + " target SDK " + oldTargetSdk + " does.");
+ return;
+ }
+ }
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
@@ -13037,7 +13054,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
try {
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(dataStream, "utf-8");
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.startTag(null, TAG_PREFERRED_BACKUP);
@@ -13066,7 +13083,7 @@ public class PackageManagerService extends IPackageManager.Stub {
try {
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new ByteArrayInputStream(backup), null);
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -13848,7 +13865,7 @@ public class PackageManagerService extends IPackageManager.Stub {
BufferedOutputStream str = new BufferedOutputStream(fout);
XmlSerializer serializer = new FastXmlSerializer();
try {
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 2e9656a..76ef19f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -94,6 +94,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1346,7 +1347,7 @@ final class Settings {
str = new FileInputStream(userPackagesStateFile);
}
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(str, null);
+ parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
while ((type=parser.next()) != XmlPullParser.START_TAG
@@ -1598,7 +1599,7 @@ final class Settings {
final BufferedOutputStream str = new BufferedOutputStream(fstr);
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -1922,7 +1923,7 @@ final class Settings {
//XmlSerializer serializer = XmlUtils.serializerInstance();
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -2339,7 +2340,7 @@ final class Settings {
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(str, null);
+ parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -4288,7 +4289,7 @@ final class Settings {
out = destination.startWrite();
XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument(null, true);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index e463fad..40c8ca3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -70,6 +70,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -670,7 +671,7 @@ public class UserManagerService extends IUserManager.Stub {
try {
fis = userListFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -823,7 +824,7 @@ public class UserManagerService extends IUserManager.Stub {
// XmlSerializer serializer = XmlUtils.serializerInstance();
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -882,7 +883,7 @@ public class UserManagerService extends IUserManager.Stub {
// XmlSerializer serializer = XmlUtils.serializerInstance();
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -964,7 +965,7 @@ public class UserManagerService extends IUserManager.Stub {
new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
fis = userFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -1569,7 +1570,7 @@ public class UserManagerService extends IUserManager.Stub {
try {
fis = restrictionsFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
XmlUtils.nextElement(parser);
if (parser.getEventType() != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read restrictions file "
@@ -1658,7 +1659,7 @@ public class UserManagerService extends IUserManager.Stub {
final BufferedOutputStream bos = new BufferedOutputStream(fos);
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index fcfaaea..f9b5b9a 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -44,6 +44,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -167,7 +168,7 @@ final class PersistentDataStore {
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException | XmlPullParserException ex) {
Slog.w(TAG, "Failed to load tv input manager persistent store data.", ex);
@@ -200,7 +201,7 @@ final class PersistentDataStore {
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e649e48..a869c20 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -39,6 +39,7 @@ import android.content.pm.ServiceInfo;
import android.graphics.Rect;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
@@ -64,6 +65,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -80,23 +82,34 @@ import com.android.server.SystemService;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.IllegalArgumentException;
+import java.lang.Integer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** This class provides a system service that manages television inputs. */
public final class TvInputManagerService extends SystemService {
private static final boolean DEBUG = false;
private static final String TAG = "TvInputManagerService";
+ // Pattern for selecting the DVB frontend devices from the list of files in the /dev directory.
+ private static final Pattern sFrontEndDevicePattern =
+ Pattern.compile("^dvb([0-9]+)\\.frontend([0-9]+)$");
+
private final Context mContext;
private final TvInputHardwareManager mTvInputHardwareManager;
@@ -1507,6 +1520,74 @@ public final class TvInputManagerService extends SystemService {
}
@Override
+ public List<DvbDeviceInfo> getDvbDeviceList() throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ArrayList<DvbDeviceInfo> deviceInfos = new ArrayList<>();
+ File devDirectory = new File("/dev");
+ for (String fileName : devDirectory.list()) {
+ Matcher matcher = sFrontEndDevicePattern.matcher(fileName);
+ if (matcher.find()) {
+ int adapterId = Integer.parseInt(matcher.group(1));
+ int deviceId = Integer.parseInt(matcher.group(2));
+ deviceInfos.add(new DvbDeviceInfo(adapterId, deviceId));
+ }
+ }
+ return Collections.unmodifiableList(deviceInfos);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device)
+ throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ String deviceFileName;
+ switch (device) {
+ case TvInputManager.DVB_DEVICE_DEMUX:
+ deviceFileName = String.format("/dev/dvb%d.demux%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_DVR:
+ deviceFileName = String.format("/dev/dvb%d.dvr%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_FRONTEND:
+ deviceFileName = String.format("/dev/dvb%d.frontend%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid DVB device: " + device);
+ }
+ try {
+ // The DVB frontend device only needs to be opened in read/write mode, which
+ // allows performing tuning operations. The DVB demux and DVR device are enough
+ // to be opened in read only mode.
+ return ParcelFileDescriptor.open(new File(deviceFileName),
+ TvInputManager.DVB_DEVICE_FRONTEND == device
+ ? ParcelFileDescriptor.MODE_READ_WRITE
+ : ParcelFileDescriptor.MODE_READ_ONLY);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int userId)
throws RemoteException {
if (mContext.checkCallingPermission(
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 755c414..7784884 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -79,6 +79,7 @@ import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
@@ -589,12 +590,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
void switchUser(int userId, IRemoteCallback reply) {
synchronized (mLock) {
mCurrentUserId = userId;
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- wallpaper = new WallpaperData(userId);
- mWallpaperMap.put(userId, wallpaper);
- loadSettingsLocked(userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
// Not started watching yet, in case wallpaper data was loaded for other reasons.
if (wallpaper.wallpaperObserver == null) {
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
@@ -717,10 +713,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
}
synchronized (mLock) {
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
@@ -782,10 +775,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
}
synchronized (mLock) {
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
if (padding.left < 0 || padding.top < 0 || padding.right < 0 || padding.bottom < 0) {
throw new IllegalArgumentException("padding must be positive: " + padding);
}
@@ -866,10 +856,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
synchronized (mLock) {
if (DEBUG) Slog.v(TAG, "setWallpaper");
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
final long ident = Binder.clearCallingIdentity();
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
@@ -1165,7 +1152,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
try {
stream = new FileOutputStream(journal.chooseForWrite(), false);
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "wp");
@@ -1229,6 +1216,22 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
return Integer.parseInt(value);
}
+ /**
+ * Sometimes it is expected the wallpaper map may not have a user's data. E.g. This could
+ * happen during user switch. The async user switch observer may not have received
+ * the event yet. We use this safe method when we don't care about this ordering and just
+ * want to update the data. The data is going to be applied when the user switch observer
+ * is eventually executed.
+ */
+ private WallpaperData getWallpaperSafeLocked(int userId) {
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ loadSettingsLocked(userId);
+ wallpaper = mWallpaperMap.get(userId);
+ }
+ return wallpaper;
+ }
+
private void loadSettingsLocked(int userId) {
if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
@@ -1248,7 +1251,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
try {
stream = new FileInputStream(file);
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
do {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 9033c9c..0357de2 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -289,11 +289,13 @@ public class AppTransition implements Dump {
return mNextAppTransitionStartY;
}
- void prepare() {
+ boolean prepare() {
if (!isRunning()) {
mAppTransitionState = APP_STATE_IDLE;
notifyAppTransitionPendingLocked();
+ return true;
}
+ return false;
}
void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
@@ -953,8 +955,8 @@ public class AppTransition implements Dump {
: com.android.internal.R.anim.voice_activity_open_exit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation voice:"
- + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " transit=" + appTransitionToString(transit)
+ + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
} else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
|| transit == TRANSIT_TASK_CLOSE
|| transit == TRANSIT_TASK_TO_BACK)) {
@@ -963,22 +965,23 @@ public class AppTransition implements Dump {
: com.android.internal.R.anim.voice_activity_close_exit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation voice:"
- + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " transit=" + appTransitionToString(transit)
+ + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
a = loadAnimationRes(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
- + " transit=" + transit + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
+ + " transit=" + appTransitionToString(transit)
+ + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
a = createClipRevealAnimationLocked(transit, enter, appFrame);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
@@ -990,7 +993,7 @@ public class AppTransition implements Dump {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
@@ -1003,7 +1006,7 @@ public class AppTransition implements Dump {
"ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
Slog.v(TAG, "applyAnimation:"
+ " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
@@ -1018,7 +1021,7 @@ public class AppTransition implements Dump {
"ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
Slog.v(TAG, "applyAnimation:"
+ " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
} else {
@@ -1084,7 +1087,7 @@ public class AppTransition implements Dump {
"applyAnimation:"
+ " anim=" + a
+ " animAttr=0x" + Integer.toHexString(animAttr)
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
return a;
@@ -1188,7 +1191,7 @@ public class AppTransition implements Dump {
@Override
public String toString() {
- return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
+ return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 21011e8..3feec82 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -16,6 +16,11 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+
import android.graphics.Matrix;
import android.util.Slog;
import android.util.TimeUtils;
@@ -78,7 +83,11 @@ public class AppWindowAnimator {
boolean deferFinalFrameCleanup;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
- ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
+ ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
+
+ /** True if the current animation was transferred from another AppWindowAnimator.
+ * See {@link #transferCurrentAnimation}*/
+ boolean usingTransferredAnimation = false;
static final Animation sDummyAnimation = new DummyAnimation();
@@ -102,9 +111,9 @@ public class AppWindowAnimator {
int zorder = anim.getZAdjustment();
int adj = 0;
if (zorder == Animation.ZORDER_TOP) {
- adj = WindowManagerService.TYPE_LAYER_OFFSET;
+ adj = TYPE_LAYER_OFFSET;
} else if (zorder == Animation.ZORDER_BOTTOM) {
- adj = -WindowManagerService.TYPE_LAYER_OFFSET;
+ adj = -TYPE_LAYER_OFFSET;
}
if (animLayerAdjustment != adj) {
@@ -140,6 +149,7 @@ public class AppWindowAnimator {
mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false;
}
+ usingTransferredAnimation = false;
}
public boolean isAnimating() {
@@ -154,19 +164,38 @@ public class AppWindowAnimator {
deferThumbnailDestruction = false;
}
+ void transferCurrentAnimation(
+ AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
+
+ if (animation != null) {
+ toAppAnimator.animation = animation;
+ animation = null;
+ toAppAnimator.animating = animating;
+ toAppAnimator.animLayerAdjustment = animLayerAdjustment;
+ animLayerAdjustment = 0;
+ toAppAnimator.updateLayers();
+ updateLayers();
+ toAppAnimator.usingTransferredAnimation = true;
+ }
+ if (transferWinAnimator != null) {
+ mAllAppWinAnimators.remove(transferWinAnimator);
+ toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
+ transferWinAnimator.mAppAnimator = toAppAnimator;
+ }
+ }
+
void updateLayers() {
- final int N = mAppToken.allAppWindows.size();
+ final int windowCount = mAppToken.allAppWindows.size();
final int adj = animLayerAdjustment;
thumbnailLayer = -1;
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < windowCount; i++) {
final WindowState w = mAppToken.allAppWindows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
winAnimator.mAnimLayer = w.mLayer + adj;
if (winAnimator.mAnimLayer > thumbnailLayer) {
thumbnailLayer = winAnimator.mAnimLayer;
}
- if (WindowManagerService.DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
- + winAnimator.mAnimLayer);
+ if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
mService.setInputMethodAnimLayerAdjustment(adj);
}
@@ -191,11 +220,11 @@ public class AppWindowAnimator {
// cache often used attributes locally
final float tmpFloats[] = mService.mTmpFloats;
thumbnailTransformation.getMatrix().getValues(tmpFloats);
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
+ if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
+ ", " + tmpFloats[Matrix.MTRANS_Y], null);
thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
+ if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
+ " layer=" + thumbnailLayer
+ " matrix=[" + tmpFloats[Matrix.MSCALE_X]
@@ -228,14 +257,14 @@ public class AppWindowAnimator {
deferFinalFrameCleanup = true;
hasMoreFrames = true;
} else {
- if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
- ", xform=" + transformation);
+ if (false && DEBUG_ANIM) Slog.v(TAG,
+ "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
+ ", xform=" + transformation);
deferFinalFrameCleanup = false;
animation = null;
clearThumbnail();
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Finished animation in " + mAppToken + " @ " + currentTime);
}
}
hasTransformation = hasMoreFrames;
@@ -258,8 +287,8 @@ public class AppWindowAnimator {
if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed)
&& animation != null) {
if (!animating) {
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + mAppToken +
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Starting animation in " + mAppToken +
" @ " + currentTime + " scale="
+ mService.getTransitionAnimationScaleLocked()
+ " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
@@ -306,8 +335,8 @@ public class AppWindowAnimator {
mService.moveInputMethodWindowsIfNeededLocked(true);
}
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + mAppToken
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Animation done in " + mAppToken
+ ": reportedVisible=" + mAppToken.reportedVisible);
transformation.clear();
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index ba995f2..01f878c 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -32,6 +32,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
/**
@@ -108,7 +109,7 @@ public class DisplaySettings {
boolean success = false;
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -193,7 +194,7 @@ public class DisplaySettings {
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "display-settings");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 77694b6..4972ce4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -495,7 +495,7 @@ public class WindowManagerService extends IWindowManager.Stub
String mLastANRState;
/** All DisplayContents in the world, kept here */
- SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
+ SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
int mRotation = 0;
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -511,7 +511,7 @@ public class WindowManagerService extends IWindowManager.Stub
deathRecipient = d;
}
}
- ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>();
+ ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
int mDeferredRotationPauseCount;
int mSystemDecorLayer = 0;
@@ -552,11 +552,10 @@ public class WindowManagerService extends IWindowManager.Stub
private final PowerManager.WakeLock mScreenFrozenLock;
final AppTransition mAppTransition;
- boolean mStartingIconInTransition = false;
boolean mSkipAppTransitionAnimation = false;
- final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<AppWindowToken>();
- final ArraySet<AppWindowToken> mClosingApps = new ArraySet<AppWindowToken>();
+ final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
+ final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
boolean mIsTouchDevice;
@@ -581,7 +580,7 @@ public class WindowManagerService extends IWindowManager.Stub
int mInputMethodAnimLayerAdjustment;
WindowState mInputMethodWindow = null;
- final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
+ final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
/** Temporary list for comparison. Always clear this after use so we don't end up with
* orphaned windows references */
@@ -4146,8 +4145,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized(mWindowMap) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(
- TAG, "Prepare app transition: transit=" + transit
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
+ + " transit=" + AppTransition.appTransitionToString(transit)
+ " " + mAppTransition
+ " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
@@ -4166,9 +4165,7 @@ public class WindowManagerService extends IWindowManager.Stub
mAppTransition.setAppTransition(transit);
}
}
- if (okToDisplay()) {
- mAppTransition.prepare();
- mStartingIconInTransition = false;
+ if (okToDisplay() && mAppTransition.prepare()) {
mSkipAppTransitionAnimation = false;
}
if (mAppTransition.isTransitionSet()) {
@@ -4295,19 +4292,16 @@ public class WindowManagerService extends IWindowManager.Stub
if (ttoken != null) {
WindowState startingWindow = ttoken.startingWindow;
if (startingWindow != null) {
- if (mStartingIconInTransition) {
- // In this case, the starting icon has already
- // been displayed, so start letting windows get
- // shown immediately without any more transitions.
- mSkipAppTransitionAnimation = true;
- }
+ // In this case, the starting icon has already been displayed, so start
+ // letting windows get shown immediately without any more transitions.
+ mSkipAppTransitionAnimation = true;
+
if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
"Moving existing starting " + startingWindow + " from " + ttoken
+ " to " + wtoken);
final long origId = Binder.clearCallingIdentity();
- // Transfer the starting window over to the new
- // token.
+ // Transfer the starting window over to the new token.
wtoken.startingData = ttoken.startingData;
wtoken.startingView = ttoken.startingView;
wtoken.startingDisplayed = ttoken.startingDisplayed;
@@ -4321,7 +4315,6 @@ public class WindowManagerService extends IWindowManager.Stub
startingWindow.mToken = wtoken;
startingWindow.mRootToken = wtoken;
startingWindow.mAppToken = wtoken;
- startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
Slog.v(TAG, "Removing starting window: " + startingWindow);
@@ -4355,17 +4348,8 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.clientHidden = ttoken.clientHidden;
wtoken.sendAppVisibilityToClients();
}
- final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
- final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
- if (tAppAnimator.animation != null) {
- wAppAnimator.animation = tAppAnimator.animation;
- wAppAnimator.animating = tAppAnimator.animating;
- wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
- tAppAnimator.animation = null;
- tAppAnimator.animLayerAdjustment = 0;
- wAppAnimator.updateLayers();
- tAppAnimator.updateLayers();
- }
+ ttoken.mAppAnimator.transferCurrentAnimation(
+ wtoken.mAppAnimator, startingWindow.mWinAnimator);
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
true /*updateInputWindows*/);
@@ -4465,7 +4449,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
- mStartingIconInTransition = true;
wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
labelRes, icon, logo, windowFlags);
Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
@@ -4566,8 +4549,8 @@ public class WindowManagerService extends IWindowManager.Stub
changed = true;
}
- final int N = wtoken.allAppWindows.size();
- for (int i=0; i<N; i++) {
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int i = 0; i < windowsCount; i++) {
WindowState win = wtoken.allAppWindows.get(i);
if (win == wtoken.startingWindow) {
continue;
@@ -4696,7 +4679,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
if (okToDisplay() && mAppTransition.isTransitionSet()) {
- if (!wtoken.startingDisplayed) {
+ if (!wtoken.startingDisplayed || mSkipAppTransitionAnimation) {
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Setting dummy animation on: " + wtoken);
wtoken.mAppAnimator.setDummyAnimation();
@@ -9178,14 +9161,14 @@ public class WindowManagerService extends IWindowManager.Stub
public int handleAppTransitionReadyLocked(WindowList windows) {
int changes = 0;
int i;
- int NN = mOpeningApps.size();
+ int appsCount = mOpeningApps.size();
boolean goodToGo = true;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Checking " + NN + " opening apps (frozen="
+ "Checking " + appsCount + " opening apps (frozen="
+ mDisplayFrozen + " timeout="
+ mAppTransition.isTimeout() + ")...");
if (!mAppTransition.isTimeout()) {
- for (i=0; i<NN && goodToGo; i++) {
+ for (i = 0; i < appsCount && goodToGo; i++) {
AppWindowToken wtoken = mOpeningApps.valueAt(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Check opening app=" + wtoken + ": allDrawn="
@@ -9238,7 +9221,6 @@ public class WindowManagerService extends IWindowManager.Stub
if (mSkipAppTransitionAnimation) {
transit = AppTransition.TRANSIT_UNSET;
}
- mStartingIconInTransition = false;
mSkipAppTransitionAnimation = false;
mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
@@ -9287,17 +9269,17 @@ public class WindowManagerService extends IWindowManager.Stub
// (2) Find the layout params of the top-most
// application window in the tokens, which is
// what will control the animation theme.
- final int NC = mClosingApps.size();
- NN = NC + mOpeningApps.size();
- for (i=0; i<NN; i++) {
+ final int closingAppsCount = mClosingApps.size();
+ appsCount = closingAppsCount + mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
final AppWindowToken wtoken;
- if (i < NC) {
+ if (i < closingAppsCount) {
wtoken = mClosingApps.valueAt(i);
if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
closingAppHasWallpaper = true;
}
} else {
- wtoken = mOpeningApps.valueAt(i - NC);
+ wtoken = mOpeningApps.valueAt(i - closingAppsCount);
if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
openingAppHasWallpaper = true;
}
@@ -9338,20 +9320,23 @@ public class WindowManagerService extends IWindowManager.Stub
transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
break;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit: " + AppTransition.appTransitionToString(transit));
} else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
&& !mOpeningApps.contains(oldWallpaper.mAppToken)) {
// We are transitioning from an activity with
// a wallpaper to one without.
transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit away from wallpaper: " + transit);
+ "New transit away from wallpaper: "
+ + AppTransition.appTransitionToString(transit));
} else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
// We are transitioning from an activity without
// a wallpaper to now showing the wallpaper
transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit into wallpaper: " + transit);
+ "New transit into wallpaper: "
+ + AppTransition.appTransitionToString(transit));
} else {
mAnimateWallpaperWithTarget = true;
}
@@ -9395,21 +9380,24 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- NN = mOpeningApps.size();
- for (i=0; i<NN; i++) {
+ appsCount = mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mOpeningApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
+
+ if (!appAnimator.usingTransferredAnimation) {
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ }
wtoken.inPendingTransaction = false;
setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
appAnimator.mAllAppWinAnimators.clear();
- final int N = wtoken.allAppWindows.size();
- for (int j = 0; j < N; j++) {
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int j = 0; j < windowsCount; j++) {
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
@@ -9417,7 +9405,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (animLp != null) {
int layer = -1;
- for (int j=0; j<wtoken.windows.size(); j++) {
+ for (int j = 0; j < wtoken.windows.size(); j++) {
WindowState win = wtoken.windows.get(j);
if (win.mWinAnimator.mAnimLayer > layer) {
layer = win.mWinAnimator.mAnimLayer;
@@ -9429,8 +9417,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
- NN = mClosingApps.size();
- for (i=0; i<NN; i++) {
+ appsCount = mClosingApps.size();
+ for (i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mClosingApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
@@ -9454,7 +9442,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (animLp != null) {
int layer = -1;
- for (int j=0; j<wtoken.windows.size(); j++) {
+ for (int j = 0; j < wtoken.windows.size(); j++) {
WindowState win = wtoken.windows.get(j);
if (win.mWinAnimator.mAnimLayer > layer) {
layer = win.mWinAnimator.mAnimLayer;
@@ -11407,8 +11395,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
- pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
- pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+ pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
mAppTransition.dump(pw, " ");
}