Merge "Fix an unintentional switch-case fall-through"
diff --git a/Android.mk b/Android.mk
index b98d3bc..e372fda 100644
--- a/Android.mk
+++ b/Android.mk
@@ -213,7 +213,6 @@
core/java/android/hardware/usb/IUsbManager.aidl \
core/java/android/net/ICaptivePortal.aidl \
core/java/android/net/IConnectivityManager.aidl \
- core/java/android/net/IConnectivityMetricsLogger.aidl \
core/java/android/net/IIpConnectivityMetrics.aidl \
core/java/android/net/IEthernetManager.aidl \
core/java/android/net/IEthernetServiceListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 61ddd76..27fd669 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4737,6 +4737,7 @@
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
+ method public abstract boolean isStateSaved();
method public abstract void popBackStack();
method public abstract void popBackStack(java.lang.String, int);
method public abstract void popBackStack(int, int);
@@ -6547,6 +6548,7 @@
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -40154,7 +40156,7 @@
package android.test.suitebuilder {
- public class TestMethod {
+ public deprecated class TestMethod {
ctor public TestMethod(java.lang.reflect.Method, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(java.lang.String, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(junit.framework.TestCase);
@@ -40165,7 +40167,7 @@
method public java.lang.String getName();
}
- public class TestSuiteBuilder {
+ public deprecated class TestSuiteBuilder {
ctor public TestSuiteBuilder(java.lang.Class);
ctor public TestSuiteBuilder(java.lang.String, java.lang.ClassLoader);
method public android.test.suitebuilder.TestSuiteBuilder addRequirements(java.util.List<com.android.internal.util.Predicate<android.test.suitebuilder.TestMethod>>);
@@ -40178,7 +40180,7 @@
method public android.test.suitebuilder.TestSuiteBuilder named(java.lang.String);
}
- public static class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
+ public static deprecated class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
ctor public TestSuiteBuilder.FailedToCreateTests(java.lang.Exception);
method public void testSuiteConstructionFailed();
}
@@ -43141,11 +43143,13 @@
field public static final int DRAW_DURATION = 4; // 0x4
field public static final int FIRST_DRAW_FRAME = 9; // 0x9
field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+ field public static final int INTENDED_VSYNC_TIMESTAMP = 10; // 0xa
field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
field public static final int SYNC_DURATION = 5; // 0x5
field public static final int TOTAL_DURATION = 8; // 0x8
field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+ field public static final int VSYNC_TIMESTAMP = 11; // 0xb
}
public abstract class FrameStats {
@@ -45644,6 +45648,7 @@
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
@@ -50932,7 +50937,7 @@
package com.android.internal.util {
- public abstract interface Predicate<T> {
+ public abstract deprecated interface Predicate<T> {
method public abstract boolean apply(T);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index e170345..a06c913 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4898,6 +4898,7 @@
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
+ method public abstract boolean isStateSaved();
method public abstract void popBackStack();
method public abstract void popBackStack(java.lang.String, int);
method public abstract void popBackStack(int, int);
@@ -6787,6 +6788,7 @@
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -26830,44 +26832,6 @@
method public void onTetheringStarted();
}
- public final class ConnectivityMetricsEvent implements android.os.Parcelable {
- ctor public ConnectivityMetricsEvent(long, int, int, android.os.Parcelable);
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent> CREATOR;
- field public final int componentTag;
- field public final android.os.Parcelable data;
- field public final int eventTag;
- field public final long timestamp;
- }
-
- public static final class ConnectivityMetricsEvent.Reference implements android.os.Parcelable {
- ctor public ConnectivityMetricsEvent.Reference(long);
- method public int describeContents();
- method public long getValue();
- method public void readFromParcel(android.os.Parcel);
- method public void setValue(long);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent.Reference> CREATOR;
- }
-
- public class ConnectivityMetricsLogger {
- ctor public ConnectivityMetricsLogger();
- method public android.net.ConnectivityMetricsEvent[] getEvents(android.net.ConnectivityMetricsEvent.Reference);
- method public void logEvent(long, int, int, android.os.Parcelable);
- method public boolean register(android.app.PendingIntent);
- method public boolean unregister(android.app.PendingIntent);
- field public static final int COMPONENT_TAG_BLUETOOTH = 1; // 0x1
- field public static final int COMPONENT_TAG_CONNECTIVITY = 0; // 0x0
- field public static final int COMPONENT_TAG_TELECOM = 3; // 0x3
- field public static final int COMPONENT_TAG_TELEPHONY = 4; // 0x4
- field public static final int COMPONENT_TAG_WIFI = 2; // 0x2
- field public static final java.lang.String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger";
- field public static final java.lang.String DATA_KEY_EVENTS_COUNT = "count";
- field public static final int NUMBER_OF_COMPONENTS = 5; // 0x5
- field public static final int TAG_SKIPPED_EVENTS = -1; // 0xffffffff
- }
-
public class Credentials {
ctor public Credentials(int, int, int);
method public int getGid();
@@ -27579,175 +27543,6 @@
}
-package android.net.metrics {
-
- public final class ApfProgramEvent implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.ApfProgramEvent> CREATOR;
- field public static final int FLAG_HAS_IPV4_ADDRESS = 1; // 0x1
- field public static final int FLAG_MULTICAST_FILTER_ON = 0; // 0x0
- field public final int currentRas;
- field public final int filteredRas;
- field public final int flags;
- field public final long lifetime;
- field public final int programLength;
- }
-
- public final class ApfStats implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.ApfStats> CREATOR;
- field public final int droppedRas;
- field public final long durationMs;
- field public final int matchingRas;
- field public final int maxProgramSize;
- field public final int parseErrors;
- field public final int programUpdates;
- field public final int receivedRas;
- field public final int zeroLifetimeRas;
- }
-
- public final class DefaultNetworkEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logEvent(int, int[], int, boolean, boolean);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.DefaultNetworkEvent> CREATOR;
- field public final int netId;
- field public final boolean prevIPv4;
- field public final boolean prevIPv6;
- field public final int prevNetId;
- field public final int[] transportTypes;
- }
-
- public final class DhcpClientEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logStateEvent(java.lang.String, java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.DhcpClientEvent> CREATOR;
- field public final int durationMs;
- field public final java.lang.String ifName;
- field public final java.lang.String msg;
- }
-
- public final class DhcpErrorEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static int errorCodeWithOption(int, int);
- method public static void logParseError(java.lang.String, int);
- method public static void logReceiveError(java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BOOTP_TOO_SHORT;
- field public static final int BUFFER_UNDERFLOW;
- field public static final android.os.Parcelable.Creator<android.net.metrics.DhcpErrorEvent> CREATOR;
- field public static final int DHCP_BAD_MAGIC_COOKIE;
- field public static final int DHCP_ERROR = 4; // 0x4
- field public static final int DHCP_INVALID_OPTION_LENGTH;
- field public static final int DHCP_NO_MSG_TYPE;
- field public static final int DHCP_UNKNOWN_MSG_TYPE;
- field public static final int L2_ERROR = 1; // 0x1
- field public static final int L2_TOO_SHORT;
- field public static final int L2_WRONG_ETH_TYPE;
- field public static final int L3_ERROR = 2; // 0x2
- field public static final int L3_INVALID_IP;
- field public static final int L3_NOT_IPV4;
- field public static final int L3_TOO_SHORT;
- field public static final int L4_ERROR = 3; // 0x3
- field public static final int L4_NOT_UDP;
- field public static final int L4_WRONG_PORT;
- field public static final int MISC_ERROR = 5; // 0x5
- field public static final int RECEIVE_ERROR;
- field public final int errorCode;
- field public final java.lang.String ifName;
- }
-
- public final class DnsEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logEvent(int, byte[], byte[], int[]);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.DnsEvent> CREATOR;
- field public final byte[] eventTypes;
- field public final int[] latenciesMs;
- field public final int netId;
- field public final byte[] returnCodes;
- }
-
- public final class IpManagerEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logEvent(int, java.lang.String, long);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int COMPLETE_LIFECYCLE = 3; // 0x3
- field public static final android.os.Parcelable.Creator<android.net.metrics.IpManagerEvent> CREATOR;
- field public static final int PROVISIONING_FAIL = 2; // 0x2
- field public static final int PROVISIONING_OK = 1; // 0x1
- field public final long durationMs;
- field public final int eventType;
- field public final java.lang.String ifName;
- }
-
- public final class IpReachabilityEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logNudFailed(java.lang.String);
- method public static void logProbeEvent(java.lang.String, int);
- method public static void logProvisioningLost(java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityEvent> CREATOR;
- field public static final int NUD_FAILED = 512; // 0x200
- field public static final int PROBE = 256; // 0x100
- field public static final int PROVISIONING_LOST = 768; // 0x300
- field public final int eventType;
- field public final java.lang.String ifName;
- }
-
- public final class NetworkEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logCaptivePortalFound(int, long);
- method public static void logEvent(int, int);
- method public static void logValidated(int, long);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.NetworkEvent> CREATOR;
- field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
- field public static final int NETWORK_CONNECTED = 1; // 0x1
- field public static final int NETWORK_DISCONNECTED = 7; // 0x7
- field public static final int NETWORK_LINGER = 5; // 0x5
- field public static final int NETWORK_UNLINGER = 6; // 0x6
- field public static final int NETWORK_VALIDATED = 2; // 0x2
- field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
- field public final long durationMs;
- field public final int eventType;
- field public final int netId;
- }
-
- public final class RaEvent implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.RaEvent> CREATOR;
- field public final long dnsslLifetime;
- field public final long prefixPreferredLifetime;
- field public final long prefixValidLifetime;
- field public final long rdnssLifetime;
- field public final long routeInfoLifetime;
- field public final long routerLifetime;
- }
-
- public final class ValidationProbeEvent implements android.os.Parcelable {
- method public int describeContents();
- method public static void logEvent(int, long, int, int);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.metrics.ValidationProbeEvent> CREATOR;
- field public static final int DNS_FAILURE = 0; // 0x0
- field public static final int DNS_SUCCESS = 1; // 0x1
- field public static final int PROBE_DNS = 0; // 0x0
- field public static final int PROBE_HTTP = 1; // 0x1
- field public static final int PROBE_HTTPS = 2; // 0x2
- field public static final int PROBE_PAC = 3; // 0x3
- field public final long durationMs;
- field public final int netId;
- field public final int probeType;
- field public final int returnCode;
- }
-
-}
-
package android.net.nsd {
public final class NsdManager {
@@ -43698,7 +43493,7 @@
package android.test.suitebuilder {
- public class TestMethod {
+ public deprecated class TestMethod {
ctor public TestMethod(java.lang.reflect.Method, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(java.lang.String, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(junit.framework.TestCase);
@@ -43709,7 +43504,7 @@
method public java.lang.String getName();
}
- public class TestSuiteBuilder {
+ public deprecated class TestSuiteBuilder {
ctor public TestSuiteBuilder(java.lang.Class);
ctor public TestSuiteBuilder(java.lang.String, java.lang.ClassLoader);
method public android.test.suitebuilder.TestSuiteBuilder addRequirements(java.util.List<com.android.internal.util.Predicate<android.test.suitebuilder.TestMethod>>);
@@ -43722,7 +43517,7 @@
method public android.test.suitebuilder.TestSuiteBuilder named(java.lang.String);
}
- public static class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
+ public static deprecated class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
ctor public TestSuiteBuilder.FailedToCreateTests(java.lang.Exception);
method public void testSuiteConstructionFailed();
}
@@ -46686,11 +46481,13 @@
field public static final int DRAW_DURATION = 4; // 0x4
field public static final int FIRST_DRAW_FRAME = 9; // 0x9
field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+ field public static final int INTENDED_VSYNC_TIMESTAMP = 10; // 0xa
field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
field public static final int SYNC_DURATION = 5; // 0x5
field public static final int TOTAL_DURATION = 8; // 0x8
field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+ field public static final int VSYNC_TIMESTAMP = 11; // 0xb
}
public abstract class FrameStats {
@@ -49189,6 +48986,7 @@
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
@@ -54841,7 +54639,7 @@
package com.android.internal.util {
- public abstract interface Predicate<T> {
+ public abstract deprecated interface Predicate<T> {
method public abstract boolean apply(T);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index af51baa..a590e45 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4747,6 +4747,7 @@
method public abstract android.app.Fragment getPrimaryNavigationFragment();
method public void invalidateOptionsMenu();
method public abstract boolean isDestroyed();
+ method public abstract boolean isStateSaved();
method public abstract void popBackStack();
method public abstract void popBackStack(java.lang.String, int);
method public abstract void popBackStack(int, int);
@@ -6573,6 +6574,7 @@
public static class AssistStructure.ViewNode {
method public float getAlpha();
method public android.view.autofill.AutoFillId getAutoFillId();
+ method public java.lang.String[] getAutoFillOptions();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
@@ -40342,7 +40344,7 @@
package android.test.suitebuilder {
- public class TestMethod {
+ public deprecated class TestMethod {
ctor public TestMethod(java.lang.reflect.Method, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(java.lang.String, java.lang.Class<? extends junit.framework.TestCase>);
ctor public TestMethod(junit.framework.TestCase);
@@ -40353,7 +40355,7 @@
method public java.lang.String getName();
}
- public class TestSuiteBuilder {
+ public deprecated class TestSuiteBuilder {
ctor public TestSuiteBuilder(java.lang.Class);
ctor public TestSuiteBuilder(java.lang.String, java.lang.ClassLoader);
method public android.test.suitebuilder.TestSuiteBuilder addRequirements(java.util.List<com.android.internal.util.Predicate<android.test.suitebuilder.TestMethod>>);
@@ -40366,7 +40368,7 @@
method public android.test.suitebuilder.TestSuiteBuilder named(java.lang.String);
}
- public static class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
+ public static deprecated class TestSuiteBuilder.FailedToCreateTests extends junit.framework.TestCase {
ctor public TestSuiteBuilder.FailedToCreateTests(java.lang.Exception);
method public void testSuiteConstructionFailed();
}
@@ -43494,11 +43496,13 @@
field public static final int DRAW_DURATION = 4; // 0x4
field public static final int FIRST_DRAW_FRAME = 9; // 0x9
field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+ field public static final int INTENDED_VSYNC_TIMESTAMP = 10; // 0xa
field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
field public static final int SYNC_DURATION = 5; // 0x5
field public static final int TOTAL_DURATION = 8; // 0x8
field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+ field public static final int VSYNC_TIMESTAMP = 11; // 0xb
}
public abstract class FrameStats {
@@ -46006,6 +46010,7 @@
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
+ method public abstract void setAutoFillOptions(java.lang.String[]);
method public abstract void setAutoFillType(android.view.autofill.AutoFillType);
method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
method public abstract void setCheckable(boolean);
@@ -51311,7 +51316,7 @@
package com.android.internal.util {
- public abstract interface Predicate<T> {
+ public abstract deprecated interface Predicate<T> {
method public abstract boolean apply(T);
}
diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk
index eb6da18e..50ccb07 100644
--- a/cmds/idmap/Android.mk
+++ b/cmds/idmap/Android.mk
@@ -15,7 +15,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := idmap.cpp create.cpp inspect.cpp
+LOCAL_SRC_FILES := idmap.cpp create.cpp scan.cpp inspect.cpp
LOCAL_SHARED_LIBRARIES := liblog libutils libandroidfw
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index d388977..3ab1915 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -13,6 +13,8 @@
idmap --help \n\
idmap --fd target overlay fd \n\
idmap --path target overlay idmap \n\
+ idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\
+ dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\
idmap --inspect idmap \n\
\n\
DESCRIPTION \n\
@@ -47,6 +49,11 @@
--path: create idmap for target package 'target' (path to apk) and overlay package \n\
'overlay' (path to apk); write results to 'idmap' (path). \n\
\n\
+ --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\
+ target package 'target-package-name-to-look-for' (package name) present at\n\
+ 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\
+ idmap file in 'dir-to-hold-idmaps' (path). \n\
+\n\
--inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
debug-friendly format. \n\
\n\
@@ -90,6 +97,16 @@
NOTES \n\
This tool and its expected invocation from installd is modelled on dexopt.";
+ bool verify_directory_readable(const char *path)
+ {
+ return access(path, R_OK | X_OK) == 0;
+ }
+
+ bool verify_directory_writable(const char *path)
+ {
+ return access(path, W_OK) == 0;
+ }
+
bool verify_file_readable(const char *path)
{
return access(path, R_OK) == 0;
@@ -150,6 +167,36 @@
return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
}
+ int maybe_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
+ {
+ if (!verify_root_or_system()) {
+ fprintf(stderr, "error: permission denied: not user root or user system\n");
+ return -1;
+ }
+
+ if (!verify_file_readable(target_apk_path)) {
+ ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+ return -1;
+ }
+
+ if (!verify_directory_writable(idmap_dir)) {
+ ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno));
+ return -1;
+ }
+
+ const size_t N = overlay_dirs->size();
+ for (size_t i = 0; i < N; i++) {
+ const char *dir = overlay_dirs->itemAt(i);
+ if (!verify_directory_readable(dir)) {
+ ALOGD("error: no read access to %s: %s\n", dir, strerror(errno));
+ return -1;
+ }
+ }
+
+ return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs);
+ }
+
int maybe_inspect(const char *idmap_path)
{
// anyone (not just root or system) may do --inspect
@@ -188,6 +235,14 @@
return maybe_create_path(argv[2], argv[3], argv[4]);
}
+ if (argc >= 6 && !strcmp(argv[1], "--scan")) {
+ android::Vector<const char *> v;
+ for (int i = 5; i < argc; i++) {
+ v.push(argv[i]);
+ }
+ return maybe_scan(argv[2], argv[3], argv[4], &v);
+ }
+
if (argc == 3 && !strcmp(argv[1], "--inspect")) {
return maybe_inspect(argv[2]);
}
diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h
index 5914de9..8d4210b 100644
--- a/cmds/idmap/idmap.h
+++ b/cmds/idmap/idmap.h
@@ -25,6 +25,12 @@
int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd);
+// Regarding target_package_name: the idmap_scan implementation should
+// be able to extract this from the manifest in target_apk_path,
+// simplifying the external API.
+int idmap_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs);
+
int idmap_inspect(const char *idmap_path);
#endif // _IDMAP_H_
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
new file mode 100644
index 0000000..ab6adfb
--- /dev/null
+++ b/cmds/idmap/scan.cpp
@@ -0,0 +1,239 @@
+#include <dirent.h>
+#include <inttypes.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include "idmap.h"
+
+#include <memory>
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/StreamingZipInflater.h>
+#include <androidfw/ZipFileRO.h>
+#include <private/android_filesystem_config.h> // for AID_SYSTEM
+#include <utils/SortedVector.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#define NO_OVERLAY_TAG (-1000)
+
+using namespace android;
+
+namespace {
+ struct Overlay {
+ Overlay() {}
+ Overlay(const String8& a, const String8& i, int p) :
+ apk_path(a), idmap_path(i), priority(p) {}
+
+ bool operator<(Overlay const& rhs) const
+ {
+ return rhs.priority > priority;
+ }
+
+ String8 apk_path;
+ String8 idmap_path;
+ int priority;
+ };
+
+ bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
+ {
+ // the file is opened for appending so that it doesn't get truncated
+ // before we can guarantee mutual exclusion via the flock
+ FILE* fout = fopen(filename, "a");
+ if (fout == NULL) {
+ return false;
+ }
+
+ if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
+ fclose(fout);
+ return false;
+ }
+
+ if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
+ TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
+ fclose(fout);
+ return false;
+ }
+
+ for (size_t i = 0; i < overlayVector.size(); ++i) {
+ const Overlay& overlay = overlayVector[i];
+ fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
+ }
+
+ TEMP_FAILURE_RETRY(fflush(fout));
+ TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
+ fclose(fout);
+
+ // Make file world readable since Zygote (running as root) will read
+ // it when creating the initial AssetManger object
+ const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
+ if (chmod(filename, mode) == -1) {
+ unlink(filename);
+ return false;
+ }
+
+ return true;
+ }
+
+ String8 flatten_path(const char *path)
+ {
+ String16 tmp(path);
+ tmp.replaceAll('/', '@');
+ return String8(tmp);
+ }
+
+ int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
+ {
+ const size_t N = parser.getAttributeCount();
+ String16 target;
+ int priority = -1;
+ for (size_t i = 0; i < N; ++i) {
+ size_t len;
+ String16 key(parser.getAttributeName(i, &len));
+ if (key == String16("targetPackage")) {
+ const char16_t *p = parser.getAttributeStringValue(i, &len);
+ if (p != NULL) {
+ target = String16(p, len);
+ }
+ } else if (key == String16("priority")) {
+ Res_value v;
+ if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
+ priority = v.data;
+ if (priority < 0 || priority > 9999) {
+ return -1;
+ }
+ }
+ }
+ }
+ if (target == String16(target_package_name)) {
+ return priority;
+ }
+ return NO_OVERLAY_TAG;
+ }
+
+ int parse_manifest(const void *data, size_t size, const char *target_package_name)
+ {
+ ResXMLTree parser;
+ parser.setTo(data, size);
+ if (parser.getError() != NO_ERROR) {
+ ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
+ return -1;
+ }
+
+ ResXMLParser::event_code_t type;
+ do {
+ type = parser.next();
+ if (type == ResXMLParser::START_TAG) {
+ size_t len;
+ String16 tag(parser.getElementName(&len));
+ if (tag == String16("overlay")) {
+ return parse_overlay_tag(parser, target_package_name);
+ }
+ }
+ } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);
+
+ return NO_OVERLAY_TAG;
+ }
+
+ int parse_apk(const char *path, const char *target_package_name)
+ {
+ std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path));
+ if (zip.get() == NULL) {
+ ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
+ return -1;
+ }
+ ZipEntryRO entry;
+ if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) {
+ ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
+ return -1;
+ }
+ uint32_t uncompLen = 0;
+ uint16_t method;
+ if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
+ ALOGW("%s: failed to read entry info\n", __FUNCTION__);
+ return -1;
+ }
+ if (method != ZipFileRO::kCompressDeflated) {
+ ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method);
+ return -1;
+ }
+ FileMap *dataMap = zip->createEntryFileMap(entry);
+ if (dataMap == NULL) {
+ ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
+ return -1;
+ }
+ char *buf = new char[uncompLen];
+ if (NULL == buf) {
+ ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
+ delete dataMap;
+ return -1;
+ }
+ StreamingZipInflater inflater(dataMap, uncompLen);
+ if (inflater.read(buf, uncompLen) < 0) {
+ ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
+ delete[] buf;
+ delete dataMap;
+ return -1;
+ }
+
+ int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name);
+ delete[] buf;
+ delete dataMap;
+ return priority;
+ }
+}
+
+int idmap_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
+{
+ String8 filename = String8(idmap_dir);
+ filename.appendPath("overlays.list");
+
+ SortedVector<Overlay> overlayVector;
+ const size_t N = overlay_dirs->size();
+ for (size_t i = 0; i < N; ++i) {
+ const char *overlay_dir = overlay_dirs->itemAt(i);
+ DIR *dir = opendir(overlay_dir);
+ if (dir == NULL) {
+ return EXIT_FAILURE;
+ }
+
+ struct dirent *dirent;
+ while ((dirent = readdir(dir)) != NULL) {
+ struct stat st;
+ char overlay_apk_path[PATH_MAX + 1];
+ snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
+ if (stat(overlay_apk_path, &st) < 0) {
+ continue;
+ }
+ if (!S_ISREG(st.st_mode)) {
+ continue;
+ }
+
+ int priority = parse_apk(overlay_apk_path, target_package_name);
+ if (priority < 0) {
+ continue;
+ }
+
+ String8 idmap_path(idmap_dir);
+ idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
+ idmap_path.append("@idmap");
+
+ if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
+ ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
+ target_apk_path, overlay_apk_path, idmap_path.string());
+ continue;
+ }
+
+ Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
+ overlayVector.add(overlay);
+ }
+
+ closedir(dir);
+ }
+
+ if (!writePackagesList(filename.string(), overlayVector)) {
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a820da4..0193c5f 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2822,7 +2822,9 @@
return;
}
- if (!mFragments.getFragmentManager().popBackStackImmediate()) {
+ FragmentManager fragmentManager = mFragments.getFragmentManager();
+
+ if (fragmentManager.isStateSaved() || !fragmentManager.popBackStackImmediate()) {
finishAfterTransition();
}
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7ff11ec..ce9d91f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2773,7 +2773,7 @@
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display =
- dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
+ dm.getCompatibleDisplay(id, appContext.getResources());
appContext = (ContextImpl) appContext.createDisplayContext(display);
break;
}
@@ -4970,7 +4970,7 @@
LoadedApk apk = ref != null ? ref.get() : null;
if (apk != null) {
final ArrayList<String> oldPaths = new ArrayList<>();
- LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths, null /*outLibPaths*/);
+ LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
apk.updateApplicationInfo(ai, oldPaths);
}
@@ -4978,7 +4978,7 @@
apk = ref != null ? ref.get() : null;
if (apk != null) {
final ArrayList<String> oldPaths = new ArrayList<>();
- LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths, null /*outLibPaths*/);
+ LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
apk.updateApplicationInfo(ai, oldPaths);
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 045bd0a..3e9b987 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2067,24 +2067,17 @@
@Override
public Display getDisplay() {
- final DisplayAdjustments displayAdjustments = mResources.getDisplayAdjustments();
if (mDisplay == null) {
return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
- displayAdjustments);
+ mResources);
}
- if (!mDisplay.getDisplayAdjustments().equals(displayAdjustments)) {
- mDisplay = mResourcesManager.getAdjustedDisplay(mDisplay.getDisplayId(),
- displayAdjustments);
- }
return mDisplay;
}
@Override
public void updateDisplay(int displayId) {
- final DisplayAdjustments displayAdjustments = mResources.getDisplayAdjustments();
- mDisplay = mResourcesManager.getAdjustedDisplay(displayId,
- displayAdjustments);
+ mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources);
}
@Override
@@ -2202,7 +2195,7 @@
compatInfo,
classLoader);
context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
- context.mResources.getDisplayAdjustments());
+ context.getResources());
return context;
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 8ad7810..977931a 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -397,6 +397,19 @@
public void invalidateOptionsMenu() { }
/**
+ * Returns {@code true} if the FragmentManager's state has already been saved
+ * by its host. Any operations that would change saved state should not be performed
+ * if this method returns true. For example, any popBackStack() method, such as
+ * {@link #popBackStackImmediate()} or any FragmentTransaction using
+ * {@link FragmentTransaction#commit()} instead of
+ * {@link FragmentTransaction#commitAllowingStateLoss()} will change
+ * the state and will result in an error.
+ *
+ * @return true if this FragmentManager's state has already been saved by its host
+ */
+ public abstract boolean isStateSaved();
+
+ /**
* Callback interface for listening to fragment state changes that happen
* within a given FragmentManager.
*/
@@ -1787,6 +1800,7 @@
}
}
+ @Override
public boolean isStateSaved() {
return mStateSaved;
}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 7ed96af..1c33e38 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -278,7 +278,7 @@
setApplicationInfo(aInfo);
final List<String> newPaths = new ArrayList<>();
- makePaths(mActivityThread, aInfo, newPaths, null /*libPaths*/);
+ makePaths(mActivityThread, aInfo, newPaths);
final List<String> addedPaths = new ArrayList<>(newPaths.size());
if (oldPaths != null) {
@@ -341,8 +341,17 @@
}
}
- public static void makePaths(ActivityThread activityThread, ApplicationInfo aInfo,
- List<String> outZipPaths, List<String> outLibPaths) {
+ public static void makePaths(ActivityThread activityThread,
+ ApplicationInfo aInfo,
+ List<String> outZipPaths) {
+ makePaths(activityThread, false, aInfo, outZipPaths, null);
+ }
+
+ public static void makePaths(ActivityThread activityThread,
+ boolean isBundledApp,
+ ApplicationInfo aInfo,
+ List<String> outZipPaths,
+ List<String> outLibPaths) {
final String appDir = aInfo.sourceDir;
final String libDir = aInfo.nativeLibraryDir;
final String[] sharedLibraries = aInfo.sharedLibraryFiles;
@@ -431,7 +440,7 @@
}
}
- if (aInfo.isSystemApp() && !aInfo.isUpdatedSystemApp()) {
+ if (isBundledApp) {
// Add path to system libraries to libPaths;
// Access to system libs should be limited
// to bundled applications; this is why updated
@@ -614,11 +623,12 @@
// space and initialize to a small value (instead of incurring growth code).
final List<String> zipPaths = new ArrayList<>(10);
final List<String> libPaths = new ArrayList<>(10);
- makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths);
final boolean isBundledApp = mApplicationInfo.isSystemApp()
&& !mApplicationInfo.isUpdatedSystemApp();
+ makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
+
String libraryPermittedPath = mDataDir;
if (isBundledApp) {
// This is necessary to grant bundled apps access to
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 55f7df3..52ec045 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -104,10 +104,17 @@
new WeakHashMap<>();
/**
- * A cache of DisplayId to DisplayAdjustments.
+ * A cache of DisplayId, DisplayAdjustments to Display.
*/
- private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>> mDisplays =
- new ArrayMap<>();
+ private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>>
+ mAdjustedDisplays = new ArrayMap<>();
+
+ /**
+ * A cache of DisplayId, Resources to Display. These display adjustments associated with these
+ * {@link Display}s will change as the resources change.
+ */
+ private final ArrayMap<Pair<Integer, Resources>, WeakReference<Display>> mResourceDisplays =
+ new ArrayMap<>();
public static ResourcesManager getInstance() {
synchronized (ResourcesManager.class) {
@@ -201,19 +208,21 @@
/**
* Returns an adjusted {@link Display} object based on the inputs or null if display isn't
- * available.
+ * available. This method is only used within {@link ResourcesManager} to calculate display
+ * metrics based on a set {@link DisplayAdjustments}. All other usages should instead call
+ * {@link ResourcesManager#getAdjustedDisplay(int, Resources)}.
*
* @param displayId display Id.
* @param displayAdjustments display adjustments.
*/
- public Display getAdjustedDisplay(final int displayId,
+ private Display getAdjustedDisplay(final int displayId,
@Nullable DisplayAdjustments displayAdjustments) {
final DisplayAdjustments displayAdjustmentsCopy = (displayAdjustments != null)
? new DisplayAdjustments(displayAdjustments) : new DisplayAdjustments();
final Pair<Integer, DisplayAdjustments> key =
Pair.create(displayId, displayAdjustmentsCopy);
synchronized (this) {
- WeakReference<Display> wd = mDisplays.get(key);
+ WeakReference<Display> wd = mAdjustedDisplays.get(key);
if (wd != null) {
final Display display = wd.get();
if (display != null) {
@@ -227,7 +236,37 @@
}
final Display display = dm.getCompatibleDisplay(displayId, key.second);
if (display != null) {
- mDisplays.put(key, new WeakReference<>(display));
+ mAdjustedDisplays.put(key, new WeakReference<>(display));
+ }
+ return display;
+ }
+ }
+
+ /**
+ * Returns an adjusted {@link Display} object based on the inputs or null if display isn't
+ * available.
+ *
+ * @param displayId display Id.
+ * @param resources The {@link Resources} backing the display adjustments.
+ */
+ public Display getAdjustedDisplay(final int displayId, Resources resources) {
+ final Pair<Integer, Resources> key = Pair.create(displayId, resources);
+ synchronized (this) {
+ WeakReference<Display> wd = mResourceDisplays.get(key);
+ if (wd != null) {
+ final Display display = wd.get();
+ if (display != null) {
+ return display;
+ }
+ }
+ final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
+ if (dm == null) {
+ // may be null early in system startup
+ return null;
+ }
+ final Display display = dm.getCompatibleDisplay(displayId, resources);
+ if (display != null) {
+ mResourceDisplays.put(key, new WeakReference<>(display));
}
return display;
}
@@ -316,6 +355,7 @@
final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj);
final Configuration config = generateConfig(key, dm);
final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj);
+
if (DEBUG) {
Slog.d(TAG, "- creating impl=" + impl + " with key: " + key);
}
@@ -811,7 +851,9 @@
}
int changes = mResConfiguration.updateFrom(config);
// Things might have changed in display manager, so clear the cached displays.
- mDisplays.clear();
+ mAdjustedDisplays.clear();
+ mResourceDisplays.clear();
+
DisplayMetrics defaultDisplayMetrics = getDisplayMetrics();
if (compat != null && (mResCompatibilityInfo == null ||
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 678c017..483a7a1 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -538,6 +538,7 @@
AutoFillId mAutoFillId;
AutoFillType mAutoFillType;
AutoFillValue mAutoFillValue;
+ String[] mAutoFillOptions;
boolean mSanitized;
int mX;
int mY;
@@ -618,6 +619,7 @@
mAutoFillId = in.readParcelable(null);
mAutoFillType = in.readParcelable(null);
mAutoFillValue = in.readParcelable(null);
+ mAutoFillOptions = in.readStringArray();
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
mX = in.readInt();
@@ -720,7 +722,14 @@
}
pwriter.writeString(mClassName);
- out.writeInt(flags);
+
+ int writtenFlags = flags;
+ if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0 && (mSanitized || !sanitizeOnWrite)) {
+ // Remove 'checked' from sanitized auto-fill request.
+ writtenFlags = flags & ~FLAGS_CHECKED;
+ }
+
+ out.writeInt(writtenFlags);
if ((flags&FLAGS_HAS_ID) != 0) {
out.writeInt(mId);
if (mId != 0) {
@@ -738,6 +747,7 @@
out.writeParcelable(mAutoFillType, 0);
final AutoFillValue sanitizedValue = writeSensitive ? mAutoFillValue : null;
out.writeParcelable(sanitizedValue, 0);
+ out.writeStringArray(mAutoFillOptions);
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
out.writeInt(mX);
@@ -844,6 +854,19 @@
return mAutoFillValue;
}
+ /**
+ * Gets the options that can be used to auto-fill this structure.
+ *
+ * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning
+ * of each possible value in the list.
+ *
+ * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+ * for assist.
+ */
+ public String[] getAutoFillOptions() {
+ return mAutoFillOptions;
+ }
+
/** @hide */
public boolean isSanitized() {
return mSanitized;
@@ -1506,6 +1529,11 @@
mNode.mAutoFillValue = value;
}
+ @Override
+ public void setAutoFillOptions(String[] options) {
+ mNode.mAutoFillOptions = options;
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f801e45..56f1e0c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2065,6 +2065,9 @@
com.android.internal.R.styleable.AndroidManifestResourceOverlay);
pkg.mOverlayTarget = sa.getString(
com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
+ pkg.mOverlayPriority = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
+ -1);
sa.recycle();
if (pkg.mOverlayTarget == null) {
@@ -2072,6 +2075,12 @@
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
}
+ if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) {
+ outError[0] = "<overlay> priority must be between 0 and 9999";
+ mParseError =
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals(TAG_KEY_SETS)) {
@@ -5509,6 +5518,7 @@
public String mRequiredAccountType;
public String mOverlayTarget;
+ public int mOverlayPriority;
public boolean mTrustedOverlay;
/**
@@ -5985,6 +5995,7 @@
mRestrictedAccountType = dest.readString();
mRequiredAccountType = dest.readString();
mOverlayTarget = dest.readString();
+ mOverlayPriority = dest.readInt();
mTrustedOverlay = (dest.readInt() == 1);
mSigningKeys = (ArraySet<PublicKey>) dest.readArraySet(boot);
mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot);
@@ -6100,6 +6111,7 @@
dest.writeString(mRestrictedAccountType);
dest.writeString(mRequiredAccountType);
dest.writeString(mOverlayTarget);
+ dest.writeInt(mOverlayPriority);
dest.writeInt(mTrustedOverlay ? 1 : 0);
dest.writeArraySet(mSigningKeys);
dest.writeArraySet(mUpgradeKeySets);
@@ -6548,7 +6560,6 @@
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
- ai.resourceDirs = state.resourceDirs;
}
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index ee56a18..24f1164 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -31,8 +31,6 @@
import com.android.internal.util.ArrayUtils;
-import java.util.Arrays;
-
/**
* Per-user state information about a package.
* @hide
@@ -56,8 +54,6 @@
public ArraySet<String> disabledComponents;
public ArraySet<String> enabledComponents;
- public String[] resourceDirs;
-
public PackageUserState() {
installed = true;
hidden = false;
@@ -85,8 +81,6 @@
installReason = o.installReason;
disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
- resourceDirs =
- o.resourceDirs == null ? null : Arrays.copyOf(o.resourceDirs, o.resourceDirs.length);
}
/**
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 33a9f5e..a529c2f 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -339,8 +339,7 @@
private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
Display display = mDisplays.get(displayId);
if (display == null) {
- display = mGlobal.getCompatibleDisplay(displayId,
- mContext.getDisplayAdjustments(displayId));
+ display = mGlobal.getCompatibleDisplay(displayId, mContext.getResources());
if (display != null) {
mDisplays.put(displayId, display);
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 826eb74..341754c 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.projection.MediaProjection;
import android.media.projection.IMediaProjection;
@@ -181,6 +182,24 @@
}
/**
+ * Gets information about a logical display.
+ *
+ * The display metrics may be adjusted to provide compatibility
+ * for legacy applications or limited screen areas.
+ *
+ * @param displayId The logical display id.
+ * @param resources Resources providing compatibility info.
+ * @return The display object, or null if there is no display with the given id.
+ */
+ public Display getCompatibleDisplay(int displayId, Resources resources) {
+ DisplayInfo displayInfo = getDisplayInfo(displayId);
+ if (displayInfo == null) {
+ return null;
+ }
+ return new Display(this, displayId, displayInfo, resources);
+ }
+
+ /**
* Gets information about a logical display without applying any compatibility metrics.
*
* @param displayId The logical display id.
diff --git a/core/java/android/net/ConnectivityMetricsEvent.aidl b/core/java/android/net/ConnectivityMetricsEvent.aidl
index a027d7c..1c541dc 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.aidl
+++ b/core/java/android/net/ConnectivityMetricsEvent.aidl
@@ -16,5 +16,5 @@
package android.net;
+/** {@hide} */
parcelable ConnectivityMetricsEvent;
-parcelable ConnectivityMetricsEvent.Reference;
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index eaaef7f..6fdc739 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -16,12 +16,10 @@
package android.net;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/** {@hide} */
-@SystemApi
public final class ConnectivityMetricsEvent implements Parcelable {
/** The time when this event was collected, as returned by System.currentTimeMillis(). */
@@ -67,7 +65,6 @@
return 0;
}
- /** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(timestamp);
@@ -80,51 +77,4 @@
return String.format("ConnectivityMetricsEvent(%tT.%tL, %d, %d): %s",
timestamp, timestamp, componentTag, eventTag, data);
}
-
- /** {@hide} */
- @SystemApi
- public final static class Reference implements Parcelable {
-
- private long mValue;
-
- public Reference(long ref) {
- this.mValue = ref;
- }
-
- /** Implement the Parcelable interface */
- public static final Parcelable.Creator<Reference> CREATOR
- = new Parcelable.Creator<Reference> (){
- public Reference createFromParcel(Parcel source) {
- return new Reference(source.readLong());
- }
-
- public Reference[] newArray(int size) {
- return new Reference[size];
- }
- };
-
- /** Implement the Parcelable interface */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mValue);
- }
-
- public void readFromParcel(Parcel in) {
- mValue = in.readLong();
- }
-
- public long getValue() {
- return mValue;
- }
-
- public void setValue(long val) {
- mValue = val;
- }
- }
}
diff --git a/core/java/android/net/ConnectivityMetricsLogger.java b/core/java/android/net/ConnectivityMetricsLogger.java
deleted file mode 100644
index 67b6908..0000000
--- a/core/java/android/net/ConnectivityMetricsLogger.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.annotation.SystemApi;
-import android.app.PendingIntent;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/** {@hide} */
-@SystemApi
-public class ConnectivityMetricsLogger {
- private static String TAG = "ConnectivityMetricsLogger";
- private static final boolean DBG = true;
-
- public static final String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger";
-
- // Component Tags
- public static final int COMPONENT_TAG_CONNECTIVITY = 0;
- public static final int COMPONENT_TAG_BLUETOOTH = 1;
- public static final int COMPONENT_TAG_WIFI = 2;
- public static final int COMPONENT_TAG_TELECOM = 3;
- public static final int COMPONENT_TAG_TELEPHONY = 4;
- public static final int NUMBER_OF_COMPONENTS = 5;
-
- // Event Tag
- public static final int TAG_SKIPPED_EVENTS = -1;
-
- public static final String DATA_KEY_EVENTS_COUNT = "count";
-
- public ConnectivityMetricsLogger() {
- }
-
- /**
- * Log a ConnectivityMetricsEvent.
- *
- * This method keeps track of skipped events when MetricsLoggerService throttles input events.
- * It skips logging when MetricsLoggerService is active. When throttling ends, it logs a
- * meta-event containing the number of events dropped. It is not safe to call this method
- * concurrently from different threads.
- *
- * @param timestamp is the epoch timestamp of the event in ms.
- * @param componentTag is the COMPONENT_* constant the event belongs to.
- * @param eventTag is an event type constant whose meaning is specific to the component tag.
- * @param data is a Parcelable instance representing the event.
- */
- public void logEvent(long timestamp, int componentTag, int eventTag, Parcelable data) {
- }
-
- /**
- * Retrieve events
- *
- * @param reference of the last event previously returned. The function will return
- * events following it.
- * If 0 then all events will be returned.
- * After the function call it will contain reference of the
- * last returned event.
- * @return events
- */
- public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) {
- return new ConnectivityMetricsEvent[0];
- }
-
- /**
- * Register PendingIntent which will be sent when new events are ready to be retrieved.
- */
- public boolean register(PendingIntent newEventsIntent) {
- return false;
- }
-
- public boolean unregister(PendingIntent newEventsIntent) {
- return false;
- }
-}
diff --git a/core/java/android/net/IConnectivityMetricsLogger.aidl b/core/java/android/net/IConnectivityMetricsLogger.aidl
deleted file mode 100644
index a83a019..0000000
--- a/core/java/android/net/IConnectivityMetricsLogger.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.app.PendingIntent;
-import android.net.ConnectivityMetricsEvent;
-
-/** {@hide} */
-interface IConnectivityMetricsLogger {
-
- /**
- * @return 0 on success
- * <0 if error happened
- * >0 timestamp after which new events will be accepted
- */
- long logEvent(in ConnectivityMetricsEvent event);
- long logEvents(in ConnectivityMetricsEvent[] events);
-
- /**
- * @param reference of the last event previously returned. The function will return
- * events following it.
- * If 0 then all events will be returned.
- * After the function call it will contain reference of the last event.
- */
- ConnectivityMetricsEvent[] getEvents(inout ConnectivityMetricsEvent.Reference reference);
-
- boolean register(in PendingIntent newEventsIntent);
- void unregister(in PendingIntent newEventsIntent);
-}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index 2715af0..4c0f418 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -506,6 +506,6 @@
if (certificateDate == null) {
return "";
}
- return DateFormat.getDateFormat(context).format(certificateDate);
+ return DateFormat.getMediumDateFormat(context).format(certificateDate);
}
}
diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java
index 258d8e1..c2795a2a 100644
--- a/core/java/android/net/metrics/ApfProgramEvent.java
+++ b/core/java/android/net/metrics/ApfProgramEvent.java
@@ -17,7 +17,6 @@
package android.net.metrics;
import android.annotation.IntDef;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -36,7 +35,6 @@
* the APF program in place with a new APF program.
* {@hide}
*/
-@SystemApi
public final class ApfProgramEvent implements Parcelable {
// Bitflag constants describing what an Apf program filters.
@@ -55,7 +53,6 @@
public final int programLength; // Length of the APF program in bytes
public final int flags; // Bitfield compound of FLAG_* constants
- /** {@hide} */
public ApfProgramEvent(
long lifetime, int filteredRas, int currentRas, int programLength, @Flags int flags) {
this.lifetime = lifetime;
@@ -105,7 +102,6 @@
}
};
- /** {@hide} */
public static @Flags int flagsFor(boolean hasIPv4, boolean multicastFilterOn) {
int bitfield = 0;
if (hasIPv4) {
diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java
index 8451e53..f8d7fa9 100644
--- a/core/java/android/net/metrics/ApfStats.java
+++ b/core/java/android/net/metrics/ApfStats.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,7 +23,6 @@
* An event logged for an interface with APF capabilities when its IpManager state machine exits.
* {@hide}
*/
-@SystemApi
public final class ApfStats implements Parcelable {
public final long durationMs; // time interval in milliseconds these stastistics covers
@@ -36,7 +34,6 @@
public final int programUpdates; // number of APF program updates
public final int maxProgramSize; // maximum APF program size advertised by hardware
- /** {@hide} */
public ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas,
int zeroLifetimeRas, int parseErrors, int programUpdates, int maxProgramSize) {
this.durationMs = durationMs;
diff --git a/core/java/android/net/metrics/DefaultNetworkEvent.java b/core/java/android/net/metrics/DefaultNetworkEvent.java
index 9f0bad7..28cf42f 100644
--- a/core/java/android/net/metrics/DefaultNetworkEvent.java
+++ b/core/java/android/net/metrics/DefaultNetworkEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.net.NetworkCapabilities;
import android.os.Parcel;
import android.os.Parcelable;
@@ -25,7 +24,6 @@
* An event recorded by ConnectivityService when there is a change in the default network.
* {@hide}
*/
-@SystemApi
public final class DefaultNetworkEvent implements Parcelable {
// The ID of the network that has become the new default or NETID_UNSET if none.
public final int netId;
@@ -38,7 +36,6 @@
public final boolean prevIPv4;
public final boolean prevIPv6;
- /** {@hide} */
public DefaultNetworkEvent(int netId, int[] transportTypes,
int prevNetId, boolean prevIPv4, boolean prevIPv6) {
this.netId = netId;
@@ -106,8 +103,4 @@
return new DefaultNetworkEvent[size];
}
};
-
- public static void logEvent(
- int netId, int[] transports, int prevNetId, boolean hadIPv4, boolean hadIPv6) {
- }
}
diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java
index 4a9ff05..7e30ab5 100644
--- a/core/java/android/net/metrics/DhcpClientEvent.java
+++ b/core/java/android/net/metrics/DhcpClientEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,7 +23,6 @@
* An event recorded when a DhcpClient state machine transitions to a new state.
* {@hide}
*/
-@SystemApi
public final class DhcpClientEvent implements Parcelable {
// Names for recording DhcpClient pseudo-state transitions.
@@ -37,7 +35,6 @@
public final String msg;
public final int durationMs;
- /** {@hide} */
public DhcpClientEvent(String ifName, String msg, int durationMs) {
this.ifName = ifName;
this.msg = msg;
@@ -77,7 +74,4 @@
return new DhcpClientEvent[size];
}
};
-
- public static void logStateEvent(String ifName, String state) {
- }
}
diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java
index c3abcf7..f34ffdf 100644
--- a/core/java/android/net/metrics/DhcpErrorEvent.java
+++ b/core/java/android/net/metrics/DhcpErrorEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -27,7 +26,6 @@
* Event class used to record error events when parsing DHCP response packets.
* {@hide}
*/
-@SystemApi
public final class DhcpErrorEvent implements Parcelable {
public static final int L2_ERROR = 1;
public static final int L3_ERROR = 2;
@@ -50,12 +48,10 @@
public static final int DHCP_INVALID_OPTION_LENGTH = makeErrorCode(DHCP_ERROR, 3);
public static final int DHCP_NO_MSG_TYPE = makeErrorCode(DHCP_ERROR, 4);
public static final int DHCP_UNKNOWN_MSG_TYPE = makeErrorCode(DHCP_ERROR, 5);
- /** {@hide} */
public static final int DHCP_NO_COOKIE = makeErrorCode(DHCP_ERROR, 6);
public static final int BUFFER_UNDERFLOW = makeErrorCode(MISC_ERROR, 1);
public static final int RECEIVE_ERROR = makeErrorCode(MISC_ERROR, 2);
- /** {@hide} */
public static final int PARSING_ERROR = makeErrorCode(MISC_ERROR, 3);
public final String ifName;
@@ -66,7 +62,6 @@
// byte 3: optional code
public final int errorCode;
- /** {@hide} */
public DhcpErrorEvent(String ifName, int errorCode) {
this.ifName = ifName;
this.errorCode = errorCode;
@@ -99,12 +94,6 @@
}
};
- public static void logParseError(String ifName, int errorCode) {
- }
-
- public static void logReceiveError(String ifName) {
- }
-
public static int errorCodeWithOption(int errorCode, int option) {
return (0xFFFF0000 & errorCode) | (0xFF & option);
}
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index 6176b2c..89ae1c2 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,7 +23,6 @@
* A DNS event recorded by NetdEventListenerService.
* {@hide}
*/
-@SystemApi
final public class DnsEvent implements Parcelable {
public final int netId;
@@ -38,7 +36,6 @@
// queries.
public final int[] latenciesMs;
- /** {@hide} */
public DnsEvent(int netId, byte[] eventTypes, byte[] returnCodes, int[] latenciesMs) {
this.netId = netId;
this.eventTypes = eventTypes;
@@ -82,8 +79,4 @@
return new DnsEvent[size];
}
};
-
- public static void logEvent(
- int netId, byte[] eventTypes, byte[] returnCodes, int[] latenciesMs) {
- }
}
diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java
index e0a026e..50dda7c 100644
--- a/core/java/android/net/metrics/IpManagerEvent.java
+++ b/core/java/android/net/metrics/IpManagerEvent.java
@@ -17,7 +17,6 @@
package android.net.metrics;
import android.annotation.IntDef;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -32,17 +31,15 @@
* when a network disconnects.
* {@hide}
*/
-@SystemApi
public final class IpManagerEvent implements Parcelable {
- public static final int PROVISIONING_OK = 1;
- public static final int PROVISIONING_FAIL = 2;
- public static final int COMPLETE_LIFECYCLE = 3;
- /** @hide */ public static final int ERROR_STARTING_IPV4 = 4;
- /** @hide */ public static final int ERROR_STARTING_IPV6 = 5;
- /** @hide */ public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6;
+ public static final int PROVISIONING_OK = 1;
+ public static final int PROVISIONING_FAIL = 2;
+ public static final int COMPLETE_LIFECYCLE = 3;
+ public static final int ERROR_STARTING_IPV4 = 4;
+ public static final int ERROR_STARTING_IPV6 = 5;
+ public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6;
- /** {@hide} */
@IntDef(value = {
PROVISIONING_OK, PROVISIONING_FAIL, COMPLETE_LIFECYCLE,
ERROR_STARTING_IPV4, ERROR_STARTING_IPV6, ERROR_STARTING_IPREACHABILITYMONITOR,
@@ -54,7 +51,6 @@
public final @EventType int eventType;
public final long durationMs;
- /** {@hide} */
public IpManagerEvent(String ifName, @EventType int eventType, long duration) {
this.ifName = ifName;
this.eventType = eventType;
@@ -90,9 +86,6 @@
}
};
- public static void logEvent(int eventType, String ifName, long durationMs) {
- }
-
@Override
public String toString() {
return String.format("IpManagerEvent(%s, %s, %dms)",
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
index ee09e22..d69e806 100644
--- a/core/java/android/net/metrics/IpReachabilityEvent.java
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -28,7 +27,6 @@
* a neighbor probe result.
* {@hide}
*/
-@SystemApi
public final class IpReachabilityEvent implements Parcelable {
// Event types.
@@ -38,9 +36,9 @@
public static final int NUD_FAILED = 2 << 8;
/** Neighbor unreachable after a forced probe, IP provisioning is also lost. */
public static final int PROVISIONING_LOST = 3 << 8;
- /** {@hide} Neighbor unreachable notification from kernel. */
+ /** Neighbor unreachable notification from kernel. */
public static final int NUD_FAILED_ORGANIC = 4 << 8;
- /** {@hide} Neighbor unreachable notification from kernel, IP provisioning is also lost. */
+ /** Neighbor unreachable notification from kernel, IP provisioning is also lost. */
public static final int PROVISIONING_LOST_ORGANIC = 5 << 8;
public final String ifName;
@@ -51,7 +49,6 @@
// byte 3: when byte 2 == PROBE, errno code from RTNetlink or IpReachabilityMonitor.
public final int eventType;
- /** {@hide} */
public IpReachabilityEvent(String ifName, int eventType) {
this.ifName = ifName;
this.eventType = eventType;
@@ -84,18 +81,8 @@
}
};
- public static void logProbeEvent(String ifName, int nlErrorCode) {
- }
-
- public static void logNudFailed(String ifName) {
- }
-
- public static void logProvisioningLost(String ifName) {
- }
-
/**
* Returns the NUD failure event type code corresponding to the given conditions.
- * {@hide}
*/
public static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
if (isFromProbe) {
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index 0667495..4df3bf0 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -17,7 +17,6 @@
package android.net.metrics;
import android.annotation.IntDef;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -30,7 +29,6 @@
/**
* {@hide}
*/
-@SystemApi
public final class NetworkEvent implements Parcelable {
public static final int NETWORK_CONNECTED = 1;
@@ -41,16 +39,11 @@
public static final int NETWORK_UNLINGER = 6;
public static final int NETWORK_DISCONNECTED = 7;
- /** {@hide} */
public static final int NETWORK_FIRST_VALIDATION_SUCCESS = 8;
- /** {@hide} */
public static final int NETWORK_REVALIDATION_SUCCESS = 9;
- /** {@hide} */
public static final int NETWORK_FIRST_VALIDATION_PORTAL_FOUND = 10;
- /** {@hide} */
public static final int NETWORK_REVALIDATION_PORTAL_FOUND = 11;
- /** {@hide} */
@IntDef(value = {
NETWORK_CONNECTED,
NETWORK_VALIDATED,
@@ -71,14 +64,12 @@
public final @EventType int eventType;
public final long durationMs;
- /** {@hide} */
public NetworkEvent(int netId, @EventType int eventType, long durationMs) {
this.netId = netId;
this.eventType = eventType;
this.durationMs = durationMs;
}
- /** {@hide} */
public NetworkEvent(int netId, @EventType int eventType) {
this(netId, eventType, 0);
}
@@ -112,15 +103,6 @@
}
};
- public static void logEvent(int netId, int eventType) {
- }
-
- public static void logValidated(int netId, long durationMs) {
- }
-
- public static void logCaptivePortalFound(int netId, long durationMs) {
- }
-
@Override
public String toString() {
return String.format("NetworkEvent(%d, %s, %dms)",
diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java
index 91bd023..3249f80 100644
--- a/core/java/android/net/metrics/RaEvent.java
+++ b/core/java/android/net/metrics/RaEvent.java
@@ -16,7 +16,6 @@
package android.net.metrics;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,10 +23,8 @@
* An event logged when the APF packet socket receives an RA packet.
* {@hide}
*/
-@SystemApi
public final class RaEvent implements Parcelable {
- /** {@hide} */
public static final long NO_LIFETIME = -1L;
// Lifetime in seconds of options found in a single RA packet.
@@ -39,7 +36,6 @@
public final long rdnssLifetime;
public final long dnsslLifetime;
- /** {@hide} */
public RaEvent(long routerLifetime, long prefixValidLifetime, long prefixPreferredLifetime,
long routeInfoLifetime, long rdnssLifetime, long dnsslLifetime) {
this.routerLifetime = routerLifetime;
@@ -96,7 +92,6 @@
}
};
- /** {@hide} */
public static class Builder {
long routerLifetime = NO_LIFETIME;
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index a724ec1..70c6e84 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -17,7 +17,6 @@
package android.net.metrics;
import android.annotation.IntDef;
-import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
@@ -31,14 +30,12 @@
* An event recorded by NetworkMonitor when sending a probe for finding captive portals.
* {@hide}
*/
-@SystemApi
public final class ValidationProbeEvent implements Parcelable {
public static final int PROBE_DNS = 0;
public static final int PROBE_HTTP = 1;
public static final int PROBE_HTTPS = 2;
public static final int PROBE_PAC = 3;
- /** {@hide} */
public static final int PROBE_FALLBACK = 4;
public static final int DNS_FAILURE = 0;
@@ -47,7 +44,6 @@
private static final int FIRST_VALIDATION = 1 << 8;
private static final int REVALIDATION = 2 << 8;
- /** {@hide} */
@IntDef(value = {DNS_FAILURE, DNS_SUCCESS})
@Retention(RetentionPolicy.SOURCE)
public @interface ReturnCode {}
@@ -62,7 +58,6 @@
public final int probeType;
public final @ReturnCode int returnCode;
- /** {@hide} */
public ValidationProbeEvent(
int netId, long durationMs, int probeType, @ReturnCode int returnCode) {
this.netId = netId;
@@ -102,24 +97,18 @@
}
};
- /** @hide */
public static int makeProbeType(int probeType, boolean firstValidation) {
return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION);
}
- /** @hide */
public static String getProbeName(int probeType) {
return Decoder.constants.get(probeType & 0xff, "PROBE_???");
}
- /** @hide */
public static String getValidationStage(int probeType) {
return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
}
- public static void logEvent(int netId, long durationMs, int probeType, int returnCode) {
- }
-
@Override
public String toString() {
return String.format("ValidationProbeEvent(%d, %s:%d %s, %dms)", netId,
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 83b6a52..7ec7ba7 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.RequiresPermission;
import android.content.res.CompatibilityInfo;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -71,7 +72,8 @@
private final String mAddress;
private final int mOwnerUid;
private final String mOwnerPackageName;
- private final DisplayAdjustments mDisplayAdjustments;
+ private final Resources mResources;
+ private DisplayAdjustments mDisplayAdjustments;
private DisplayInfo mDisplayInfo; // never null
private boolean mIsValid;
@@ -355,19 +357,39 @@
/**
* Internal method to create a display.
+ * The display created with this method will have a static {@link DisplayAdjustments} applied.
* Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
* or {@link android.hardware.display.DisplayManager#getDisplay}
* to get a display object.
*
* @hide
*/
- public Display(DisplayManagerGlobal global,
- int displayId, DisplayInfo displayInfo /*not null*/,
+ public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo,
DisplayAdjustments daj) {
+ this(global, displayId, displayInfo, daj, null /*res*/);
+ }
+
+ /**
+ * Internal method to create a display.
+ * The display created with this method will be adjusted based on the adjustments in the
+ * supplied {@link Resources}.
+ *
+ * @hide
+ */
+ public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo,
+ Resources res) {
+ this(global, displayId, displayInfo, null /*daj*/, res);
+ }
+
+ private Display(DisplayManagerGlobal global, int displayId,
+ /*@NotNull*/ DisplayInfo displayInfo, DisplayAdjustments daj, Resources res) {
mGlobal = global;
mDisplayId = displayId;
mDisplayInfo = displayInfo;
- mDisplayAdjustments = new DisplayAdjustments(daj);
+ mResources = res;
+ mDisplayAdjustments = mResources != null
+ ? new DisplayAdjustments(mResources.getConfiguration())
+ : daj != null ? new DisplayAdjustments(daj) : null;
mIsValid = true;
// Cache properties that cannot change as long as the display is valid.
@@ -512,6 +534,13 @@
* @hide
*/
public DisplayAdjustments getDisplayAdjustments() {
+ if (mResources != null) {
+ final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
+ if (!mDisplayAdjustments.equals(currentAdjustements)) {
+ mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
+ }
+ }
+
return mDisplayAdjustments;
}
@@ -562,7 +591,7 @@
public void getSize(Point outSize) {
synchronized (this) {
updateDisplayInfoLocked();
- mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
+ mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.x = mTempMetrics.widthPixels;
outSize.y = mTempMetrics.heightPixels;
}
@@ -577,7 +606,7 @@
public void getRectSize(Rect outSize) {
synchronized (this) {
updateDisplayInfoLocked();
- mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
+ mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
}
}
@@ -908,7 +937,7 @@
public void getMetrics(DisplayMetrics outMetrics) {
synchronized (this) {
updateDisplayInfoLocked();
- mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
+ mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments());
}
}
@@ -1017,7 +1046,7 @@
long now = SystemClock.uptimeMillis();
if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
updateDisplayInfoLocked();
- mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
+ mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
mCachedAppWidthCompat = mTempMetrics.widthPixels;
mCachedAppHeightCompat = mTempMetrics.heightPixels;
mLastCachedAppSizeUpdate = now;
@@ -1029,7 +1058,7 @@
public String toString() {
synchronized (this) {
updateDisplayInfoLocked();
- mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
+ mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
return "Display id " + mDisplayId + ": " + mDisplayInfo
+ ", " + mTempMetrics + ", isValid=" + mIsValid;
}
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index 92f0e8f..358a2d1 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -132,6 +132,26 @@
*/
public static final int FIRST_DRAW_FRAME = 9;
+ /**
+ * Metric identifier for the timestamp of the intended vsync for this frame.
+ * <p>
+ * The intended start point for the frame. If this value is different from
+ * {@link #VSYNC_TIMESTAMP}, there was work occurring on the UI thread that
+ * prevented it from responding to the vsync signal in a timely fashion.
+ * </p>
+ */
+ public static final int INTENDED_VSYNC_TIMESTAMP = 10;
+
+ /**
+ * Metric identifier for the timestamp of the actual vsync for this frame.
+ * <p>
+ * The time value that was used in all the vsync listeners and drawing for
+ * the frame (Choreographer frame callbacks, animations,
+ * {@link View#getDrawingTime()}, etc…)
+ * </p>
+ */
+ public static final int VSYNC_TIMESTAMP = 11;
+
private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
/**
@@ -151,6 +171,8 @@
SWAP_BUFFERS_DURATION,
TOTAL_DURATION,
FIRST_DRAW_FRAME,
+ INTENDED_VSYNC_TIMESTAMP,
+ VSYNC_TIMESTAMP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Metric {}
@@ -261,7 +283,7 @@
* @return the value of the metric or -1 if it is not available.
*/
public long getMetric(@Metric int id) {
- if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) {
+ if (id < UNKNOWN_DELAY_DURATION || id > VSYNC_TIMESTAMP) {
return -1;
}
@@ -271,6 +293,10 @@
if (id == FIRST_DRAW_FRAME) {
return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
+ } else if (id == INTENDED_VSYNC_TIMESTAMP) {
+ return mTimingData[Index.INTENDED_VSYNC];
+ } else if (id == VSYNC_TIMESTAMP) {
+ return mTimingData[Index.VSYNC];
}
int durationsIdx = 2 * id;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index cf8da17..b718696 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -508,9 +508,9 @@
nativeSetAlpha(mNativeObject, alpha);
}
- public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ public void setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
checkNotReleased();
- nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
+ nativeSetMatrix(mNativeObject, dsdx, dtdx, dtdy, dsdy);
}
public void setWindowCrop(Rect crop) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index aa85a98..8666930 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -953,7 +953,7 @@
public @interface AutoFillMode {}
/**
- * This view inherits the autofill state from it's parent. If there is no parent it is
+ * This view inherits the auto-fill state from it's parent. If there is no parent it is
* {@link #AUTO_FILL_MODE_AUTO}.
* Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">
* {@code android:autoFillMode}.
@@ -968,7 +968,11 @@
public static final int AUTO_FILL_MODE_AUTO = 1;
/**
- * Require the user to manually force an auto-fill request.
+ * Do not trigger an auto-fill request if this view is focused. The user can still force
+ * an auto-fill request.
+ * <p>This does not prevent this field from being auto-filled if an auto-fill operation is
+ * triggered from a different view.</p>
+ *
* Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">{@code
* android:autoFillMode}.
*/
@@ -6523,7 +6527,12 @@
if (isAutoFillable()) {
AutoFillManager afm = getAutoFillManager();
if (afm != null) {
- afm.focusChanged(this, gainFocus);
+ boolean adjGainFocus = gainFocus;
+ if (adjGainFocus && getResolvedAutoFillMode() == AUTO_FILL_MODE_MANUAL) {
+ adjGainFocus = false;
+ }
+
+ afm.focusChanged(this, adjGainFocus);
}
}
@@ -6984,8 +6993,12 @@
* Called when assist structure is being retrieved from a view as part of an auto-fill request.
*
* <p>This method already provides most of what's needed for auto-fill, but should be overridden
- * when the view contents does not include PII (Personally Identifiable Information) (so it
- * can call {@link ViewStructure#setSanitized(boolean) ViewStructure#setSanitized(true)}).
+ * <ol>
+ * <li>The view contents does not include PII (Personally Identifiable Information), so it
+ * can call {@link ViewStructure#setSanitized(boolean)} passing {@code true}.
+ * <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
+ * {@link ViewStructure#setAutoFillOptions(String[])}, or {@link ViewStructure#setUrl(String)}.
+ * </ol>
*
* @param structure Fill in with structured view data. The default implementation
* fills in all data that can be inferred from the view itself.
@@ -9303,6 +9316,30 @@
}
/**
+ * Returns the resolved auto-fill mode for this view.
+ *
+ * This is the same as {@link #getAutoFillMode()} but if the mode is
+ * {@link #AUTO_FILL_MODE_INHERIT} the parents auto-fill mode will be returned.
+ *
+ * @return One of {@link #AUTO_FILL_MODE_AUTO}, or {@link #AUTO_FILL_MODE_MANUAL}.
+ *
+ * @hide
+ */
+ public @AutoFillMode int getResolvedAutoFillMode() {
+ @AutoFillMode int autoFillMode = getAutoFillMode();
+
+ if (autoFillMode == AUTO_FILL_MODE_INHERIT) {
+ if (mParent == null) {
+ throw new IllegalStateException("View is detached, cannot resolve autoFillMode");
+ } else {
+ return mParent.getResolvedAutoFillMode();
+ }
+ } else {
+ return autoFillMode;
+ }
+ }
+
+ /**
* Find the nearest view in the specified direction that can take focus.
* This does not actually give focus to that view.
*
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index cc11cb8..cdfd61b 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -659,4 +659,17 @@
* @return true if the action was consumed by this ViewParent
*/
public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments);
+
+ /**
+ * Return the resolved auto-fill mode.
+ *
+ * @return The resolved auto-fill mode
+ *
+ * @see View#getResolvedAutoFillMode()
+ *
+ * @hide
+ */
+ default @View.AutoFillMode int getResolvedAutoFillMode() {
+ return View.AUTO_FILL_MODE_AUTO;
+ }
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c81e938..595e7a1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1047,8 +1047,8 @@
// Get new instance of display based on current display adjustments. It may be updated later
// if moving between the displays also involved a configuration change.
- final DisplayAdjustments displayAdjustments = mView.getResources().getDisplayAdjustments();
- mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId, displayAdjustments);
+ mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId,
+ mView.getResources());
mAttachInfo.mDisplayState = mDisplay.getState();
// Internal state updated, now notify the view hierarchy.
mView.dispatchMovedToDisplay(mDisplay);
@@ -3384,7 +3384,7 @@
if (force || mLastConfiguration.diff(config) != 0) {
// Update the display with new DisplayAdjustments.
mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(
- mDisplay.getDisplayId(), localResources.getDisplayAdjustments());
+ mDisplay.getDisplayId(), localResources);
final int lastLayoutDirection = mLastConfiguration.getLayoutDirection();
final int currentLayoutDirection = config.getLayoutDirection();
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index bc2725f..84c2c84 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -307,6 +307,15 @@
public abstract void setAutoFillValue(AutoFillValue value);
/**
+ * Sets the options that can be used to auto-fill this node.
+ *
+ * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning of
+ * each possible value in the list.
+ */
+ // TODO(b/33197203, b/33802548): add CTS/unit test
+ public abstract void setAutoFillOptions(String[] options);
+
+ /**
* Marks this node as sanitized so its content are sent on {@link
* android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
* Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)}.
diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java
index 017f7f8..5d85bfd 100644
--- a/core/java/android/view/autofill/AutoFillType.java
+++ b/core/java/android/view/autofill/AutoFillType.java
@@ -44,8 +44,6 @@
private static final int TYPE_TEXT = 1;
private static final int TYPE_TOGGLE = 2;
- // TODO(b/33197203): make sure it works with Spinners and/or add a new type for them
- // (since they're often used for credit card selection)
private static final int TYPE_LIST = 3;
// TODO(b/33197203): add others, like date picker? That would be trick, because they're set as:
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 2d6f443..f9d7332 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -176,7 +176,7 @@
// paths and pass them to the zygote as strings.
final List<String> zipPaths = new ArrayList<>(10);
final List<String> libPaths = new ArrayList<>(10);
- LoadedApk.makePaths(null, sPackage.applicationInfo, zipPaths, libPaths);
+ LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths);
final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
TextUtils.join(File.pathSeparator, zipPaths);
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 2cfefba..0b3cff1 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -34,6 +34,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.autofill.AutoFillManager;
/**
* An AdapterView is a view whose children are determined by an {@link Adapter}.
@@ -914,6 +915,11 @@
dispatchOnItemSelected();
}
}
+ // Always notify AutoFillManager - it will return right away if auto-fill is disabled.
+ final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+ if (afm != null) {
+ afm.valueChanged(this);
+ }
}
private void dispatchOnItemSelected() {
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index f2c2af5..887c59a 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -32,6 +32,7 @@
import android.view.SoundEffectConstants;
import android.view.ViewDebug;
import android.view.ViewHierarchyEncoder;
+import android.view.ViewStructure;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.autofill.AutoFillManager;
@@ -68,6 +69,10 @@
private OnCheckedChangeListener mOnCheckedChangeListener;
private OnCheckedChangeListener mOnCheckedChangeWidgetListener;
+ // Indicates whether the toggle state was set from resources or dynamically, so it can be used
+ // to sanitize auto-fill requests.
+ private boolean mCheckedFromResource = false;
+
private static final int[] CHECKED_STATE_SET = {
R.attr.state_checked
};
@@ -109,6 +114,7 @@
final boolean checked = a.getBoolean(
com.android.internal.R.styleable.CompoundButton_checked, false);
setChecked(checked);
+ mCheckedFromResource = true;
a.recycle();
@@ -148,6 +154,7 @@
@Override
public void setChecked(boolean checked) {
if (mChecked != checked) {
+ mCheckedFromResource = false;
mChecked = checked;
refreshDrawableState();
notifyViewAccessibilityStateChangedIfNeeded(
@@ -569,6 +576,13 @@
// TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
@Override
+ public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
+ super.onProvideAutoFillStructure(structure, flags);
+
+ structure.setSanitized(mCheckedFromResource);
+ }
+
+ @Override
public void autoFill(AutoFillValue value) {
if (!isEnabled()) return;
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index 76b3813..bba3a11 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -24,6 +24,7 @@
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStructure;
import android.view.autofill.AutoFillManager;
import android.view.autofill.AutoFillType;
import android.view.autofill.AutoFillValue;
@@ -66,6 +67,10 @@
private OnCheckedChangeListener mOnCheckedChangeListener;
private PassThroughHierarchyChangeListener mPassThroughListener;
+ // Indicates whether the child was set from resources or dynamically, so it can be used
+ // to sanitize auto-fill requests.
+ private int mInitialCheckedId = View.NO_ID;
+
/**
* {@inheritDoc}
*/
@@ -89,8 +94,8 @@
int value = attributes.getResourceId(R.styleable.RadioGroup_checkedButton, View.NO_ID);
if (value != View.NO_ID) {
mCheckedId = value;
+ mInitialCheckedId = value;
}
-
final int index = attributes.getInt(com.android.internal.R.styleable.RadioGroup_orientation, VERTICAL);
setOrientation(index);
@@ -411,6 +416,12 @@
// TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
@Override
+ public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
+ super.onProvideAutoFillStructure(structure, flags);
+ structure.setSanitized(mCheckedId == mInitialCheckedId);
+ }
+
+ @Override
public void autoFill(AutoFillValue value) {
if (!isEnabled()) return;
@@ -430,6 +441,15 @@
@Override
public AutoFillValue getAutoFillValue() {
- return isEnabled() ? AutoFillValue.forList(getCheckedRadioButtonId()) : null;
+ if (!isEnabled()) return null;
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getId() == mCheckedId) {
+ return AutoFillValue.forList(i);
+ }
+ }
+ return null;
}
}
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 28cc693..50c016b 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -41,9 +41,12 @@
import android.view.PointerIcon;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStructure;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.autofill.AutoFillType;
+import android.view.autofill.AutoFillValue;
import android.widget.PopupWindow.OnDismissListener;
import com.android.internal.R;
@@ -784,6 +787,7 @@
return handled;
}
+ @Override
public void onClick(DialogInterface dialog, int which) {
setSelection(which);
dialog.dismiss();
@@ -912,6 +916,42 @@
return super.onResolvePointerIcon(event, pointerIndex);
}
+ // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+ @Override
+ public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
+ super.onProvideAutoFillStructure(structure, flags);
+ // TODO(b/33197203): implement sanitization so initial value is only sanitized when coming
+ // from resources.
+
+ final int count = getAdapter().getCount();
+ if (count > 0) {
+ final String[] options = new String[count];
+ for (int i = 0; i < count; i++) {
+ options[i] = getAdapter().getItem(i).toString();
+ }
+ structure.setAutoFillOptions(options);
+ }
+ }
+
+ @Override
+ public void autoFill(AutoFillValue value) {
+ if (!isEnabled()) return;
+
+ final int position = value.getListValue();
+ setSelection(position);
+ }
+
+ @Override
+ public AutoFillType getAutoFillType() {
+ return AutoFillType.forList();
+ }
+
+ @Override
+ public AutoFillValue getAutoFillValue() {
+ return isEnabled() ? AutoFillValue.forList(getSelectedItemPosition()) : null;
+ }
+
static class SavedState extends AbsSpinner.SavedState {
boolean showDropdown;
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
index ef91576..0183343 100644
--- a/core/java/android/widget/TextInputTimePickerView.java
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -177,15 +177,15 @@
mAmPmSpinner.setVisibility(is24Hour ? View.INVISIBLE : View.VISIBLE);
- mHourEditText.setText(String.format(format, localizedHour));
- mMinuteEditText.setText(String.format(format, minute));
-
if (amOrPm == AM) {
mAmPmSpinner.setSelection(0);
} else {
mAmPmSpinner.setSelection(1);
}
+ mHourEditText.setText(String.format(format, localizedHour));
+ mMinuteEditText.setText(String.format(format, minute));
+
if (mErrorShowing) {
validateInput();
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bf8de38..5e6e0f9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -727,7 +727,7 @@
private boolean mHasPresetAutoSizeValues = false;
// Indicates whether the text was set from resources or dynamically, so it can be used to
- // sanitize auto-fill request.
+ // sanitize auto-fill requests.
private boolean mTextFromResource = false;
/**
diff --git a/core/java/com/android/internal/util/Predicate.java b/core/java/com/android/internal/util/Predicate.java
index bc6d6b3..1b5eaff 100644
--- a/core/java/com/android/internal/util/Predicate.java
+++ b/core/java/com/android/internal/util/Predicate.java
@@ -25,7 +25,10 @@
* <p/>
* Implementors of Predicate which may cause side effects upon evaluation are
* strongly encouraged to state this fact clearly in their API documentation.
+ *
+ * @deprecated Use {@code java.util.function.Predicate} instead.
*/
+@Deprecated
public interface Predicate<T> {
boolean apply(T t);
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 0c07192..3dd2498 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -220,7 +220,6 @@
external/skia/src/effects \
external/skia/src/image \
external/skia/src/images \
- external/skia/src/utils \
external/sqlite/dist \
external/sqlite/android \
external/tremor/Tremor \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 30d6337..417ef8a0 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -8,7 +8,6 @@
#include "SkBRDAllocator.h"
#include "SkFrontBufferedStream.h"
#include "SkMath.h"
-#include "SkOpts.h"
#include "SkPixelRef.h"
#include "SkStream.h"
#include "SkUtils.h"
@@ -229,45 +228,6 @@
needsFineScale(fullSize.height(), decodedSize.height(), sampleSize);
}
-static inline SkAlphaType computeDecodeAlphaType(SkColorType colorType, SkAlphaType alphaType) {
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- // Skia premultiplies linearly. Until the framework enables linear blending,
- // it expects a legacy premultiply.
- if (kPremul_SkAlphaType == alphaType && kRGBA_F16_SkColorType != colorType) {
- return kUnpremul_SkAlphaType;
- }
-#endif
-
- return alphaType;
-}
-
-static inline void premultiplyIfNecessary(SkBitmap* bitmap, SkPMColor* colorPtr, int* colorCount,
- SkAlphaType alphaType, bool requireUnpremultiplied) {
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- if (kUnpremul_SkAlphaType != alphaType || requireUnpremultiplied) {
- return;
- }
-
- switch (bitmap->colorType()) {
- case kN32_SkColorType:
- for (int y = 0; y < bitmap->height(); y++) {
- SkOpts::RGBA_to_rgbA(bitmap->getAddr32(0, y), bitmap->getAddr32(0, y),
- bitmap->width());
- }
-
- return;
- case kIndex_8_SkColorType:
- SkOpts::RGBA_to_rgbA(colorPtr, colorPtr, *colorCount);
- return;
- default:
- // kRGBA_F16 will be premultiplied by the codec if necessary.
- // kGray_8 (alias kAlpha_8) and k565 are opaque.
- LOG_ALWAYS_FATAL("Should be unreachable - no need for legacy premultiply.");
- return;
- }
-#endif
-}
-
static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options) {
// This function takes ownership of the input stream. Since the SkAndroidCodec
// will take ownership of the stream, we don't necessarily need to take ownership
@@ -450,15 +410,13 @@
}
SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied);
- SkAlphaType decodeAlphaType = computeDecodeAlphaType(decodeColorType, alphaType);
const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(),
- decodeColorType, decodeAlphaType, codec->computeOutputColorSpace(decodeColorType));
-
- SkImageInfo bitmapInfo = decodeInfo.makeAlphaType(alphaType);
+ decodeColorType, alphaType, codec->computeOutputColorSpace(decodeColorType));
// For wide gamut images, we will leave the color space on the SkBitmap. Otherwise,
// use the default.
+ SkImageInfo bitmapInfo = decodeInfo;
sk_sp<SkColorSpace> srgb =
SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
SkColorSpace::kSRGB_Gamut,
@@ -502,8 +460,6 @@
default:
return nullObjectReturn("codec->getAndroidPixels() failed.");
}
- premultiplyIfNecessary(&decodingBitmap, colorPtr, colorCount, decodeAlphaType,
- requireUnpremultiplied);
jbyteArray ninePatchChunk = NULL;
if (peeker.mPatch != NULL) {
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 314595f..723dce6 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -119,6 +119,96 @@
return block;
}
+// This is called by zygote (running as user root) as part of preloadResources.
+static void verifySystemIdmaps()
+{
+ pid_t pid;
+ char system_id[10];
+
+ snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
+
+ switch (pid = fork()) {
+ case -1:
+ ALOGE("failed to fork for idmap: %s", strerror(errno));
+ break;
+ case 0: // child
+ {
+ struct __user_cap_header_struct capheader;
+ struct __user_cap_data_struct capdata;
+
+ memset(&capheader, 0, sizeof(capheader));
+ memset(&capdata, 0, sizeof(capdata));
+
+ capheader.version = _LINUX_CAPABILITY_VERSION;
+ capheader.pid = 0;
+
+ if (capget(&capheader, &capdata) != 0) {
+ ALOGE("capget: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ capdata.effective = capdata.permitted;
+ if (capset(&capheader, &capdata) != 0) {
+ ALOGE("capset: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (setgid(AID_SYSTEM) != 0) {
+ ALOGE("setgid: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (setuid(AID_SYSTEM) != 0) {
+ ALOGE("setuid: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ // Generic idmap parameters
+ const char* argv[8];
+ int argc = 0;
+ struct stat st;
+
+ memset(argv, NULL, sizeof(argv));
+ argv[argc++] = AssetManager::IDMAP_BIN;
+ argv[argc++] = "--scan";
+ argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
+ argv[argc++] = AssetManager::TARGET_APK_PATH;
+ argv[argc++] = AssetManager::IDMAP_DIR;
+
+ // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
+ // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
+ char subdir[PROP_VALUE_MAX];
+ int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY,
+ subdir);
+ if (len == 0) {
+ len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
+ }
+ if (len > 0) {
+ String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
+ if (stat(overlayPath.string(), &st) == 0) {
+ argv[argc++] = overlayPath.string();
+ }
+ }
+ if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
+ argv[argc++] = AssetManager::OVERLAY_DIR;
+ }
+
+ // Finally, invoke idmap (if any overlay directory exists)
+ if (argc > 5) {
+ execv(AssetManager::IDMAP_BIN, (char* const*)argv);
+ ALOGE("failed to execv for idmap: %s", strerror(errno));
+ exit(1); // should never get here
+ } else {
+ exit(0);
+ }
+ }
+ break;
+ default: // parent
+ waitpid(pid, NULL, 0);
+ break;
+ }
+}
+
// ----------------------------------------------------------------------------
// this guy is exported to other jni routines
@@ -1507,6 +1597,9 @@
static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
{
+ if (isSystem) {
+ verifySystemIdmaps();
+ }
AssetManager* am = new AssetManager();
if (am == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", "");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0171562..a81901d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -356,9 +356,9 @@
}
static void nativeSetMatrix(JNIEnv* env, jclass clazz, jlong nativeObject,
- jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) {
+ jfloat dsdx, jfloat dtdx, jfloat dtdy, jfloat dsdy) {
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
- status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy);
+ status_t err = ctrl->setMatrix(dsdx, dtdx, dtdy, dsdy);
if (err < 0 && err != NO_INIT) {
doThrowIAE(env);
}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8031f19..d2d6620 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2289,12 +2289,14 @@
<!-- Controls the auto-fill behavior for this view -->
<attr name="autoFillMode">
- <!-- Inherit the behavior from the parent. If there is no parent it is auto. -->
+ <!-- Inherit the behavior from the parent. If there is no parent it is auto. This is the
+ default value for this attribute.-->
<enum name="inherit" value="0" />
<!-- Allows this view to automatically trigger an auto-fill request when it get focus.
-->
<enum name="auto" value="1" />
- <!-- The user has to manually force an auto-fill request for this view. -->
+ <!-- Do not trigger an auto-fill request when this view is focused. The user can still
+ manually force an auto-fill request for this view. -->
<enum name="manual" value="2" />
</attr>
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index 0a814f3..05fec5e 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -50,5 +50,5 @@
LOCAL_SRC_FILES := src/android/test/PerformanceTestCase.java
LOCAL_MODULE := legacy-performance-test-hostdex
-include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+include $(BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY)
endif # HOST_OS == linux
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 84111ae..acacd76 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -202,6 +202,15 @@
*cookie = static_cast<int32_t>(mAssetPaths.size());
}
+#ifdef __ANDROID__
+ // Load overlays, if any
+ asset_path oap;
+ for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {
+ oap.isSystemAsset = isSystemAsset;
+ mAssetPaths.add(oap);
+ }
+#endif
+
if (mResources != NULL) {
appendPathToResTable(ap, appAsLib);
}
@@ -484,6 +493,11 @@
}
bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) const {
+ // skip those ap's that correspond to system overlays
+ if (ap.isSystemOverlay) {
+ return true;
+ }
+
Asset* ass = NULL;
ResTable* sharedRes = NULL;
bool shared = true;
@@ -525,6 +539,14 @@
ALOGV("Creating shared resources for %s", ap.path.string());
sharedRes = new ResTable();
sharedRes->add(ass, idmap, nextEntryIdx + 1, false);
+#ifdef __ANDROID__
+ const char* data = getenv("ANDROID_DATA");
+ LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
+ String8 overlaysListPath(data);
+ overlaysListPath.appendPath(kResourceCache);
+ overlaysListPath.appendPath("overlays.list");
+ addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);
+#endif
sharedRes = const_cast<AssetManager*>(this)->
mZipSet.setZipResourceTable(ap.path, sharedRes);
}
@@ -633,6 +655,58 @@
return ass;
}
+void AssetManager::addSystemOverlays(const char* pathOverlaysList,
+ const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const
+{
+ FILE* fin = fopen(pathOverlaysList, "r");
+ if (fin == NULL) {
+ return;
+ }
+
+#ifndef _WIN32
+ if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) {
+ fclose(fin);
+ return;
+ }
+#endif
+ char buf[1024];
+ while (fgets(buf, sizeof(buf), fin)) {
+ // format of each line:
+ // <path to apk><space><path to idmap><newline>
+ char* space = strchr(buf, ' ');
+ char* newline = strchr(buf, '\n');
+ asset_path oap;
+
+ if (space == NULL || newline == NULL || newline < space) {
+ continue;
+ }
+
+ oap.path = String8(buf, space - buf);
+ oap.type = kFileTypeRegular;
+ oap.idmap = String8(space + 1, newline - space - 1);
+ oap.isSystemOverlay = true;
+
+ Asset* oass = const_cast<AssetManager*>(this)->
+ openNonAssetInPathLocked("resources.arsc",
+ Asset::ACCESS_BUFFER,
+ oap);
+
+ if (oass != NULL) {
+ Asset* oidmap = openIdmapLocked(oap);
+ offset++;
+ sharedRes->add(oass, oidmap, offset + 1, false);
+ const_cast<AssetManager*>(this)->mAssetPaths.add(oap);
+ const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
+ delete oidmap;
+ }
+ }
+
+#ifndef _WIN32
+ TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN));
+#endif
+ fclose(fin);
+}
+
const ResTable& AssetManager::getResources(bool required) const
{
const ResTable* rt = getResTable(required);
@@ -1372,6 +1446,20 @@
return mModWhen == modWhen;
}
+void AssetManager::SharedZip::addOverlay(const asset_path& ap)
+{
+ mOverlays.add(ap);
+}
+
+bool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const
+{
+ if (idx >= mOverlays.size()) {
+ return false;
+ }
+ *out = mOverlays[idx];
+ return true;
+}
+
AssetManager::SharedZip::~SharedZip()
{
if (kIsDebug) {
@@ -1490,6 +1578,22 @@
return true;
}
+void AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay)
+{
+ int idx = getIndex(path);
+ sp<SharedZip> zip = mZipFile[idx];
+ zip->addOverlay(overlay);
+}
+
+bool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const
+{
+ sp<SharedZip> zip = SharedZip::get(path, false);
+ if (zip == NULL) {
+ return false;
+ }
+ return zip->getOverlay(idx, out);
+}
+
/*
* Compute the zip file's index.
*
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index f1e8b93..becd307 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -202,10 +202,12 @@
private:
struct asset_path
{
- asset_path() : path(""), type(kFileTypeRegular), idmap(""), isSystemAsset(false) {}
+ asset_path() : path(""), type(kFileTypeRegular), idmap(""),
+ isSystemOverlay(false), isSystemAsset(false) {}
String8 path;
FileType type;
String8 idmap;
+ bool isSystemOverlay;
bool isSystemAsset;
};
@@ -235,6 +237,9 @@
Asset* openIdmapLocked(const struct asset_path& ap) const;
+ void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,
+ ResTable* sharedRes, size_t offset) const;
+
class SharedZip : public RefBase {
public:
static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
@@ -249,6 +254,9 @@
bool isUpToDate();
+ void addOverlay(const asset_path& ap);
+ bool getOverlay(size_t idx, asset_path* out) const;
+
protected:
~SharedZip();
@@ -263,6 +271,8 @@
Asset* mResourceTableAsset;
ResTable* mResourceTable;
+ Vector<asset_path> mOverlays;
+
static Mutex gLock;
static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
};
@@ -296,6 +306,9 @@
bool isUpToDate();
+ void addOverlay(const String8& path, const asset_path& overlay);
+ bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
+
private:
void closeZip(int idx);
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 860725b..44af5fd 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -133,7 +133,7 @@
LOG_ALWAYS_FATAL_IF(!glInterface.get());
GrContextOptions options;
- options.fDisableDistanceFieldPaths = true;
+ options.fGpuPathRenderers &= ~GrContextOptions::GpuPathRenderers::kDistanceField;
options.fAllowPathMaskCaching = true;
mRenderThread.setGrContext(GrContext::Create(GrBackend::kOpenGL_GrBackend,
(GrBackendContext)glInterface.get(), options));
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index a391d1e..95d9459 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -579,7 +579,7 @@
SkPaint textPaint;
textPaint.setAntiAlias(true);
textPaint.setTextSize(20);
- textPaint.setStrikeThruText(true);
+ textPaint.setFlags(textPaint.getFlags() | SkPaint::kStrikeThruText_ReserveFlag);
textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
for (int i = 0; i < LOOPS; i++) {
TestUtils::drawUtf8ToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1));
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 669f03c..f48d98c 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -200,8 +200,10 @@
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
- paint.setUnderlineText(i != 0);
- paint.setStrikeThruText(j != 0);
+ uint32_t flags = paint.getFlags();
+ if (i != 0) flags |= SkPaint::kUnderlineText_ReserveFlag;
+ if (j != 0) flags |= SkPaint::kStrikeThruText_ReserveFlag;
+ paint.setFlags(flags);
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
}
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 5b4dd48..34164b16 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -118,8 +118,6 @@
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<!-- Permission needed to hold a wakelock in dumpstate.cpp (drop_root_user()) -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
- <!-- Permission needed to enable/disable overlays -->
- <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index c81bd1b..280ae69 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3458,6 +3458,9 @@
// OPEN: Settings > Apps > Default Apps > Assist > Default voice input
DEFAULT_VOICE_INPUT_PICKER = 844;
+ // OPEN: Settings > Storage > [Profile]
+ SETTINGS_STORAGE_PROFILE = 845;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index b459f74..4f8b8af 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -38,15 +38,15 @@
import android.app.backup.BackupTransport;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
-import android.app.backup.IBackupObserver;
-import android.app.backup.IBackupManagerMonitor;
-import android.app.backup.RestoreDescription;
-import android.app.backup.RestoreSet;
import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
+import android.app.backup.RestoreDescription;
+import android.app.backup.RestoreSet;
import android.app.backup.SelectBackupTransportCallback;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -136,6 +136,7 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -146,6 +147,7 @@
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
@@ -327,6 +329,11 @@
final Object mClearDataLock = new Object();
volatile boolean mClearingData;
+ @GuardedBy("mPendingRestores")
+ private boolean mIsRestoreInProgress;
+ @GuardedBy("mPendingRestores")
+ private final Queue<PerformUnifiedRestoreTask> mPendingRestores = new ArrayDeque<>();
+
ActiveRestoreSession mActiveRestoreSession;
// Watch the device provisioning operation during setup
@@ -909,11 +916,28 @@
{
RestoreParams params = (RestoreParams)msg.obj;
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
- BackupRestoreTask task = new PerformUnifiedRestoreTask(params.transport,
+
+ PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(params.transport,
params.observer, params.monitor, params.token, params.pkgInfo,
params.pmToken, params.isSystemRestore, params.filterSet);
- Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
- sendMessage(restoreMsg);
+
+ synchronized (mPendingRestores) {
+ if (mIsRestoreInProgress) {
+ if (DEBUG) {
+ Slog.d(TAG, "Restore in progress, queueing.");
+ }
+ mPendingRestores.add(task);
+ // This task will be picked up and executed when the the currently running
+ // restore task finishes.
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting restore.");
+ }
+ mIsRestoreInProgress = true;
+ Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
+ sendMessage(restoreMsg);
+ }
+ }
break;
}
@@ -2658,19 +2682,32 @@
mStateDir = new File(mBaseStateDir, dirName);
mCurrentOpToken = generateToken();
- mCurrentState = BackupState.INITIAL;
mFinished = false;
- CountDownLatch latch = new CountDownLatch(1);
- String[] fullBackups =
- mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
- mFullBackupTask =
- new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null,
- fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, latch,
- mObserver, mMonitor,mUserInitiated);
+ synchronized (mCurrentOpLock) {
+ if (isBackupOperationInProgress()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping backup since one is already in progress.");
+ }
+ mCancelAll = true;
+ mFullBackupTask = null;
+ mCurrentState = BackupState.FINAL;
+ addBackupTrace("Skipped. Backup already in progress.");
+ } else {
+ mCurrentState = BackupState.INITIAL;
+ CountDownLatch latch = new CountDownLatch(1);
+ String[] fullBackups =
+ mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+ mFullBackupTask =
+ new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null,
+ fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
+ latch,
+ mObserver, mMonitor, mUserInitiated);
- registerTask();
- addBackupTrace("STATE => INITIAL");
+ registerTask();
+ addBackupTrace("STATE => INITIAL");
+ }
+ }
}
/**
@@ -3053,7 +3090,9 @@
mWakelock.acquire();
(new Thread(mFullBackupTask, "full-transport-requested")).start();
} else if (mCancelAll) {
- mFullBackupTask.unregisterTask();
+ if (mFullBackupTask != null) {
+ mFullBackupTask.unregisterTask();
+ }
sendBackupFinished(mObserver, BackupManager.ERROR_BACKUP_CANCELLED);
} else {
mFullBackupTask.unregisterTask();
@@ -3537,6 +3576,18 @@
}
}
+ private boolean isBackupOperationInProgress() {
+ synchronized (mCurrentOpLock) {
+ for (int i = 0; i < mCurrentOperations.size(); i++) {
+ Operation op = mCurrentOperations.valueAt(i);
+ if (op.type == OP_TYPE_BACKUP && op.state == OP_PENDING) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
// ----- Full backup/restore to a file/socket -----
@@ -4519,6 +4570,14 @@
mCurrentOpToken = generateToken();
mBackupRunnerOpToken = generateToken();
+ if (isBackupOperationInProgress()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping full backup. A backup is already in progress.");
+ }
+ mCancelAll = true;
+ return;
+ }
+
registerTask();
for (String pkg : whichPackages) {
@@ -9148,6 +9207,24 @@
// done; we can finally release the wakelock and be legitimately done.
Slog.i(TAG, "Restore complete.");
+
+ synchronized (mPendingRestores) {
+ if (mPendingRestores.size() > 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting next pending restore.");
+ }
+ PerformUnifiedRestoreTask task = mPendingRestores.remove();
+ mBackupHandler.sendMessage(
+ mBackupHandler.obtainMessage(MSG_BACKUP_RESTORE_STEP, task));
+
+ } else {
+ mIsRestoreInProgress = false;
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "No pending restores.");
+ }
+ }
+ }
+
mWakelock.release();
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index fe5b3a2..b95ed08 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -881,7 +881,7 @@
final class MyPackageMonitor extends PackageMonitor {
/**
- * Set of packages to be monitored.
+ * Package names that are known to contain {@link InputMethodService}.
*
* <p>No need to include packages because of direct-boot unaware IMEs since we always rescan
* all the packages when the user is unlocked, and direct-boot awareness will not be changed
@@ -889,16 +889,36 @@
* rescanning.</p>
*/
@GuardedBy("mMethodMap")
- private ArraySet<String> mPackagesToMonitorComponentChange = new ArraySet<>();
+ final private ArraySet<String> mKnownImePackageNames = new ArraySet<>();
+
+ /**
+ * Packages that are appeared, disappeared, or modified for whatever reason.
+ *
+ * <p>Note: For now we intentionally use {@link ArrayList} instead of {@link ArraySet}
+ * because 1) the number of elements is almost always 1 or so, and 2) we do not care
+ * duplicate elements for our use case.</p>
+ *
+ * <p>This object must be accessed only from callback methods in {@link PackageMonitor},
+ * which should be bound to {@link #getRegisteredHandler()}.</p>
+ */
+ private final ArrayList<String> mChangedPackages = new ArrayList<>();
+
+ /**
+ * {@code true} if one or more packages that contain {@link InputMethodService} appeared.
+ *
+ * <p>This field must be accessed only from callback methods in {@link PackageMonitor},
+ * which should be bound to {@link #getRegisteredHandler()}.</p>
+ */
+ private boolean mImePackageAppeared = false;
@GuardedBy("mMethodMap")
- void clearPackagesToMonitorComponentChangeLocked() {
- mPackagesToMonitorComponentChange.clear();
+ void clearKnownImePackageNamesLocked() {
+ mKnownImePackageNames.clear();
}
@GuardedBy("mMethodMap")
- final void addPackageToMonitorComponentChangeLocked(@NonNull String packageName) {
- mPackagesToMonitorComponentChange.add(packageName);
+ final void addKnownImePackageNameLocked(@NonNull String packageName) {
+ mKnownImePackageNames.add(packageName);
}
@GuardedBy("mMethodMap")
@@ -943,19 +963,97 @@
}
@Override
- public boolean onPackageChanged(String packageName, int uid, String[] components) {
- // If this package is in the watch list, we want to check it.
- synchronized (mMethodMap) {
- return mPackagesToMonitorComponentChange.contains(packageName);
+ public void onBeginPackageChanges() {
+ clearPackageChangeState();
+ }
+
+ @Override
+ public void onPackageAppeared(String packageName, int reason) {
+ if (!mImePackageAppeared) {
+ final PackageManager pm = mContext.getPackageManager();
+ final List<ResolveInfo> services = pm.queryIntentServicesAsUser(
+ new Intent(InputMethod.SERVICE_INTERFACE).setPackage(packageName),
+ PackageManager.MATCH_DISABLED_COMPONENTS, getChangingUserId());
+ // No need to lock this because we access it only on getRegisteredHandler().
+ if (!services.isEmpty()) {
+ mImePackageAppeared = true;
+ }
+ }
+ // No need to lock this because we access it only on getRegisteredHandler().
+ mChangedPackages.add(packageName);
+ }
+
+ @Override
+ public void onPackageDisappeared(String packageName, int reason) {
+ // No need to lock this because we access it only on getRegisteredHandler().
+ mChangedPackages.add(packageName);
+ }
+
+ @Override
+ public void onPackageModified(String packageName) {
+ // No need to lock this because we access it only on getRegisteredHandler().
+ mChangedPackages.add(packageName);
+ }
+
+ @Override
+ public void onPackagesSuspended(String[] packages) {
+ // No need to lock this because we access it only on getRegisteredHandler().
+ for (String packageName : packages) {
+ mChangedPackages.add(packageName);
}
}
@Override
- public void onSomePackagesChanged() {
+ public void onPackagesUnsuspended(String[] packages) {
+ // No need to lock this because we access it only on getRegisteredHandler().
+ for (String packageName : packages) {
+ mChangedPackages.add(packageName);
+ }
+ }
+
+ @Override
+ public void onFinishPackageChanges() {
+ onFinishPackageChangesInternal();
+ clearPackageChangeState();
+ }
+
+ private void clearPackageChangeState() {
+ // No need to lock them because we access these fields only on getRegisteredHandler().
+ mChangedPackages.clear();
+ mImePackageAppeared = false;
+ }
+
+ private boolean shouldRebuildInputMethodListLocked() {
+ // This method is guaranteed to be called only by getRegisteredHandler().
+
+ // If there is any new package that contains at least one IME, then rebuilt the list
+ // of IMEs.
+ if (mImePackageAppeared) {
+ return true;
+ }
+
+ // Otherwise, check if mKnownImePackageNames and mChangedPackages have any intersection.
+ // TODO: Consider to create a utility method to do the following test. List.retainAll()
+ // is an option, but it may still do some extra operations that we do not need here.
+ final int N = mChangedPackages.size();
+ for (int i = 0; i < N; ++i) {
+ final String packageName = mChangedPackages.get(i);
+ if (mKnownImePackageNames.contains(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void onFinishPackageChangesInternal() {
synchronized (mMethodMap) {
if (!isChangingPackagesOfCurrentUserLocked()) {
return;
}
+ if (!shouldRebuildInputMethodListLocked()) {
+ return;
+ }
+
InputMethodInfo curIm = null;
String curInputMethodId = mSettings.getSelectedInputMethod();
final int N = mMethodList.size();
@@ -3283,7 +3381,7 @@
mMethodList.clear();
mMethodMap.clear();
mMethodMapUpdateCount++;
- mMyPackageMonitor.clearPackagesToMonitorComponentChangeLocked();
+ mMyPackageMonitor.clearKnownImePackageNamesLocked();
// Use for queryIntentServicesAsUser
final PackageManager pm = mContext.getPackageManager();
@@ -3339,10 +3437,9 @@
final int N = allInputMethodServices.size();
for (int i = 0; i < N; ++i) {
final ServiceInfo si = allInputMethodServices.get(i).serviceInfo;
- if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
- continue;
+ if (android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
+ mMyPackageMonitor.addKnownImePackageNameLocked(si.packageName);
}
- mMyPackageMonitor.addPackageToMonitorComponentChangeLocked(si.packageName);
}
}
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index cb13a3d..3f97d4f 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -16,7 +16,6 @@
package com.android.server;
-import android.annotation.NonNull;
import android.content.Context;
import android.os.Trace;
import android.util.Slog;
@@ -106,25 +105,22 @@
+ ": service constructor threw an exception", ex);
}
- startService(service);
+ // Register it.
+ mServices.add(service);
+
+ // Start it.
+ try {
+ service.onStart();
+ } catch (RuntimeException ex) {
+ throw new RuntimeException("Failed to start service " + name
+ + ": onStart threw an exception", ex);
+ }
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
- public void startService(@NonNull final SystemService service) {
- // Register it.
- mServices.add(service);
- // Start it.
- try {
- service.onStart();
- } catch (RuntimeException ex) {
- throw new RuntimeException("Failed to start service " + service.getClass().getName()
- + ": onStart threw an exception", ex);
- }
- }
-
/**
* Starts the specified boot phase for all system services that have been started up to
* this point.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7a3326b..30b267f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7694,7 +7694,7 @@
aspectRatio);
mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
bounds, true /* moveHomeStackToFront */);
- final ActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
+ final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
stack.setPictureInPictureAspectRatio(aspectRatio);
stack.setPictureInPictureActions(actions);
@@ -7748,9 +7748,9 @@
// Only update the saved args from the args that are set
r.pictureInPictureArgs.copyOnlySet(args);
- final ActivityStack stack = r.getStack();
- if (stack.getStackId() == PINNED_STACK_ID) {
+ if (r.getStack().getStackId() == PINNED_STACK_ID) {
// If the activity is already in picture-in-picture, update the pinned stack now
+ final PinnedActivityStack stack = r.getStack();
stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio());
stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
}
@@ -10312,7 +10312,7 @@
synchronized (this) {
if (animate) {
if (stackId == PINNED_STACK_ID) {
- final ActivityStack pinnedStack =
+ final PinnedActivityStack pinnedStack =
mStackSupervisor.getStack(PINNED_STACK_ID);
pinnedStack.animateResizePinnedStack(bounds, animationDuration);
} else {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 6f89cf2..aef429e 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -880,8 +880,8 @@
/**
* @return Stack value from current task, null if there is no task.
*/
- ActivityStack getStack() {
- return task != null ? task.getStack() : null;
+ <T extends ActivityStack> T getStack() {
+ return task != null ? (T) task.getStack() : null;
}
boolean changeWindowTranslucency(boolean toOpaque) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b948c15..7f7caff 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -84,7 +84,6 @@
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
-import android.app.RemoteAction;
import android.app.ResultInfo;
import android.content.ComponentName;
import android.content.Intent;
@@ -135,7 +134,8 @@
/**
* State and management of a single stack of activities.
*/
-final class ActivityStack extends ConfigurationContainer implements StackWindowListener {
+class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
+ implements StackWindowListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
@@ -247,7 +247,7 @@
final ActivityManagerService mService;
private final WindowManagerService mWindowManager;
- private StackWindowController mWindowContainerController;
+ T mWindowContainerController;
private final RecentTasks mRecentTasks;
/**
@@ -462,14 +462,18 @@
? new LaunchingTaskPositioner() : null;
final ActivityStackSupervisor.ActivityDisplay display = mActivityContainer.mActivityDisplay;
mTmpRect2.setEmpty();
- mWindowContainerController = new StackWindowController(mStackId, this,
- display.mDisplayId, onTop, mTmpRect2);
+ mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
+ mTmpRect2);
activityContainer.mStack = this;
mStackSupervisor.mActivityContainers.put(mStackId, activityContainer);
postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
}
- StackWindowController getWindowContainerController() {
+ T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
+ return (T) new StackWindowController(mStackId, this, displayId, onTop, outBounds);
+ }
+
+ T getWindowContainerController() {
return mWindowContainerController;
}
@@ -540,18 +544,6 @@
mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
}
- void animateResizePinnedStack(Rect bounds, int animationDuration) {
- mWindowContainerController.animateResizePinnedStack(bounds, animationDuration);
- }
-
- void setPictureInPictureAspectRatio(float aspectRatio) {
- mWindowContainerController.setPictureInPictureAspectRatio(aspectRatio);
- }
-
- void setPictureInPictureActions(List<RemoteAction> actions) {
- mWindowContainerController.setPictureInPictureActions(actions);
- }
-
void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds, Rect outTempInsetBounds,
boolean ignoreVisibility) {
mWindowContainerController.getStackDockedModeBounds(outBounds, outTempBounds,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7ceeff8..1e33bb9 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -120,7 +120,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
-import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
@@ -153,7 +152,6 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Slog;
@@ -2037,19 +2035,20 @@
|| mService.mSupportsFreeformWindowManagement;
}
- ActivityStack getStack(int stackId) {
+ protected <T extends ActivityStack> T getStack(int stackId) {
return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
}
- ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
+ protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded,
+ boolean createOnTop) {
final ActivityContainer activityContainer = mActivityContainers.get(stackId);
if (activityContainer != null) {
- return activityContainer.mStack;
+ return (T) activityContainer.mStack;
}
if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
return null;
}
- return createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
+ return (T) createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
}
/**
@@ -2856,7 +2855,7 @@
mWindowManager.deferSurfaceLayout();
// Need to make sure the pinned stack exist so we can resize it below...
- final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
+ final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
try {
final TaskRecord task = r.task;
@@ -2906,7 +2905,7 @@
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
- stack.animateResizePinnedStack(bounds, -1);
+ stack.animateResizePinnedStack(bounds, -1 /* animationDuration */);
mService.mTaskChangeNotificationController.notifyActivityPinned();
}
@@ -4367,7 +4366,14 @@
synchronized (mService) {
mStackId = stackId;
mActivityDisplay = activityDisplay;
- new ActivityStack(this, mRecentTasks, onTop);
+ switch (mStackId) {
+ case PINNED_STACK_ID:
+ new PinnedActivityStack(this, mRecentTasks, onTop);
+ break;
+ default:
+ new ActivityStack(this, mRecentTasks, onTop);
+ break;
+ }
mIdString = "ActivtyContainer{" + mStackId + "}";
if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
}
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
new file mode 100644
index 0000000..aa7ab15
--- /dev/null
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.RemoteAction;
+import android.graphics.Rect;
+
+import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
+import com.android.server.wm.PinnedStackWindowController;
+import com.android.server.wm.StackWindowController;
+
+import java.util.List;
+
+/**
+ * State and management of the pinned stack of activities.
+ */
+class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> {
+
+ PinnedActivityStack(ActivityContainer activityContainer,
+ RecentTasks recentTasks, boolean onTop) {
+ super(activityContainer, recentTasks, onTop);
+ }
+
+ @Override
+ PinnedStackWindowController createStackWindowController(int displayId, boolean onTop,
+ Rect outBounds) {
+ return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
+ }
+
+ void animateResizePinnedStack(Rect bounds, int animationDuration) {
+ getWindowContainerController().animateResizePinnedStack(bounds, animationDuration);
+ }
+
+ void setPictureInPictureAspectRatio(float aspectRatio) {
+ getWindowContainerController().setPictureInPictureAspectRatio(aspectRatio);
+ }
+
+ void setPictureInPictureActions(List<RemoteAction> actions) {
+ getWindowContainerController().setPictureInPictureActions(actions);
+ }
+}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 74e025d..5149933 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -149,13 +149,7 @@
}
private void handleBinderDiedLocked(IBinder appToken) {
- VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
- if (device != null) {
- Slog.i(TAG, "Virtual display device released because application token died: "
- + device.mOwnerPackageName);
- device.destroyLocked(false);
- sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
- }
+ mVirtualDisplayDevices.remove(appToken);
}
private void handleMediaProjectionStoppedLocked(IBinder appToken) {
@@ -216,6 +210,10 @@
public void binderDied() {
synchronized (getSyncRoot()) {
handleBinderDiedLocked(mAppToken);
+ Slog.i(TAG, "Virtual display device released because application token died: "
+ + mOwnerPackageName);
+ destroyLocked(false);
+ sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_REMOVED);
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 88e8ce6..cc709ce 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -664,38 +664,7 @@
}
private void updateAssets(final int userId, List<String> targetPackageNames) {
- final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
- final boolean updateFrameworkRes = targetPackageNames.contains("android");
- if (updateFrameworkRes) {
- targetPackageNames = pm.getTargetPackageNames(userId);
- }
-
- final Map<String, List<String>> pendingChanges = new ArrayMap<>(targetPackageNames.size());
- synchronized (mLock) {
- final int N = targetPackageNames.size();
- for (int i = 0; i < N; i++) {
- final String targetPackageName = targetPackageNames.get(i);
- pendingChanges.put(targetPackageName,
- mImpl.getEnabledOverlayPackageNames(targetPackageName, userId));
- }
- }
-
- final int N = targetPackageNames.size();
- for (int i = 0; i < N; i++) {
- final String targetPackageName = targetPackageNames.get(i);
- if (!pm.setEnabledOverlayPackages(
- userId, targetPackageName, pendingChanges.get(targetPackageName))) {
- Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
- targetPackageName, userId));
- }
- }
-
- final IActivityManager am = ActivityManagerNative.getDefault();
- try {
- am.scheduleApplicationInfoChanged(targetPackageNames, userId);
- } catch (RemoteException e) {
- // Intentionally left empty.
- }
+ // TODO: implement when we integrate OMS properly
}
private void schedulePersistSettings() {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 96a2577..c11131a 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -242,6 +242,12 @@
try {
UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
if (callingUserInfo.isManagedProfile()) {
+
+ // STOPSHIP Remove the whitelist.
+ if ("com.google.android.talk".equals(callingPackage)
+ || "com.google.android.quicksearchbox".equals(callingPackage)) {
+ return false;
+ }
Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile "
+ targetUserId + " from " + callingUserId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b6884b8..975ae06 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -661,12 +661,9 @@
final ArrayMap<String, Set<String>> mKnownCodebase =
new ArrayMap<String, Set<String>>();
- // List of APK paths to load for each user and package. This data is never
- // persisted by the package manager. Instead, the overlay manager will
- // ensure the data is up-to-date in runtime.
- @GuardedBy("mPackages")
- final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
- new SparseArray<ArrayMap<String, ArrayList<String>>>();
+ // Tracks available target package names -> overlay package paths.
+ final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
+ new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
/**
* Tracks new system packages [received in an OTA] that we expect to
@@ -3737,7 +3734,6 @@
ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
ps.readUserState(userId), userId);
if (ai != null) {
- rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
}
return ai;
@@ -3772,7 +3768,6 @@
ApplicationInfo ai = PackageParser.generateApplicationInfo(
p, flags, ps.readUserState(userId), userId);
if (ai != null) {
- rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(p);
}
return ai;
@@ -3789,26 +3784,6 @@
return null;
}
- private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
- List<String> paths = new ArrayList<>();
- ArrayMap<String, ArrayList<String>> userSpecificOverlays =
- mEnabledOverlayPaths.get(userId);
- if (userSpecificOverlays != null) {
- if (!"android".equals(ai.packageName)) {
- ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
- if (frameworkOverlays != null) {
- paths.addAll(frameworkOverlays);
- }
- }
-
- ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
- if (appOverlays != null) {
- paths.addAll(appOverlays);
- }
- }
- ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
- }
-
private String normalizePackageNameLPr(String packageName) {
String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
return normalizedPackageName != null ? normalizedPackageName : packageName;
@@ -7172,7 +7147,6 @@
ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
if (ai != null) {
- rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
}
} else {
@@ -7196,7 +7170,6 @@
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
- rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(p);
list.add(ai);
}
@@ -7340,7 +7313,6 @@
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
- rebaseEnabledOverlays(ai, userId);
finalList.add(ai);
}
}
@@ -7476,6 +7448,60 @@
return finalList;
}
+ private void createIdmapsForPackageLI(PackageParser.Package pkg) {
+ ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
+ if (overlays == null) {
+ Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
+ return;
+ }
+ for (PackageParser.Package opkg : overlays.values()) {
+ // Not much to do if idmap fails: we already logged the error
+ // and we certainly don't want to abort installation of pkg simply
+ // because an overlay didn't fit properly. For these reasons,
+ // ignore the return value of createIdmapForPackagePairLI.
+ createIdmapForPackagePairLI(pkg, opkg);
+ }
+ }
+
+ private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
+ PackageParser.Package opkg) {
+ if (!opkg.mTrustedOverlay) {
+ Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
+ opkg.baseCodePath + ": overlay not trusted");
+ return false;
+ }
+ ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
+ if (overlaySet == null) {
+ Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
+ opkg.baseCodePath + " but target package has no known overlays");
+ return false;
+ }
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ // TODO: generate idmap for split APKs
+ try {
+ mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
+ + opkg.baseCodePath);
+ return false;
+ }
+ PackageParser.Package[] overlayArray =
+ overlaySet.values().toArray(new PackageParser.Package[0]);
+ Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
+ public int compare(PackageParser.Package p1, PackageParser.Package p2) {
+ return p1.mOverlayPriority - p2.mOverlayPriority;
+ }
+ };
+ Arrays.sort(overlayArray, cmp);
+
+ pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
+ int i = 0;
+ for (PackageParser.Package p : overlayArray) {
+ pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
+ }
+ return true;
+ }
+
private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
try {
@@ -9964,6 +9990,7 @@
// writer
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
+ boolean createIdmapFailed = false;
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
@@ -10304,9 +10331,36 @@
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
}
+
+ // Create idmap files for pairs of (packages, overlay packages).
+ // Note: "android", ie framework-res.apk, is handled by native layers.
+ if (pkg.mOverlayTarget != null) {
+ // This is an overlay package.
+ if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
+ if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
+ mOverlays.put(pkg.mOverlayTarget,
+ new ArrayMap<String, PackageParser.Package>());
+ }
+ ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
+ map.put(pkg.packageName, pkg);
+ PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
+ if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
+ createIdmapFailed = true;
+ }
+ }
+ } else if (mOverlays.containsKey(pkg.packageName) &&
+ !pkg.packageName.equals("android")) {
+ // This is a regular package, with one or more known overlay packages.
+ createIdmapsForPackageLI(pkg);
+ }
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+ if (createIdmapFailed) {
+ throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
+ "scanPackageLI failed to createIdmap");
+ }
}
private static void maybeRenameForeignDexMarkers(PackageParser.Package existing,
@@ -20105,7 +20159,6 @@
public static final int DUMP_FROZEN = 1 << 19;
public static final int DUMP_DEXOPT = 1 << 20;
public static final int DUMP_COMPILER_STATS = 1 << 21;
- public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
public static final int OPTION_SHOW_FILTERS = 1 << 0;
@@ -20225,7 +20278,6 @@
pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
pw.println(" dexopt: dump dexopt state");
pw.println(" compiler-stats: dump compiler statistics");
- pw.println(" enabled-overlays: dump list of enabled overlay packages");
pw.println(" <package.name>: info about given package");
return;
} else if ("--checkin".equals(opt)) {
@@ -20354,8 +20406,6 @@
dumpState.setDump(DumpState.DUMP_DEXOPT);
} else if ("compiler-stats".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
- } else if ("enabled-overlays".equals(cmd)) {
- dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
} else if ("write".equals(cmd)) {
synchronized (mPackages) {
mSettings.writeLPr();
@@ -20726,11 +20776,6 @@
dumpCompilerStatsLPr(pw, packageName);
}
- if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
- if (dumpState.onTitlePrinted()) pw.println();
- dumpEnabledOverlaysLPr(pw);
- }
-
if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted()) pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
@@ -20827,23 +20872,6 @@
}
}
- private void dumpEnabledOverlaysLPr(PrintWriter pw) {
- pw.println("Enabled overlay paths:");
- final int N = mEnabledOverlayPaths.size();
- for (int i = 0; i < N; i++) {
- final int userId = mEnabledOverlayPaths.keyAt(i);
- pw.println(String.format(" User %d:", userId));
- final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
- mEnabledOverlayPaths.valueAt(i);
- final int M = userSpecificOverlays.size();
- for (int j = 0; j < M; j++) {
- final String targetPackageName = userSpecificOverlays.keyAt(j);
- final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
- pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths));
- }
- }
- }
-
private String dumpDomainString(String packageName) {
List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
.getList();
@@ -22947,43 +22975,10 @@
@Override
- public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
- @Nullable List<String> overlayPackageNames) {
- synchronized (mPackages) {
- if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
- Slog.e(TAG, "failed to find package " + targetPackageName);
- return false;
- }
-
- ArrayList<String> paths = null;
- if (overlayPackageNames != null) {
- final int N = overlayPackageNames.size();
- paths = new ArrayList<String>(N);
- for (int i = 0; i < N; i++) {
- final String packageName = overlayPackageNames.get(i);
- final PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null) {
- Slog.e(TAG, "failed to find package " + packageName);
- return false;
- }
- paths.add(pkg.baseCodePath);
- }
- }
-
- ArrayMap<String, ArrayList<String>> userSpecificOverlays =
- mEnabledOverlayPaths.get(userId);
- if (userSpecificOverlays == null) {
- userSpecificOverlays = new ArrayMap<String, ArrayList<String>>();
- mEnabledOverlayPaths.put(userId, userSpecificOverlays);
- }
-
- if (paths != null && paths.size() > 0) {
- userSpecificOverlays.put(targetPackageName, paths);
- } else {
- userSpecificOverlays.remove(targetPackageName);
- }
- return true;
- }
+ public boolean setEnabledOverlayPackages(int userId, String targetPackageName,
+ List<String> overlayPackageNames) {
+ // TODO: implement when we integrate OMS properly
+ return false;
}
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f7a9e41..b7479da 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -226,8 +226,8 @@
Matrix outMatrix) {
sTempFloats[Matrix.MSCALE_X] = windowState.mWinAnimator.mDsDx;
sTempFloats[Matrix.MSKEW_Y] = windowState.mWinAnimator.mDtDx;
- sTempFloats[Matrix.MSKEW_X] = windowState.mWinAnimator.mDsDy;
- sTempFloats[Matrix.MSCALE_Y] = windowState.mWinAnimator.mDtDy;
+ sTempFloats[Matrix.MSKEW_X] = windowState.mWinAnimator.mDtDy;
+ sTempFloats[Matrix.MSCALE_Y] = windowState.mWinAnimator.mDsDy;
sTempFloats[Matrix.MTRANS_X] = windowState.mShownPosition.x;
sTempFloats[Matrix.MTRANS_Y] = windowState.mShownPosition.y;
sTempFloats[Matrix.MPERSP_0] = 0;
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 01bd86d..837b69e 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -272,18 +272,10 @@
void onAnimationEnd();
void moveToFullscreen();
-
- void getFullScreenBounds(Rect bounds);
}
- void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration) {
- boolean moveToFullscreen = false;
- if (to == null) {
- to = new Rect();
- target.getFullScreenBounds(to);
- moveToFullscreen = true;
- }
-
+ void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration,
+ boolean moveToFullscreen) {
final BoundsAnimator existing = mRunningAnimations.get(target);
final boolean replacing = existing != null;
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index cfeb198..5f41187 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -230,28 +230,6 @@
}
/**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds) {
- return getMovementBounds(stackBounds, true /* adjustForIme */);
- }
-
- /**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
- final Rect movementBounds = new Rect();
- getInsetBounds(movementBounds);
-
- // Apply the movement bounds adjustments based on the current state
- mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
- (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
- return movementBounds;
- }
-
- /**
* @param preChangeTargetBounds The final bounds of the stack if it is currently animating
* @return the repositioned PIP bounds given it's pre-change bounds, and the new display
* content.
@@ -387,6 +365,28 @@
}
/**
+ * @return the movement bounds for the given {@param stackBounds} and the current state of the
+ * controller.
+ */
+ private Rect getMovementBounds(Rect stackBounds) {
+ return getMovementBounds(stackBounds, true /* adjustForIme */);
+ }
+
+ /**
+ * @return the movement bounds for the given {@param stackBounds} and the current state of the
+ * controller.
+ */
+ private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+ final Rect movementBounds = new Rect();
+ getInsetBounds(movementBounds);
+
+ // Apply the movement bounds adjustments based on the current state
+ mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
+ (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+ return movementBounds;
+ }
+
+ /**
* Applies the minimized offsets to the given stack bounds.
*/
private void applyMinimizedOffset(Rect stackBounds, Rect movementBounds) {
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
new file mode 100644
index 0000000..71f88de
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+
+import android.app.RemoteAction;
+import android.graphics.Rect;
+
+import com.android.server.UiThread;
+
+import java.util.List;
+
+/**
+ * Controller for the pinned stack container. See {@link StackWindowController}.
+ */
+public class PinnedStackWindowController extends StackWindowController {
+
+ private Rect mTmpBoundsRect = new Rect();
+
+ public PinnedStackWindowController(int stackId, StackWindowListener listener, int displayId,
+ boolean onTop, Rect outBounds) {
+ super(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
+ }
+
+ /**
+ * Animates the pinned stack.
+ */
+ public void animateResizePinnedStack(Rect bounds, int animationDuration) {
+ synchronized (mWindowMap) {
+ if (mContainer == null) {
+ throw new IllegalArgumentException("Pinned stack container not found :(");
+ }
+
+ // Get non-null fullscreen bounds if the bounds are null
+ final boolean moveToFullscreen = bounds == null;
+ bounds = getPinnedStackAnimationBounds(bounds);
+
+ // If the bounds are truly null, then there was no fullscreen stack at this time, so
+ // animate this to the full display bounds
+ final Rect toBounds;
+ if (bounds == null) {
+ toBounds = new Rect();
+ mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
+ } else {
+ toBounds = bounds;
+ }
+
+ final Rect originalBounds = new Rect();
+ mContainer.getBounds(originalBounds);
+ mContainer.setAnimatingBounds(toBounds);
+ UiThread.getHandler().post(() -> {
+ mService.mBoundsAnimationController.animateBounds(mContainer, originalBounds,
+ toBounds, animationDuration, moveToFullscreen);
+ });
+ }
+ }
+
+ /**
+ * Sets the current picture-in-picture aspect ratio.
+ */
+ public void setPictureInPictureAspectRatio(float aspectRatio) {
+ synchronized (mWindowMap) {
+ if (!mService.mSupportsPictureInPicture || mContainer == null) {
+ return;
+ }
+
+ final int displayId = mContainer.getDisplayContent().getDisplayId();
+ final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio);
+ final Rect targetBounds = new Rect();
+ mContainer.getAnimatingBounds(targetBounds);
+ if (!toBounds.equals(targetBounds)) {
+ animateResizePinnedStack(toBounds, -1 /* duration */);
+ }
+
+ final PinnedStackController pinnedStackController =
+ mContainer.getDisplayContent().getPinnedStackController();
+ pinnedStackController.setAspectRatio(
+ pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
+ ? aspectRatio : -1f);
+ }
+ }
+
+ /**
+ * Sets the current picture-in-picture actions.
+ */
+ public void setPictureInPictureActions(List<RemoteAction> actions) {
+ synchronized (mWindowMap) {
+ if (!mService.mSupportsPictureInPicture || mContainer == null) {
+ return;
+ }
+
+ mContainer.getDisplayContent().getPinnedStackController().setActions(actions);
+ }
+ }
+
+ /**
+ * Checks the {@param bounds} and retirms non-null fullscreen bounds for the pinned stack
+ * animation if necessary.
+ */
+ private Rect getPinnedStackAnimationBounds(Rect bounds) {
+ mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
+ if (bounds == null && !mTmpBoundsRect.isEmpty()) {
+ bounds = new Rect(mTmpBoundsRect);
+ }
+ return bounds;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 142f69a..b0e115b 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -199,59 +199,6 @@
}
}
- // TODO: This and similar methods should be separated into PinnedStackWindowContainerController
- public void animateResizePinnedStack(final Rect bounds, final int animationDuration) {
- synchronized (mWindowMap) {
- if (mContainer == null) {
- throw new IllegalArgumentException("Pinned stack container not found :(");
- }
- final Rect originalBounds = new Rect();
- mContainer.getBounds(originalBounds);
- mContainer.setAnimatingBounds(bounds);
- UiThread.getHandler().post(new Runnable() {
- @Override
- public void run() {
- mService.mBoundsAnimationController.animateBounds(
- mContainer, originalBounds, bounds, animationDuration);
- }
- });
- }
- }
-
- /** Sets the current picture-in-picture aspect ratio. */
- public void setPictureInPictureAspectRatio(float aspectRatio) {
- synchronized (mWindowMap) {
- if (!mService.mSupportsPictureInPicture || mContainer == null) {
- return;
- }
-
- final int displayId = mContainer.getDisplayContent().getDisplayId();
- final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio);
- final Rect targetBounds = new Rect();
- mContainer.getAnimatingBounds(targetBounds);
- if (!toBounds.equals(targetBounds)) {
- animateResizePinnedStack(toBounds, -1 /* duration */);
- }
-
- final PinnedStackController pinnedStackController =
- mContainer.getDisplayContent().getPinnedStackController();
- pinnedStackController.setAspectRatio(
- pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
- ? aspectRatio : -1f);
- }
- }
-
- /** Sets the current picture-in-picture actions. */
- public void setPictureInPictureActions(List<RemoteAction> actions) {
- synchronized (mWindowMap) {
- if (!mService.mSupportsPictureInPicture || mContainer == null) {
- return;
- }
-
- mContainer.getDisplayContent().getPinnedStackController().setActions(actions);
- }
- }
-
public void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds,
Rect outTempInsetBounds, boolean ignoreVisibility) {
synchronized (mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 5f8b694..c7532ac 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
@@ -1476,14 +1477,6 @@
}
}
- @Override
- public void getFullScreenBounds(Rect bounds) {
- // This is currently only used for the pinned stack animation when leaving PiP
- // (see {@link BoundsAnimationController}), and in that case we need to animate this back
- // to the full bounds to match the fullscreen stack
- getDisplayContent().getLogicalDisplayRect(bounds);
- }
-
public boolean hasMovementAnimations() {
return StackId.hasMovementAnimations(mStackId);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9397c9e..474610b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7267,10 +7267,6 @@
return mRoot.getDisplayContentOrCreate(DEFAULT_DISPLAY);
}
- private DisplayInfo getDefaultDisplayInfoLocked() {
- return getDefaultDisplayContentLocked().getDisplayInfo();
- }
-
public void onDisplayAdded(int displayId) {
mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c0929cb..98598e1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -172,7 +172,7 @@
private boolean mAnimateMove = false;
float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
- float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
+ private float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
boolean mHaveMatrix;
@@ -945,8 +945,8 @@
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
- mDsDy = tmpFloats[Matrix.MSKEW_X];
- mDtDy = tmpFloats[Matrix.MSCALE_Y];
+ mDtDy = tmpFloats[Matrix.MSKEW_X];
+ mDsDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
mWin.mShownPosition.set(Math.round(x), Math.round(y));
@@ -959,7 +959,7 @@
mShownAlpha = mAlpha;
if (!mService.mLimitedAlphaCompositing
|| (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
- || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
+ || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)
&& x == frame.left && y == frame.top))) {
//Slog.i(TAG_WM, "Applying alpha transform");
if (selfTransformation) {
@@ -1038,8 +1038,8 @@
mHaveMatrix = true;
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
- mDsDy = tmpFloats[Matrix.MSKEW_X];
- mDtDy = tmpFloats[Matrix.MSCALE_Y];
+ mDtDy = tmpFloats[Matrix.MSKEW_X];
+ mDsDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
mWin.mShownPosition.set(Math.round(x), Math.round(y));
@@ -1054,8 +1054,8 @@
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale;
mDtDx = 0;
- mDsDy = 0;
- mDtDy = mWin.mGlobalScale;
+ mDtDy = 0;
+ mDsDy = mWin.mGlobalScale;
}
}
@@ -1384,8 +1384,8 @@
applyCrop(clipRect, finalClipRect, recoveringMemory);
mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
mDtDx * w.mVScale * mExtraVScale,
- mDsDy * w.mHScale * mExtraHScale,
- mDtDy * w.mVScale * mExtraVScale, recoveringMemory);
+ mDtDy * w.mHScale * mExtraHScale,
+ mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
}
if (mSurfaceResized) {
@@ -1467,15 +1467,15 @@
"alpha=" + mShownAlpha + " layer=" + mAnimLayer
+ " matrix=[" + mDsDx + "*" + w.mHScale
+ "," + mDtDx + "*" + w.mVScale
- + "][" + mDsDy + "*" + w.mHScale
- + "," + mDtDy + "*" + w.mVScale + "]", false);
+ + "][" + mDtDy + "*" + w.mHScale
+ + "," + mDsDy + "*" + w.mVScale + "]", false);
boolean prepared =
mSurfaceController.prepareToShowInTransaction(mShownAlpha, mAnimLayer,
mDsDx * w.mHScale * mExtraHScale,
mDtDx * w.mVScale * mExtraVScale,
- mDsDy * w.mHScale * mExtraHScale,
- mDtDy * w.mVScale * mExtraVScale,
+ mDtDy * w.mHScale * mExtraHScale,
+ mDsDy * w.mVScale * mExtraVScale,
recoveringMemory);
if (prepared && mLastHidden && mDrawState == HAS_DRAWN) {
@@ -1777,8 +1777,8 @@
pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
pw.print(" mDsDx="); pw.print(mDsDx);
pw.print(" mDtDx="); pw.print(mDtDx);
- pw.print(" mDsDy="); pw.print(mDsDy);
- pw.print(" mDtDy="); pw.println(mDtDy);
+ pw.print(" mDtDy="); pw.print(mDtDy);
+ pw.print(" mDsDy="); pw.println(mDsDy);
}
if (mAnimationStartDelayed) {
pw.print(prefix); pw.print("mAnimationStartDelayed="); pw.print(mAnimationStartDelayed);
@@ -1926,15 +1926,15 @@
float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
- float DsDy = mService.mTmpFloats[Matrix.MSKEW_X];
- float DtDy = mService.mTmpFloats[Matrix.MSCALE_Y];
+ float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
+ float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
float nx = mService.mTmpFloats[Matrix.MTRANS_X];
float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
mSurfaceController.setPositionInTransaction(nx, ny, false);
mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
DtDx * w.mVScale,
- DsDy * w.mHScale,
- DtDy * w.mVScale, false);
+ DtDy * w.mHScale,
+ DsDy * w.mVScale, false);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e586482..a5f1945 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -82,7 +82,6 @@
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.notification.NotificationManagerService;
-import com.android.server.om.OverlayManagerService;
import com.android.server.os.DeviceIdentifiersPolicyService;
import com.android.server.os.SchedulingPolicyService;
import com.android.server.pm.Installer;
@@ -593,11 +592,6 @@
mActivityManagerService.setSystemProcess();
traceEnd();
- // Manages Overlay packages
- traceBeginAndSlog("StartOverlayManagerService");
- mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
- traceEnd();
-
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 28596f7..384f49f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -197,6 +197,7 @@
assertEquals(a.installLocation, b.installLocation);
assertEquals(a.coreApp, b.coreApp);
assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
+ assertEquals(a.mOverlayPriority, b.mOverlayPriority);
assertEquals(a.mTrustedOverlay, b.mTrustedOverlay);
assertEquals(a.use32bitAbi, b.use32bitAbi);
assertEquals(a.packageName, b.packageName);
@@ -432,6 +433,7 @@
pkg.installLocation = 100;
pkg.coreApp = true;
pkg.mRequiredForAllUsers = true;
+ pkg.mOverlayPriority = 100;
pkg.mTrustedOverlay = true;
pkg.use32bitAbi = true;
pkg.packageName = "foo";
diff --git a/test-runner/src/android/test/suitebuilder/TestMethod.java b/test-runner/src/android/test/suitebuilder/TestMethod.java
index 08568d5..ae1db5e 100644
--- a/test-runner/src/android/test/suitebuilder/TestMethod.java
+++ b/test-runner/src/android/test/suitebuilder/TestMethod.java
@@ -26,7 +26,11 @@
/**
* Represents a test to be run. Can be constructed without instantiating the TestCase or even
* loading the class.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
+@Deprecated
public class TestMethod {
private final String enclosingClassname;
diff --git a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
index 8c89489..3b920cf 100644
--- a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
+++ b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
@@ -38,7 +38,11 @@
/**
* Build suites based on a combination of included packages, excluded packages,
* and predicates that must be satisfied.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
+@Deprecated
public class TestSuiteBuilder {
private Context context;
@@ -223,7 +227,11 @@
/**
* A special {@link junit.framework.TestCase} used to indicate a failure during the build()
* step.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
+ @Deprecated
public static class FailedToCreateTests extends TestCase {
private final Exception exception;
diff --git a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java b/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
index e201012..c5965e8 100644
--- a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
+++ b/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
@@ -17,101 +17,59 @@
package com.android.server.connectivity;
import android.net.ConnectivityMetricsEvent;
-import android.net.ConnectivityMetricsLogger;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.function.Consumer;
+
abstract public class MetricsTestUtil {
private MetricsTestUtil() {
}
- static ConnectivityMetricsEvent ipEv(Parcelable p) {
- return ev(ConnectivityMetricsLogger.COMPONENT_TAG_CONNECTIVITY, p);
+ static ConnectivityMetricsEvent ev(Parcelable p) {
+ return new ConnectivityMetricsEvent(1L, 0, 0, p);
}
- static ConnectivityMetricsEvent telephonyEv() {
- return ev(ConnectivityMetricsLogger.COMPONENT_TAG_TELEPHONY, new Bundle());
- }
-
- static ConnectivityMetricsEvent ev(int tag, Parcelable p) {
- return new ConnectivityMetricsEvent(1L, tag, 0, p);
- }
-
- // Utiliy interface for describing the content of a Parcel. This relies on
- // the implementation defails of Parcelable and on the fact that the fully
- // qualified Parcelable class names are written as string in the Parcels.
- interface ParcelField {
- void write(Parcel p);
- }
-
- static ConnectivityMetricsEvent describeIpEvent(ParcelField... fs) {
+ static ConnectivityMetricsEvent describeIpEvent(Consumer<Parcel>... fs) {
Parcel p = Parcel.obtain();
- for (ParcelField f : fs) {
- f.write(p);
+ for (Consumer<Parcel> f : fs) {
+ f.accept(p);
}
p.setDataPosition(0);
- return ipEv(p.readParcelable(ClassLoader.getSystemClassLoader()));
+ return ev(p.readParcelable(ClassLoader.getSystemClassLoader()));
}
- static ParcelField aType(Class<?> c) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeString(c.getName());
- }
- };
+ static Consumer<Parcel> aType(Class<?> c) {
+ return aString(c.getName());
}
- static ParcelField aBool(boolean b) {
+ static Consumer<Parcel> aBool(boolean b) {
return aByte((byte) (b ? 1 : 0));
}
- static ParcelField aByte(byte b) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeByte(b);
- }
- };
+ static Consumer<Parcel> aByte(byte b) {
+ return (p) -> p.writeByte(b);
}
- static ParcelField anInt(int i) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeInt(i);
- }
- };
+ static Consumer<Parcel> anInt(int i) {
+ return (p) -> p.writeInt(i);
}
- static ParcelField aLong(long l) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeLong(l);
- }
- };
+ static Consumer<Parcel> aLong(long l) {
+ return (p) -> p.writeLong(l);
}
- static ParcelField aString(String s) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeString(s);
- }
- };
+ static Consumer<Parcel> aString(String s) {
+ return (p) -> p.writeString(s);
}
- static ParcelField aByteArray(byte... ary) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeByteArray(ary);
- }
- };
+ static Consumer<Parcel> aByteArray(byte... ary) {
+ return (p) -> p.writeByteArray(ary);
}
- static ParcelField anIntArray(int... ary) {
- return new ParcelField() {
- public void write(Parcel p) {
- p.writeIntArray(ary);
- }
- };
+ static Consumer<Parcel> anIntArray(int... ary) {
+ return (p) -> p.writeIntArray(ary);
}
static byte b(int i) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 3d5d5c6..df3ce19 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -640,6 +640,10 @@
return AccessibilityManager.getInstance(this);
}
+ if (AUTO_FILL_MANAGER_SERVICE.equals(service)) {
+ return null;
+ }
+
throw new UnsupportedOperationException("Unsupported Service: " + service);
}