Merge "Fix oom_adj range"
diff --git a/api/current.txt b/api/current.txt
index 8147ad5..6c4bd1b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11461,7 +11461,7 @@
method public int getSessionId();
method public long getSize();
method public int getStagedSessionErrorCode();
- method public String getStagedSessionErrorMessage();
+ method @NonNull public String getStagedSessionErrorMessage();
method public android.os.UserHandle getUser();
method public boolean isActive();
method public boolean isMultiPackage();
@@ -23492,7 +23492,7 @@
public static final class AudioRecord.MetricsConstants {
field public static final String CHANNELS = "android.media.audiorecord.channels";
field public static final String ENCODING = "android.media.audiorecord.encoding";
- field public static final String LATENCY = "android.media.audiorecord.latency";
+ field @Deprecated public static final String LATENCY = "android.media.audiorecord.latency";
field public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
field public static final String SOURCE = "android.media.audiorecord.source";
}
@@ -23656,9 +23656,9 @@
}
public static final class AudioTrack.MetricsConstants {
- field public static final String CHANNELMASK = "android.media.audiorecord.channelmask";
+ field @Deprecated public static final String CHANNELMASK = "android.media.audiorecord.channelmask";
field public static final String CONTENTTYPE = "android.media.audiotrack.type";
- field public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
+ field @Deprecated public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
field public static final String STREAMTYPE = "android.media.audiotrack.streamtype";
field public static final String USAGE = "android.media.audiotrack.usage";
}
@@ -30806,7 +30806,6 @@
}
public final class NfcAdapter {
- method public boolean deviceSupportsNfcSecure();
method public void disableForegroundDispatch(android.app.Activity);
method @Deprecated public void disableForegroundNdefPush(android.app.Activity);
method public void disableReaderMode(android.app.Activity);
@@ -30819,7 +30818,8 @@
method @Deprecated public boolean invokeBeam(android.app.Activity);
method public boolean isEnabled();
method @Deprecated public boolean isNdefPushEnabled();
- method public boolean isNfcSecureEnabled();
+ method public boolean isSecureNfcEnabled();
+ method public boolean isSecureNfcSupported();
method @Deprecated public void setBeamPushUris(android.net.Uri[], android.app.Activity);
method @Deprecated public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
method @Deprecated public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
@@ -35118,6 +35118,8 @@
}
public final class PowerManager {
+ method public void addThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
+ method public void addThermalStatusListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.PowerManager.OnThermalStatusChangedListener);
method public int getCurrentThermalStatus();
method public int getLocationPowerSaveMode();
method public boolean isDeviceIdleMode();
@@ -35129,8 +35131,7 @@
method public boolean isWakeLockLevelSupported(int);
method public android.os.PowerManager.WakeLock newWakeLock(int, String);
method public void reboot(String);
- method public void registerThermalStatusCallback(@NonNull android.os.PowerManager.ThermalStatusCallback, @NonNull java.util.concurrent.Executor);
- method public void unregisterThermalStatusCallback(@NonNull android.os.PowerManager.ThermalStatusCallback);
+ method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
field public static final String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED";
@@ -35155,9 +35156,8 @@
field public static final int THERMAL_STATUS_SHUTDOWN = 6; // 0x6
}
- public abstract static class PowerManager.ThermalStatusCallback {
- ctor public PowerManager.ThermalStatusCallback();
- method public void onStatusChange(int);
+ public static interface PowerManager.OnThermalStatusChangedListener {
+ method public void onThermalStatusChanged(int);
}
public final class PowerManager.WakeLock {
diff --git a/api/removed.txt b/api/removed.txt
index 7a06803..93d06928 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -335,11 +335,17 @@
package android.net {
public class ConnectivityManager {
+ method @Deprecated public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
method @Deprecated public boolean requestRouteToHost(int, int);
method @Deprecated public int startUsingNetworkFeature(int, String);
method @Deprecated public int stopUsingNetworkFeature(int, String);
}
+ @Deprecated public abstract static class ConnectivityManager.TetheringEntitlementValueListener {
+ ctor public ConnectivityManager.TetheringEntitlementValueListener();
+ method public void onEntitlementResult(int);
+ }
+
@Deprecated public class NetworkBadging {
method @NonNull public static android.graphics.drawable.Drawable getWifiIcon(@IntRange(from=0, to=4) int, int, @Nullable android.content.res.Resources.Theme);
field public static final int BADGING_4K = 30; // 0x1e
diff --git a/api/system-current.txt b/api/system-current.txt
index 42486b8..805bfb5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4034,7 +4034,7 @@
method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
method public boolean getAvoidBadWifi();
method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl();
- method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementValue(int, boolean, @NonNull android.net.ConnectivityManager.TetheringEntitlementValueListener, @Nullable android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean);
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.net.Network, android.os.Bundle);
@@ -4057,8 +4057,7 @@
method public void onTetheringStarted();
}
- public abstract static class ConnectivityManager.TetheringEntitlementValueListener {
- ctor public ConnectivityManager.TetheringEntitlementValueListener();
+ public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
method public void onEntitlementResult(int);
}
@@ -5085,9 +5084,9 @@
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setNfcSecure(boolean);
field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
}
@@ -6447,7 +6446,6 @@
method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
method public void onDisconnected();
method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
- method @Deprecated public final void setContentCaptureWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
}
@@ -9501,7 +9499,6 @@
package android.view.autofill {
public final class AutofillManager {
- method @Deprecated public void setAugmentedAutofillWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
method public void setAugmentedAutofillWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 3b02954..26c21d3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2307,7 +2307,6 @@
method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
method public void onDisconnected();
method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
- method @Deprecated public final void setContentCaptureWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
}
@@ -2935,7 +2934,6 @@
}
public final class AutofillManager {
- method @Deprecated public void setAugmentedAutofillWhitelist(@Nullable java.util.List<java.lang.String>, @Nullable java.util.List<android.content.ComponentName>);
method public void setAugmentedAutofillWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index a1341fb..f4c3e9c 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -287,11 +287,20 @@
bool CheckOverlayable(const LoadedPackage& target_package,
const utils::OverlayManifestInfo& overlay_info,
const PolicyBitmask& fulfilled_policies, const ResourceId& resid) {
+ static constexpr const PolicyBitmask sDefaultPolicies =
+ PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION |
+ PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE;
+
+ // If the resource does not have an overlayable definition, allow the resource to be overlaid if
+ // the overlay is preinstalled or signed with the same signature as the target.
+ if (!target_package.DefinesOverlayable()) {
+ return (sDefaultPolicies & fulfilled_policies) != 0;
+ }
+
const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid);
if (overlayable_info == nullptr) {
- // If the resource does not have an overlayable definition, allow the resource to be overlaid.
- // Once overlayable enforcement is turned on, this check will return false.
- return !target_package.DefinesOverlayable();
+ // Do not allow non-overlayable resources to be overlaid.
+ return false;
}
if (overlay_info.target_name != overlayable_info->name) {
@@ -427,6 +436,12 @@
matching_resources.Add(target_resid, overlay_resid);
}
+ if (matching_resources.Map().empty()) {
+ out_error << "overlay \"" << overlay_apk_path << "\" does not successfully overlay any resource"
+ << std::endl;
+ return nullptr;
+ }
+
// encode idmap data
std::unique_ptr<IdmapData> data(new IdmapData());
const auto types_end = matching_resources.Map().cend();
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index bbfbad9..8d65428 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -173,20 +173,27 @@
ASSERT_THAT(idmap, IsNull());
}
-TEST(IdmapTests, CreateIdmapFromApkAssets) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
+void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_apk_path,
+ const PolicyBitmask& fulfilled_policies, bool enforce_overlayable,
+ std::unique_ptr<const Idmap>* out_idmap) {
+ std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path.to_string());
ASSERT_THAT(target_apk, NotNull());
- const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
+ std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path.to_string());
ASSERT_THAT(overlay_apk, NotNull());
std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
- ASSERT_THAT(idmap, NotNull());
+ *out_idmap =
+ Idmap::FromApkAssets(target_apk_path.to_string(), *target_apk, overlay_apk_path.to_string(),
+ *overlay_apk, fulfilled_policies, enforce_overlayable, error);
+}
+
+TEST(IdmapTests, CreateIdmapFromApkAssets) {
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
+ std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ true, &idmap);
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
@@ -226,19 +233,12 @@
// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() + "/system-overlay/system-overlay.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
- /* enforce_overlayable */ true, error);
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
+ std::string overlay_apk_path = GetTestDataPath() + "/system-overlay/system-overlay.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path,
+ PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ true, &idmap);
ASSERT_THAT(idmap, NotNull());
const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
@@ -263,21 +263,12 @@
}
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() +
- "/signature-overlay/signature-overlay.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE;
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- policy_flags, /* enforce_overlayable */ true, error);
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
+ std::string overlay_apk_path = GetTestDataPath() + "/signature-overlay/signature-overlay.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path,
+ PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE,
+ /* enforce_overlayable */ true, &idmap);
ASSERT_THAT(idmap, NotNull());
const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
@@ -298,52 +289,15 @@
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
}
-TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() +
- "/signature-overlay/signature-overlay.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC;
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- policy_flags, /* enforce_overlayable */ true, error);
- ASSERT_THAT(idmap, NotNull());
-
- const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
- ASSERT_EQ(dataBlocks.size(), 1U);
-
- const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
-
- ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
- ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U);
-
- const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
- ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing
-}
-
// Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled.
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() +
- "/system-overlay-invalid/system-overlay-invalid.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
- /* enforce_overlayable */ true, error);
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
+ std::string overlay_apk_path =
+ GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path,
+ PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ true, &idmap);
ASSERT_THAT(idmap, NotNull());
const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
@@ -369,20 +323,13 @@
// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() +
- "/system-overlay-invalid/system-overlay-invalid.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
- /* enforce_overlayable */ false, error);
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
+ std::string overlay_apk_path =
+ GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path,
+ PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ false, &idmap);
ASSERT_THAT(idmap, NotNull());
const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
@@ -409,63 +356,13 @@
ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
}
-// The resources of APKs that do not include an overlayable declaration should not restrict what
-// resources can be overlaid.
-TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() +
- "/system-overlay-invalid/system-overlay-invalid.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
- ASSERT_THAT(idmap, NotNull());
-
- const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
- ASSERT_EQ(dataBlocks.size(), 1U);
-
- const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
-
- ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
- ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
-
- const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
- ASSERT_EQ(types.size(), 1U);
-
- ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
- ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
- ASSERT_EQ(types[0]->GetEntryCount(), 7U);
- ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
- ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
- ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
- ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
- ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
- ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature
- ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system
- ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
-}
-
-// The resources of APKs that do not include an overlayable declaration should not restrict what
-// resources can be overlaid.
+// Overlays that do not specify a target <overlayable> can overlay resources defined as overlayable.
TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
- const std::string target_apk_path(GetTestDataPath() + "/target/target-no-overlayable.apk");
- std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
- ASSERT_THAT(target_apk, NotNull());
-
- const std::string overlay_apk_path(GetTestDataPath() + "/overlay/overlay-no-name.apk");
- std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
- ASSERT_THAT(overlay_apk, NotNull());
-
- std::stringstream error;
- std::unique_ptr<const Idmap> idmap =
- Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk,
- PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error);
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
+ std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ false, &idmap);
ASSERT_THAT(idmap, NotNull());
const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
@@ -483,16 +380,81 @@
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
ASSERT_EQ(types[0]->GetEntryCount(), 1U);
ASSERT_EQ(types[0]->GetEntryOffset(), 0U);
- ASSERT_EQ(types[0]->GetEntry(0), 0x0000U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/int1
ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetEntryCount(), 4U);
ASSERT_EQ(types[1]->GetEntryOffset(), 10U);
- ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
- ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
- ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
- ASSERT_EQ(types[1]->GetEntry(3), 0x0002U);
+ ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); // string/str1
+ ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); // string/str2
+ ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); // string/str3
+ ASSERT_EQ(types[1]->GetEntry(3), 0x0002U); // string/str4
+}
+
+// Overlays that are not pre-installed and are not signed with the same signature as the target
+// cannot overlay packages that have not defined overlayable resources.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPoliciesPublicFail) {
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
+ std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-no-name.apk";
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PUBLIC,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, IsNull());
+}
+
+// Overlays that are pre-installed or are signed with the same signature as the target can overlay
+// packages that have not defined overlayable resources.
+TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsDefaultPolicies) {
+ std::unique_ptr<const Idmap> idmap;
+ std::string target_apk_path = GetTestDataPath() + "/target/target-no-overlayable.apk";
+ std::string overlay_apk_path =
+ GetTestDataPath() + "/system-overlay-invalid/system-overlay-invalid.apk";
+
+ auto CheckEntries = [&]() -> void {
+ const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
+ ASSERT_EQ(dataBlocks.size(), 1U);
+
+ const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
+
+ ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU);
+ ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U);
+
+ const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries();
+ ASSERT_EQ(types.size(), 1U);
+
+ ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
+ ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 7U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 3U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature
+ ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
+ };
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SIGNATURE,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_PRODUCT_PARTITION,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SYSTEM_PARTITION,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_VENDOR_PARTITION,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
}
TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build
index e879f44..68b9f50 100755
--- a/cmds/idmap2/tests/data/overlay/build
+++ b/cmds/idmap2/tests/data/overlay/build
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FRAMEWORK_RES_APK="${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk"
+FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar
aapt2 compile --dir res -o compiled.flata
diff --git a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
index 7d23c09..6425190 100644
--- a/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
+++ b/cmds/idmap2/tests/data/overlay/overlay-no-name.apk
Binary files differ
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index b20cce9..7de8105 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -2130,7 +2130,7 @@
* Text description of the error code returned by {@code getStagedSessionErrorCode}, or
* empty string if no error was encountered.
*/
- public String getStagedSessionErrorMessage() {
+ public @NonNull String getStagedSessionErrorMessage() {
checkSessionIsStaged();
return mStagedSessionErrorMessage;
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 1312f18..0497f8c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2681,12 +2681,39 @@
}
}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ TETHER_ERROR_NO_ERROR,
+ TETHER_ERROR_PROVISION_FAILED,
+ TETHER_ERROR_ENTITLEMENT_UNKONWN,
+ })
+ public @interface EntitlementResultCode {
+ }
+
/**
- * Callback for use with {@link #getLatestTetheringEntitlementValue} to find out whether
+ * Callback for use with {@link #getLatestTetheringEntitlementResult} to find out whether
* entitlement succeeded.
* @hide
*/
@SystemApi
+ public interface OnTetheringEntitlementResultListener {
+ /**
+ * Called to notify entitlement result.
+ *
+ * @param resultCode an int value of entitlement result. It may be one of
+ * {@link #TETHER_ERROR_NO_ERROR},
+ * {@link #TETHER_ERROR_PROVISION_FAILED}, or
+ * {@link #TETHER_ERROR_ENTITLEMENT_UNKONWN}.
+ */
+ void onEntitlementResult(@EntitlementResultCode int resultCode);
+ }
+
+ /**
+ * @removed
+ * @deprecated This API would be removed when all of caller has been updated.
+ * */
+ @Deprecated
public abstract static class TetheringEntitlementValueListener {
/**
* Called to notify entitlement result.
@@ -2712,14 +2739,43 @@
* {@link #TETHERING_USB}, or
* {@link #TETHERING_BLUETOOTH}.
* @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check.
- * @param listener an {@link TetheringEntitlementValueListener} which will be called to notify
- * the caller of the result of entitlement check. The listener may be called zero or
- * one time.
- * @param handler {@link Handler} to specify the thread upon which the listener will be invoked.
+ * @param executor the executor on which callback will be invoked.
+ * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to
+ * notify the caller of the result of entitlement check. The listener may be called zero
+ * or one time.
* {@hide}
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
+ public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull final OnTetheringEntitlementResultListener listener) {
+ Preconditions.checkNotNull(listener, "TetheringEntitlementResultListener cannot be null.");
+ ResultReceiver wrappedListener = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() -> {
+ listener.onEntitlementResult(resultCode);
+ }));
+ }
+ };
+
+ try {
+ String pkgName = mContext.getOpPackageName();
+ Log.i(TAG, "getLatestTetheringEntitlementResult:" + pkgName);
+ mService.getLatestTetheringEntitlementResult(type, wrappedListener,
+ showEntitlementUi, pkgName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @removed
+ * @deprecated This API would be removed when all of caller has been updated.
+ * */
+ @Deprecated
public void getLatestTetheringEntitlementValue(int type, boolean showEntitlementUi,
@NonNull final TetheringEntitlementValueListener listener, @Nullable Handler handler) {
Preconditions.checkNotNull(listener, "TetheringEntitlementValueListener cannot be null.");
@@ -2733,7 +2789,7 @@
try {
String pkgName = mContext.getOpPackageName();
Log.i(TAG, "getLatestTetheringEntitlementValue:" + pkgName);
- mService.getLatestTetheringEntitlementValue(type, wrappedListener,
+ mService.getLatestTetheringEntitlementResult(type, wrappedListener,
showEntitlementUi, pkgName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 6728712..fd44fc8 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -212,6 +212,6 @@
boolean isCallerCurrentAlwaysOnVpnApp();
boolean isCallerCurrentAlwaysOnVpnLockdownApp();
- void getLatestTetheringEntitlementValue(int type, in ResultReceiver receiver,
+ void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
boolean showEntitlementUi, String callerPkg);
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index a7d2ee9..8970c62 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -1704,11 +1704,12 @@
/**
* Sets Secure NFC feature.
* <p>This API is for the Settings application.
+ * @return True if successful
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean setNfcSecure(boolean enable) {
+ public boolean enableSecureNfc(boolean enable) {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
@@ -1726,7 +1727,7 @@
* @return True if device supports Secure NFC, false otherwise
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
*/
- public boolean deviceSupportsNfcSecure() {
+ public boolean isSecureNfcSupported() {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
@@ -1741,12 +1742,12 @@
/**
* Checks Secure NFC feature is enabled.
*
- * @return True if device supports Secure NFC is enabled, false otherwise
+ * @return True if Secure NFC is enabled, false otherwise
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
* @throws UnsupportedOperationException if device doesn't support
- * Secure NFC functionality. {@link #deviceSupportsNfcSecure}
+ * Secure NFC functionality. {@link #isSecureNfcSupported}
*/
- public boolean isNfcSecureEnabled() {
+ public boolean isSecureNfcEnabled() {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index c906d33..728b215 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -809,7 +809,8 @@
final Handler mHandler;
IThermalService mThermalService;
- private ArrayMap<ThermalStatusCallback, IThermalStatusListener> mCallbackMap = new ArrayMap<>();
+ private final ArrayMap<OnThermalStatusChangedListener, IThermalStatusListener>
+ mListenerMap = new ArrayMap<>();
IDeviceIdleController mIDeviceIdleController;
@@ -1769,51 +1770,73 @@
}
/**
- * Callback passed to
- * {@link PowerManager#registerThermalStatusCallback} and
- * {@link PowerManager#unregisterThermalStatusCallback}
- * to notify caller of thermal status.
+ * Listener passed to
+ * {@link PowerManager#addThermalStatusListener} and
+ * {@link PowerManager#removeThermalStatusListener}
+ * to notify caller of thermal status has changed.
*/
- public abstract static class ThermalStatusCallback {
+ public interface OnThermalStatusChangedListener {
/**
* Called when overall thermal throttling status changed.
* @param status defined in {@link android.os.Temperature}.
*/
- public void onStatusChange(@ThermalStatus int status) {}
+ void onThermalStatusChanged(@ThermalStatus int status);
}
+
/**
- * This function registers a callback for thermal status change.
+ * This function adds a listener for thermal status change, listen call back will be
+ * enqueued tasks on the main thread
*
- * @param callback callback to be registered.
- * @param executor {@link Executor} to handle the callbacks.
+ * @param listener listener to be added,
*/
- public void registerThermalStatusCallback(
- @NonNull ThermalStatusCallback callback, @NonNull @CallbackExecutor Executor executor) {
- Preconditions.checkNotNull(callback, "callback cannnot be null");
- Preconditions.checkNotNull(executor, "executor cannnot be null");
+ public void addThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
+ Preconditions.checkNotNull(listener, "listener cannot be null");
synchronized (this) {
if (mThermalService == null) {
mThermalService = IThermalService.Stub.asInterface(
ServiceManager.getService(Context.THERMAL_SERVICE));
}
- try {
- if (mCallbackMap.containsKey(callback)) {
- throw new IllegalArgumentException("ThermalStatusCallback already registered");
- }
- IThermalStatusListener listener = new IThermalStatusListener.Stub() {
- @Override
- public void onStatusChange(int status) {
+ this.addThermalStatusListener(mContext.getMainExecutor(), listener);
+ }
+ }
+
+ /**
+ * This function adds a listener for thermal status change.
+ *
+ * @param executor {@link Executor} to handle listener callback.
+ * @param listener listener to be added.
+ */
+ public void addThermalStatusListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull OnThermalStatusChangedListener listener) {
+ Preconditions.checkNotNull(listener, "listener cannot be null");
+ Preconditions.checkNotNull(executor, "executor cannot be null");
+ synchronized (this) {
+ if (mThermalService == null) {
+ mThermalService = IThermalService.Stub.asInterface(
+ ServiceManager.getService(Context.THERMAL_SERVICE));
+ }
+ Preconditions.checkArgument(!mListenerMap.containsKey(listener),
+ "Listener already registered: " + listener);
+ IThermalStatusListener internalListener = new IThermalStatusListener.Stub() {
+ @Override
+ public void onStatusChange(int status) {
+ final long token = Binder.clearCallingIdentity();
+ try {
executor.execute(() -> {
- callback.onStatusChange(status);
+ listener.onThermalStatusChanged(status);
});
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
- };
- if (mThermalService.registerThermalStatusListener(listener)) {
- mCallbackMap.put(callback, listener);
+ }
+ };
+ try {
+ if (mThermalService.registerThermalStatusListener(internalListener)) {
+ mListenerMap.put(listener, internalListener);
} else {
- throw new RuntimeException("ThermalStatusCallback failed to register");
+ throw new RuntimeException("Listener failed to set");
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1822,28 +1845,24 @@
}
/**
- * This function unregisters a callback for thermal status change.
+ * This function removes a listener for thermal status change
*
- * @param callback to be unregistered.
- *
- * see {@link #registerThermalStatusCallback}
+ * @param listener listener to be removed
*/
- public void unregisterThermalStatusCallback(@NonNull ThermalStatusCallback callback) {
- Preconditions.checkNotNull(callback, "callback cannnot be null");
+ public void removeThermalStatusListener(@NonNull OnThermalStatusChangedListener listener) {
+ Preconditions.checkNotNull(listener, "listener cannot be null");
synchronized (this) {
if (mThermalService == null) {
mThermalService = IThermalService.Stub.asInterface(
ServiceManager.getService(Context.THERMAL_SERVICE));
}
+ IThermalStatusListener internalListener = mListenerMap.get(listener);
+ Preconditions.checkArgument(internalListener != null, "Listener was not added");
try {
- IThermalStatusListener listener = mCallbackMap.get(callback);
- if (listener == null) {
- throw new IllegalArgumentException("ThermalStatusCallback not registered");
- }
- if (mThermalService.unregisterThermalStatusListener(listener)) {
- mCallbackMap.remove(callback);
+ if (mThermalService.unregisterThermalStatusListener(internalListener)) {
+ mListenerMap.remove(listener);
} else {
- throw new RuntimeException("ThermalStatusCallback failed to unregister");
+ throw new RuntimeException("Listener failed to remove");
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3a2564a..f8dfc58 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5758,7 +5758,11 @@
"autofill_user_data_min_value_length";
/**
- * Defines whether Content Capture is enabled for the user.
+ * Defines whether Content Capture is enabled for the user.
+ *
+ * <p>Type: {@code int} ({@code 0} for disabled, {@code 1} for enabled).
+ * <p>Default: enabled
+ *
* @hide
*/
@TestApi
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 9c4669f..4afd204 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -37,7 +37,6 @@
import android.os.RemoteException;
import android.service.autofill.AutofillService;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureContext;
@@ -168,19 +167,6 @@
}
/**
- * @deprecated use {@link #setContentCaptureWhitelist(Set, Set)} instead
- */
- @Deprecated
- public final void setContentCaptureWhitelist(@Nullable List<String> packages,
- @Nullable List<ComponentName> activities) {
- setContentCaptureWhitelist(toSet(packages), toSet(activities));
- }
-
- private <T> ArraySet<T> toSet(@Nullable List<T> set) {
- return set == null ? null : new ArraySet<T>(set);
- }
-
- /**
* Explicitly limits content capture to the given packages and activities.
*
* <p>To reset the whitelist, call it passing {@code null} to both arguments.
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index f13cb5a..2e27737 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -714,7 +714,8 @@
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
} catch (Exception e) {
- final InflateException ie = new InflateException(parser.getPositionDescription()
+ final InflateException ie = new InflateException(
+ getParserStateDescription(inflaterContext, attrs)
+ ": " + e.getMessage(), e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
@@ -730,6 +731,16 @@
}
}
+ private static String getParserStateDescription(Context context, AttributeSet attrs) {
+ int sourceResId = Resources.getAttributeSetSourceResId(attrs);
+ if (sourceResId == Resources.ID_NULL) {
+ return attrs.getPositionDescription();
+ } else {
+ return attrs.getPositionDescription() + " in "
+ + context.getResources().getResourceName(sourceResId);
+ }
+ }
+
private static final ClassLoader BOOT_CLASS_LOADER = LayoutInflater.class.getClassLoader();
private final boolean verifyClassLoader(Constructor<? extends View> constructor) {
@@ -818,7 +829,7 @@
if (mFilter != null && clazz != null) {
boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
- failNotAllowed(name, prefix, attrs);
+ failNotAllowed(name, prefix, viewContext, attrs);
}
}
constructor = clazz.getConstructor(mConstructorSignature);
@@ -837,10 +848,10 @@
boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
mFilterMap.put(name, allowed);
if (!allowed) {
- failNotAllowed(name, prefix, attrs);
+ failNotAllowed(name, prefix, viewContext, attrs);
}
} else if (allowedState.equals(Boolean.FALSE)) {
- failNotAllowed(name, prefix, attrs);
+ failNotAllowed(name, prefix, viewContext, attrs);
}
}
}
@@ -862,14 +873,16 @@
mConstructorArgs[0] = lastContext;
}
} catch (NoSuchMethodException e) {
- final InflateException ie = new InflateException(attrs.getPositionDescription()
+ final InflateException ie = new InflateException(
+ getParserStateDescription(viewContext, attrs)
+ ": Error inflating class " + (prefix != null ? (prefix + name) : name), e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
} catch (ClassCastException e) {
// If loaded class is not a View subclass
- final InflateException ie = new InflateException(attrs.getPositionDescription()
+ final InflateException ie = new InflateException(
+ getParserStateDescription(viewContext, attrs)
+ ": Class is not a View " + (prefix != null ? (prefix + name) : name), e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
@@ -878,7 +891,7 @@
throw e;
} catch (Exception e) {
final InflateException ie = new InflateException(
- attrs.getPositionDescription() + ": Error inflating class "
+ getParserStateDescription(viewContext, attrs) + ": Error inflating class "
+ (clazz == null ? "<unknown>" : clazz.getName()), e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
@@ -890,8 +903,8 @@
/**
* Throw an exception because the specified class is not allowed to be inflated.
*/
- private void failNotAllowed(String name, String prefix, AttributeSet attrs) {
- throw new InflateException(attrs.getPositionDescription()
+ private void failNotAllowed(String name, String prefix, Context context, AttributeSet attrs) {
+ throw new InflateException(getParserStateDescription(context, attrs)
+ ": Class not allowed to be inflated "+ (prefix != null ? (prefix + name) : name));
}
@@ -1013,13 +1026,15 @@
throw e;
} catch (ClassNotFoundException e) {
- final InflateException ie = new InflateException(attrs.getPositionDescription()
+ final InflateException ie = new InflateException(
+ getParserStateDescription(context, attrs)
+ ": Error inflating class " + name, e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
} catch (Exception e) {
- final InflateException ie = new InflateException(attrs.getPositionDescription()
+ final InflateException ie = new InflateException(
+ getParserStateDescription(context, attrs)
+ ": Error inflating class " + name, e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
@@ -1215,8 +1230,8 @@
}
if (type != XmlPullParser.START_TAG) {
- throw new InflateException(childParser.getPositionDescription() +
- ": No start tag found!");
+ throw new InflateException(getParserStateDescription(context, childAttrs)
+ + ": No start tag found!");
}
final String childName = childParser.getName();
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index f8d5014..b2f3f5e 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -67,6 +67,7 @@
private boolean mExpanded;
private boolean mShowExpandButtonAtEnd;
private boolean mShowWorkBadgeAtEnd;
+ private int mHeaderTextMarginEnd;
private Drawable mBackground;
private boolean mEntireHeaderClickable;
private boolean mExpandOnlyOnButton;
@@ -133,7 +134,8 @@
MeasureSpec.AT_MOST);
int wrapContentHeightSpec = MeasureSpec.makeMeasureSpec(givenHeight,
MeasureSpec.AT_MOST);
- int totalWidth = getPaddingStart() + getPaddingEnd();
+ int totalWidth = getPaddingStart();
+ int iconWidth = getPaddingEnd();
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
@@ -146,10 +148,19 @@
int childHeightSpec = getChildMeasureSpec(wrapContentHeightSpec,
lp.topMargin + lp.bottomMargin, lp.height);
child.measure(childWidthSpec, childHeightSpec);
- totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
+ if ((child == mExpandButton && mShowExpandButtonAtEnd)
+ || child == mProfileBadge
+ || child == mAppOps) {
+ iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
+ } else {
+ totalWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
+ }
}
- if (totalWidth > givenWidth) {
- int overFlow = totalWidth - givenWidth;
+
+ // Ensure that there is at least enough space for the icons
+ int endMargin = Math.max(mHeaderTextMarginEnd, iconWidth);
+ if (totalWidth > givenWidth - endMargin) {
+ int overFlow = totalWidth - givenWidth + endMargin;
// We are overflowing, lets shrink the app name first
overFlow = shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mAppName,
mChildMinWidth);
@@ -161,6 +172,7 @@
shrinkViewForOverflow(wrapContentHeightSpec, overFlow, mSecondaryHeaderText,
0);
}
+ totalWidth += getPaddingEnd();
mTotalWidth = Math.min(totalWidth, givenWidth);
setMeasuredDimension(givenWidth, givenHeight);
}
@@ -383,6 +395,26 @@
return mIcon;
}
+ /**
+ * Sets the margin end for the text portion of the header, excluding right-aligned elements
+ * @param headerTextMarginEnd margin size
+ */
+ @RemotableViewMethod
+ public void setHeaderTextMarginEnd(int headerTextMarginEnd) {
+ if (mHeaderTextMarginEnd != headerTextMarginEnd) {
+ mHeaderTextMarginEnd = headerTextMarginEnd;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Get the current margin end value for the header text
+ * @return margin size
+ */
+ public int getHeaderTextMarginEnd() {
+ return mHeaderTextMarginEnd;
+ }
+
public class HeaderTouchListener implements View.OnTouchListener {
private final ArrayList<Rect> mTouchRects = new ArrayList<>();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 287365f7..a9965b0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5803,6 +5803,11 @@
setImportantForAutofill(a.getInt(attr, IMPORTANT_FOR_AUTOFILL_AUTO));
}
break;
+ case R.styleable.View_importantForContentCapture:
+ if (a.peekValue(attr) != null) {
+ setImportantForContentCapture(a.getInt(attr,
+ IMPORTANT_FOR_CONTENT_CAPTURE_AUTO));
+ }
case R.styleable.View_defaultFocusHighlightEnabled:
if (a.peekValue(attr) != null) {
setDefaultFocusHighlightEnabled(a.getBoolean(attr, true));
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 5d59e42..df8690d 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -360,7 +360,7 @@
}
clearWindowCache();
final int nodesForWindowCount = mNodeCache.size();
- for (int i = 0; i < nodesForWindowCount; i++) {
+ for (int i = nodesForWindowCount - 1; i >= 0; i--) {
final int windowId = mNodeCache.keyAt(i);
clearNodesForWindowLocked(windowId);
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 70fe230..0c0a555 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1827,22 +1827,6 @@
}
/**
- * @deprecated use {@link #setAugmentedAutofillWhitelist(Set, Set)} instead.
- * @hide
- */
- @SystemApi
- @TestApi
- @Deprecated
- public void setAugmentedAutofillWhitelist(@Nullable List<String> packages,
- @Nullable List<ComponentName> activities) {
- setAugmentedAutofillWhitelist(toSet(packages), toSet(activities));
- }
-
- private <T> ArraySet<T> toSet(@Nullable List<T> set) {
- return set == null ? null : new ArraySet<T>(set);
- }
-
- /**
* Explicitly limits augmented autofill to the given packages and activities.
*
* <p>To reset the whitelist, call it passing {@code null} to both arguments.
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index 498bc5a..de86d92 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -37,7 +38,7 @@
private final int mNotificationContentImageMarginEnd;
private ImageView mRightIcon;
private View mActions;
- private View mHeader;
+ private NotificationHeaderView mHeader;
private View mMainColumn;
private View mMediaContent;
private int mImagePushIn;
@@ -94,7 +95,14 @@
mMainColumn.setLayoutParams(params);
reMeasure = true;
}
- int headerMarginEnd = size + imageEndMargin;
+ // margin for the entire header line
+ int headerMarginEnd = imageEndMargin;
+ // margin for the header text (not including the expand button and other icons)
+ int headerTextMarginEnd = size + imageEndMargin;
+ if (headerTextMarginEnd != mHeader.getHeaderTextMarginEnd()) {
+ mHeader.setHeaderTextMarginEnd(headerTextMarginEnd);
+ reMeasure = true;
+ }
params = (MarginLayoutParams) mHeader.getLayoutParams();
if (params.getMarginEnd() != headerMarginEnd) {
params.setMarginEnd(headerMarginEnd);
diff --git a/core/res/res/anim/lock_scanning.xml b/core/res/res/anim/lock_scanning.xml
new file mode 100644
index 0000000..36d8f88
--- /dev/null
+++ b/core/res/res/anim/lock_scanning.xml
@@ -0,0 +1,371 @@
+<!--
+ Copyright (C) 2019 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="32dp" android:width="32dp" android:viewportHeight="32"
+ android:viewportWidth="32">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_2_G_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_2_G" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:scaleX="0.64" android:scaleY="0.64">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="?attr/textColor"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M14.25 0.25 C14.25,0.25 12.75,0.25 12.75,0.25 C12.75,0.25 10.75,0.25 10.75,0.25 C10.75,0.25 5.75,0.25 5.75,0.25 C5.75,0.25 3.75,0.25 3.75,0.25 C3.75,0.25 2.25,0.25 2.25,0.25 C1.15,0.25 0.25,1.15 0.25,2.25 C0.25,2.25 0.25,12.25 0.25,12.25 C0.25,13.35 1.15,14.25 2.25,14.25 C2.25,14.25 14.25,14.25 14.25,14.25 C15.35,14.25 16.25,13.35 16.25,12.25 C16.25,12.25 16.25,2.25 16.25,2.25 C16.25,1.15 15.35,0.25 14.25,0.25c M14.25 12.25 C14.25,12.25 2.25,12.25 2.25,12.25 C2.25,12.25 2.25,2.25 2.25,2.25 C2.25,2.25 3.75,2.25 3.75,2.25 C3.75,2.25 12.75,2.25 12.75,2.25 C12.75,2.25 14.25,2.25 14.25,2.25 C14.25,2.25 14.25,12.25 14.25,12.25c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_4_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:scaleX="0.64" android:scaleY="0.64">
+ <group android:name="_R_G_L_1_G" android:translateX="6"
+ android:translateY="5" android:pivotX="2.25" android:pivotY="2.25"
+ android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="?attr/textColor"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_4_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:scaleX="0.64" android:scaleY="0.64">
+ <group android:name="_R_G_L_0_G_T_1" android:translateX="8.25"
+ android:translateY="1.121" android:scaleX="0.125"
+ android:scaleY="0.125">
+ <group android:name="_R_G_L_0_G" android:translateY="25.029">
+ <path android:name="_R_G_L_0_G_D_0_P_0"
+ android:strokeColor="?attr/textColor" android:strokeLineCap="round"
+ android:strokeLineJoin="round" android:strokeWidth="16"
+ android:strokeAlpha="1"
+ android:pathData=" M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="150"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="150"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="117"
+ android:startOffset="150" android:valueFrom="1"
+ android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="117"
+ android:startOffset="150" android:valueFrom="1"
+ android:valueTo="0.6" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="333"
+ android:startOffset="267" android:valueFrom="0.6"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="333"
+ android:startOffset="267" android:valueFrom="0.6"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_4_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="83"
+ android:startOffset="0"
+ android:valueFrom="M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "
+ android:valueTo="M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="150"
+ android:startOffset="83"
+ android:valueFrom="M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "
+ android:valueTo="M-28.02 -43.42 C-28.02,-43.42 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.76,-43.67 27.76,-43.67 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="117"
+ android:startOffset="233"
+ android:valueFrom="M-28.02 -43.42 C-28.02,-43.42 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.76,-43.67 27.76,-43.67 "
+ android:valueTo="M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="83"
+ android:startOffset="0" android:valueFrom="1.121"
+ android:valueTo="1.121" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="150"
+ android:startOffset="83" android:valueFrom="1.121"
+ android:valueTo="3.749" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="117"
+ android:startOffset="233" android:valueFrom="3.749"
+ android:valueTo="1.121" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_4_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="0" android:valueFrom="0.64"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="83"
+ android:startOffset="83" android:valueFrom="0.64"
+ android:valueTo="0.62" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="183"
+ android:startOffset="167" android:valueFrom="0.62"
+ android:valueTo="0.8" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="250"
+ android:startOffset="350" android:valueFrom="0.8"
+ android:valueTo="0.64" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="1000"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector>
\ No newline at end of file
diff --git a/core/res/res/anim/lock_to_error.xml b/core/res/res/anim/lock_to_error.xml
index 29b4964..4aad742 100755
--- a/core/res/res/anim/lock_to_error.xml
+++ b/core/res/res/anim/lock_to_error.xml
@@ -14,545 +14,174 @@
limitations under the License.
-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
+ xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
- <vector
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
+ <vector android:height="32dp" android:width="32dp" android:viewportHeight="32"
+ android:viewportWidth="32">
<group android:name="_R_G">
- <group
- android:name="_R_G_L_3_G"
- android:pivotY="-32"
- android:scaleX="0.12762"
- android:scaleY="0.12762"
- android:translateX="12"
- android:translateY="39.871">
- <path
- android:name="_R_G_L_3_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#ff0000"
- android:fillType="nonZero"
- android:pathData=" M-28.21 -31.92 C-28.21,-31.92 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.97,-31.67 27.97,-31.67 "
- android:trimPathStart="0"
- android:trimPathEnd="1"
- android:trimPathOffset="0" />
- <path
- android:name="_R_G_L_3_G_D_1_P_0"
- android:pathData=" M-28.21 -31.92 C-28.21,-31.92 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.97,-31.67 27.97,-31.67 "
- android:strokeWidth="16"
- android:strokeAlpha="1"
- android:strokeColor="?attr/textColor"
- android:trimPathStart="0"
- android:trimPathEnd="1"
- android:trimPathOffset="0" />
- </group>
- <group
- android:name="_R_G_L_2_G_T_1"
- android:rotation="45"
- android:scaleX="1"
- android:scaleY="1"
- android:translateX="12"
- android:translateY="15">
- <group
- android:name="_R_G_L_2_G"
- android:translateX="-2.25"
- android:translateY="-2.25">
- <path
- android:name="_R_G_L_2_G_D_0_P_0"
- android:fillAlpha="1"
- android:fillColor="?attr/textColor"
- android:fillType="nonZero"
- android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
+ <group android:name="_R_G_L_2_G_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_2_G" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:rotation="0" android:scaleX="0.64"
+ android:scaleY="0.64">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="?attr/textColor"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M14.25 0.25 C14.25,0.25 12.75,0.25 12.75,0.25 C12.75,0.25 10.75,0.25 10.75,0.25 C10.75,0.25 5.75,0.25 5.75,0.25 C5.75,0.25 3.75,0.25 3.75,0.25 C3.75,0.25 2.25,0.25 2.25,0.25 C1.15,0.25 0.25,1.15 0.25,2.25 C0.25,2.25 0.25,12.25 0.25,12.25 C0.25,13.35 1.15,14.25 2.25,14.25 C2.25,14.25 14.25,14.25 14.25,14.25 C15.35,14.25 16.25,13.35 16.25,12.25 C16.25,12.25 16.25,2.25 16.25,2.25 C16.25,1.15 15.35,0.25 14.25,0.25c M14.25 12.25 C14.25,12.25 2.25,12.25 2.25,12.25 C2.25,12.25 2.25,2.25 2.25,2.25 C2.25,2.25 3.75,2.25 3.75,2.25 C3.75,2.25 12.75,2.25 12.75,2.25 C12.75,2.25 14.25,2.25 14.25,2.25 C14.25,2.25 14.25,12.25 14.25,12.25c "/>
</group>
</group>
- <group
- android:name="_R_G_L_1_G_T_1"
- android:scaleX="0.125"
- android:scaleY="0.125"
- android:translateX="12.023"
- android:translateY="1.281">
- <group
- android:name="_R_G_L_1_G"
- android:translateX="0.317"
- android:translateY="45.25">
- <path
- android:name="_R_G_L_1_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#EA4335"
- android:fillType="nonZero"
- android:pathData=" M4.21 -42.01 C4.21,-42.01 4.21,-32 4.21,-32 C4.21,-32 -5.25,-32 -5.25,-32 C-5.25,-32 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c " />
+ <group android:name="_R_G_L_1_G_N_4_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:rotation="0" android:scaleX="0.64"
+ android:scaleY="0.64">
+ <group android:name="_R_G_L_1_G" android:translateX="6"
+ android:translateY="5">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="?attr/textColor"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "/>
+ </group>
</group>
</group>
- <group
- android:name="_R_G_L_0_G"
- android:pivotY="21"
- android:scaleX="0.14286"
- android:scaleY="0.14286"
- android:translateX="12"
- android:translateY="-6">
- <path
- android:name="_R_G_L_0_G_D_0_P_0"
- android:fillAlpha="0"
- android:fillColor="#ffffff"
- android:fillType="nonZero"
- android:pathData=" M49.24 -12.32 C49.24,-12.32 49.24,52.91 49.24,52.91 C49.24,58.95 44.34,63.85 38.3,63.85 C38.3,63.85 -37.8,63.85 -37.8,63.85 C-43.84,63.85 -48.74,58.95 -48.74,52.91 C-48.74,52.91 -48.74,-12.32 -48.74,-12.32 C-48.74,-18.37 -43.84,-23.27 -37.8,-23.27 C-37.8,-23.27 38.3,-23.27 38.3,-23.27 C44.34,-23.27 49.24,-18.37 49.24,-12.32c " />
- <path
- android:name="_R_G_L_0_G_D_1_P_0"
- android:pathData=" M49.24 -12.32 C49.24,-12.32 49.24,52.91 49.24,52.91 C49.24,58.95 44.34,63.85 38.3,63.85 C38.3,63.85 -37.8,63.85 -37.8,63.85 C-43.84,63.85 -48.74,58.95 -48.74,52.91 C-48.74,52.91 -48.74,-12.32 -48.74,-12.32 C-48.74,-18.37 -43.84,-23.27 -37.8,-23.27 C-37.8,-23.27 38.3,-23.27 38.3,-23.27 C44.34,-23.27 49.24,-18.37 49.24,-12.32c "
- android:strokeWidth="14"
- android:strokeAlpha="1"
- android:strokeColor="?attr/textColor"
- android:strokeLineCap="round"
- android:strokeLineJoin="round" />
+ <group android:name="_R_G_L_0_G_N_4_N_1_T_0" android:pivotX="16" android:pivotY="16"
+ android:scaleX="1.5" android:scaleY="1.5">
+ <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="7.75"
+ android:translateY="10.670000000000002" android:pivotX="8.25"
+ android:pivotY="7.25" android:rotation="0" android:scaleX="0.64"
+ android:scaleY="0.64">
+ <group android:name="_R_G_L_0_G" android:translateX="-16.219"
+ android:translateY="32.25" android:pivotX="27.965"
+ android:pivotY="-32" android:scaleX="0.125" android:scaleY="0.125">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="?attr/textColor"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="16" android:strokeAlpha="1"
+ android:pathData=" M-28.21 -25.03 C-28.21,-25.03 -27.85,-48.38 -27.97,-55.48 C-28,-57.63 -23.5,-79.87 -0.75,-79.82 C22.77,-79.76 27.75,-59.37 27.72,-58.27 C27.55,-52.88 27.93,-26.15 27.93,-26.15 "/>
+ </group>
+ </group>
</group>
</group>
- <group android:name="time_group" />
+ <group android:name="time_group"/>
</vector>
</aapt:attr>
- <target android:name="_R_G_L_3_G_D_0_P_0">
+ <target android:name="_R_G_L_2_G">
<aapt:attr name="android:animation">
<set android:ordering="together">
- <objectAnimator
- android:duration="250"
- android:propertyName="trimPathStart"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.5"
- android:valueType="floatType">
+ <objectAnimator android:propertyName="rotation" android:duration="133"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="0"
+ android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="120"
+ android:startOffset="133" android:valueFrom="0"
+ android:valueTo="-10" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="97"
+ android:startOffset="253" android:valueFrom="-10"
+ android:valueTo="10" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="100"
+ android:startOffset="350" android:valueFrom="10"
+ android:valueTo="-5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="167"
+ android:startOffset="450" android:valueFrom="-5" android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
- <target android:name="_R_G_L_3_G_D_0_P_0">
+ <target android:name="_R_G_L_1_G_N_4_T_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
- <objectAnimator
- android:duration="250"
- android:propertyName="trimPathEnd"
- android:startOffset="0"
- android:valueFrom="1"
- android:valueTo="0.5"
- android:valueType="floatType">
+ <objectAnimator android:propertyName="rotation" android:duration="133"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="0"
+ android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="120"
+ android:startOffset="133" android:valueFrom="0"
+ android:valueTo="-10" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="97"
+ android:startOffset="253" android:valueFrom="-10"
+ android:valueTo="10" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="100"
+ android:startOffset="350" android:valueFrom="10"
+ android:valueTo="-5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="rotation" android:duration="167"
+ android:startOffset="450" android:valueFrom="-5" android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
- <target android:name="_R_G_L_3_G_D_1_P_0">
+ <target android:name="_R_G_L_0_G_N_4_T_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
- <objectAnimator
- android:duration="117"
- android:propertyName="strokeColor"
- android:startOffset="0"
- android:valueFrom="#fff"
- android:valueTo="#fff"
- android:valueType="colorType">
+ <objectAnimator android:propertyName="rotation" android:duration="133"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="0"
+ android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
- <objectAnimator
- android:duration="17"
- android:propertyName="strokeColor"
- android:startOffset="117"
- android:valueFrom="#fff"
- android:valueTo="#EA4335"
- android:valueType="colorType">
+ <objectAnimator android:propertyName="rotation" android:duration="120"
+ android:startOffset="133" android:valueFrom="0"
+ android:valueTo="-10" android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="strokeWidth"
- android:startOffset="0"
- android:valueFrom="16"
- android:valueTo="8"
- android:valueType="floatType">
+ <objectAnimator android:propertyName="rotation" android:duration="97"
+ android:startOffset="253" android:valueFrom="-10"
+ android:valueTo="10" android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="250"
- android:propertyName="trimPathStart"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0.5"
- android:valueType="floatType">
+ <objectAnimator android:propertyName="rotation" android:duration="100"
+ android:startOffset="350" android:valueFrom="10"
+ android:valueTo="-5" android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="250"
- android:propertyName="trimPathEnd"
- android:startOffset="0"
- android:valueFrom="1"
- android:valueTo="0.5"
- android:valueType="floatType">
+ <objectAnimator android:propertyName="rotation" android:duration="167"
+ android:startOffset="450" android:valueFrom="-5" android:valueTo="0"
+ android:valueType="floatType">
<aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_3_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleY"
- android:startOffset="183"
- android:valueFrom="0.12762"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="117"
- android:propertyName="fillColor"
- android:startOffset="0"
- android:valueFrom="#fff"
- android:valueTo="#fff"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="17"
- android:propertyName="fillColor"
- android:startOffset="117"
- android:valueFrom="#fff"
- android:valueTo="#EA4335"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="133"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "
- android:valueTo="M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="133"
- android:propertyName="pathData"
- android:startOffset="133"
- android:valueFrom="M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "
- android:valueTo="M2.25 0.25 C2.25,0.25 4.25,2.25 4.25,2.25 C4.25,2.25 2.25,4.25 2.25,4.25 C2.25,4.25 0.25,2.25 0.25,2.25 C0.25,2.25 2.25,0.25 2.25,0.25c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="17"
- android:pathData="M 12,15C 12,15.171875 12,14.828125 12,15"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:pathData="M 12,15C 12,15.171875 12,15.859124999999999 12,16.031"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="17">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_2_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="17"
- android:propertyName="scaleX"
- android:startOffset="0"
- android:valueFrom="1"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="17"
- android:propertyName="scaleY"
- android:startOffset="0"
- android:valueFrom="1"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleX"
- android:startOffset="17"
- android:valueFrom="1"
- android:valueTo="0.4325"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleY"
- android:startOffset="17"
- android:valueFrom="1"
- android:valueTo="0.4325"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="150"
- android:propertyName="fillAlpha"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="0"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="17"
- android:propertyName="fillAlpha"
- android:startOffset="150"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M4.21 -42.01 C4.21,-42.01 4.21,-32 4.21,-32 C4.21,-32 -5.25,-32 -5.25,-32 C-5.25,-32 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueTo="M4.21 -42.01 C4.21,-42.01 4.21,-32 4.21,-32 C4.21,-32 -5.25,-32 -5.25,-32 C-5.25,-32 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="183"
- android:propertyName="pathData"
- android:startOffset="167"
- android:valueFrom="M4.21 -42.01 C4.21,-42.01 4.21,-32 4.21,-32 C4.21,-32 -5.25,-32 -5.25,-32 C-5.25,-32 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueTo="M4.21 -42.01 C4.21,-42.01 4.16,33 4.16,33 C4.16,33 -5.3,33 -5.3,33 C-5.3,33 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="50"
- android:propertyName="pathData"
- android:startOffset="350"
- android:valueFrom="M4.21 -42.01 C4.21,-42.01 4.16,33 4.16,33 C4.16,33 -5.3,33 -5.3,33 C-5.3,33 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueTo="M4.21 -42.01 C4.21,-42.01 4.19,30.81 4.19,30.81 C4.19,30.81 -5.27,30.81 -5.27,30.81 C-5.27,30.81 -5.25,-42.01 -5.25,-42.01 C-5.25,-42.01 4.21,-42.01 4.21,-42.01c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="167"
- android:pathData="M 12.023,1.281C 12.023,1.656 12.023,0.9059999999999999 12.023,1.281"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="183"
- android:pathData="M 12.023,1.281C 12.023,1.656 12.023,3.156 12.023,3.531"
- android:propertyName="translateXY"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:startOffset="167">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="0"
- android:propertyName="scaleX"
- android:startOffset="167"
- android:valueFrom="0"
- android:valueTo="0.125"
- android:valueType="floatType" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="267"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M49.24 -12.32 C49.24,-12.32 49.24,52.91 49.24,52.91 C49.24,58.95 44.34,63.85 38.3,63.85 C38.3,63.85 -37.8,63.85 -37.8,63.85 C-43.84,63.85 -48.74,58.95 -48.74,52.91 C-48.74,52.91 -48.74,-12.32 -48.74,-12.32 C-48.74,-18.37 -43.84,-23.27 -37.8,-23.27 C-37.8,-23.27 38.3,-23.27 38.3,-23.27 C44.34,-23.27 49.24,-18.37 49.24,-12.32c "
- android:valueTo="M75.1 -1.1 C75.1,19.57 66.72,38.28 53.18,51.83 C39.63,65.37 20.92,73.75 0.25,73.75 C-20.42,73.75 -39.13,65.37 -52.68,51.83 C-66.22,38.28 -74.6,19.57 -74.6,-1.1 C-74.6,-21.77 -66.22,-40.48 -52.68,-54.02 C-39.13,-67.57 -20.42,-75.95 0.25,-75.95 C20.92,-75.95 39.63,-67.57 53.18,-54.02 C66.72,-40.48 75.1,-21.77 75.1,-1.1c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="117"
- android:propertyName="strokeColor"
- android:startOffset="0"
- android:valueFrom="#fff"
- android:valueTo="#fff"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- <objectAnimator
- android:duration="17"
- android:propertyName="strokeColor"
- android:startOffset="117"
- android:valueFrom="#fff"
- android:valueTo="#EA4335"
- android:valueType="colorType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="267"
- android:propertyName="strokeWidth"
- android:startOffset="0"
- android:valueFrom="14"
- android:valueTo="12"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_1_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator
- android:duration="267"
- android:propertyName="pathData"
- android:startOffset="0"
- android:valueFrom="M49.24 -12.32 C49.24,-12.32 49.24,52.91 49.24,52.91 C49.24,58.95 44.34,63.85 38.3,63.85 C38.3,63.85 -37.8,63.85 -37.8,63.85 C-43.84,63.85 -48.74,58.95 -48.74,52.91 C-48.74,52.91 -48.74,-12.32 -48.74,-12.32 C-48.74,-18.37 -43.84,-23.27 -37.8,-23.27 C-37.8,-23.27 38.3,-23.27 38.3,-23.27 C44.34,-23.27 49.24,-18.37 49.24,-12.32c "
- android:valueTo="M75.1 -1.1 C75.1,19.57 66.72,38.28 53.18,51.83 C39.63,65.37 20.92,73.75 0.25,73.75 C-20.42,73.75 -39.13,65.37 -52.68,51.83 C-66.22,38.28 -74.6,19.57 -74.6,-1.1 C-74.6,-21.77 -66.22,-40.48 -52.68,-54.02 C-39.13,-67.57 -20.42,-75.95 0.25,-75.95 C20.92,-75.95 39.63,-67.57 53.18,-54.02 C66.72,-40.48 75.1,-21.77 75.1,-1.1c "
- android:valueType="pathType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0" />
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0"/>
</aapt:attr>
</objectAnimator>
</set>
@@ -561,13 +190,9 @@
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
- <objectAnimator
- android:duration="1017"
- android:propertyName="translateX"
- android:startOffset="0"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" />
+ <objectAnimator android:propertyName="translateX" android:duration="1000"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
</set>
</aapt:attr>
</target>
diff --git a/core/res/res/drawable/ic_auth_error.xml b/core/res/res/drawable/ic_auth_error.xml
deleted file mode 100644
index ea5f572..0000000
--- a/core/res/res/drawable/ic_auth_error.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- Copyright (C) 2019 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.
--->
-<vector android:height="24dp" android:viewportHeight="60"
- android:viewportWidth="60" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="?attr/colorError" android:pathData="M28.8,37.5l2.4,0l0,2.5l-2.4,0z"/>
- <path android:fillColor="?attr/colorError" android:pathData="M28.8,17.5l2.4,0l0,15l-2.4,0z"/>
- <path android:fillColor="#00000000"
- android:pathData="M30,6.2c-13.1,0 -23.7,10.6 -23.7,23.8S16.9,53.8 30,53.8c13.1,0 23.8,-10.6 23.8,-23.8S43.1,6.2 30,6.2z"
- android:strokeColor="?android:attr/colorError" android:strokeWidth="2.5"/>
-</vector>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e01f421..13551e7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1380,7 +1380,6 @@
<java-symbol type="drawable" name="ic_print_error" />
<java-symbol type="drawable" name="ic_lock_24dp" />
<java-symbol type="drawable" name="ic_lock_open_24dp" />
- <java-symbol type="drawable" name="ic_auth_error" />
<java-symbol type="drawable" name="jog_dial_arrow_long_left_green" />
<java-symbol type="drawable" name="jog_dial_arrow_long_right_red" />
<java-symbol type="drawable" name="jog_dial_arrow_short_left_and_right" />
@@ -2248,6 +2247,7 @@
<java-symbol type="anim" name="lock_lock" />
<java-symbol type="anim" name="lock_unlock" />
<java-symbol type="anim" name="lock_in" />
+ <java-symbol type="anim" name="lock_scanning" />
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
<java-symbol type="dimen" name="status_bar_icon_size" />
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 1b587dd..576ac73 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -41,7 +41,9 @@
private UiDevice mUiDevice;
private Executor mExec = Executors.newSingleThreadExecutor();
@Mock
- private PowerManager.ThermalStatusCallback mCallback;
+ private PowerManager.OnThermalStatusChangedListener mListener1;
+ @Mock
+ private PowerManager.OnThermalStatusChangedListener mListener2;
private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
/**
@@ -169,6 +171,11 @@
// TODO: Threaded test (needs handler) to make sure timed wakelocks work too
}
+ /**
+ * Confirm that we can get thermal status.
+ *
+ * @throws Exception
+ */
@Test
public void testGetThermalStatus() throws Exception {
int status = 0;
@@ -179,24 +186,57 @@
assertEquals(status, mPm.getCurrentThermalStatus());
}
+ /**
+ * Confirm that we can add/remove thermal status listener.
+ *
+ * @throws Exception
+ */
@Test
public void testThermalStatusCallback() throws Exception {
- mPm.registerThermalStatusCallback(mCallback, mExec);
- verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(0);
- reset(mCallback);
- int status = 3;
+ // Initial override status is THERMAL_STATUS_NONE
+ int status = PowerManager.THERMAL_STATUS_NONE;
+ // Add listener1
+ mPm.addThermalStatusListener(mExec, mListener1);
+ verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalStatusChanged(status);
+ reset(mListener1);
+ status = PowerManager.THERMAL_STATUS_SEVERE;
mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ Integer.toString(status));
- verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(status);
- reset(mCallback);
- mPm.unregisterThermalStatusCallback(mCallback);
- status = 2;
+ verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalStatusChanged(status);
+ reset(mListener1);
+ // Add listener1 again
+ try {
+ mPm.addThermalStatusListener(mListener1);
+ fail("Expected exception not thrown");
+ } catch (IllegalArgumentException expectedException) {
+ }
+ // Add listener2 on main thread.
+ mPm.addThermalStatusListener(mListener2);
+ status = PowerManager.THERMAL_STATUS_MODERATE;
mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ Integer.toString(status));
- verify(mCallback, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(0)).onStatusChange(status);
-
+ verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalStatusChanged(status);
+ verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalStatusChanged(status);
+ reset(mListener1);
+ reset(mListener2);
+ // Remove listener1
+ mPm.removeThermalStatusListener(mListener1);
+ // Remove listener1 again
+ try {
+ mPm.removeThermalStatusListener(mListener1);
+ fail("Expected exception not thrown");
+ } catch (IllegalArgumentException expectedException) {
+ }
+ status = PowerManager.THERMAL_STATUS_LIGHT;
+ mUiDevice.executeShellCommand("cmd thermalservice override-status "
+ + Integer.toString(status));
+ verify(mListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(0)).onThermalStatusChanged(status);
+ verify(mListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
+ .times(1)).onThermalStatusChanged(status);
}
}
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 28937a6..fbb629b 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1984,41 +1984,45 @@
{
private MetricsConstants() {}
- /**
- * Key to extract the output format being recorded
- * from the {@link AudioRecord#getMetrics} return value.
- * The value is a String.
- */
- public static final String ENCODING = "android.media.audiorecord.encoding";
+ // MM_PREFIX is slightly different than TAG, used to avoid cut-n-paste errors.
+ private static final String MM_PREFIX = "android.media.audiorecord.";
/**
- * Key to extract the Source Type for this track
+ * Key to extract the audio data encoding for this track
* from the {@link AudioRecord#getMetrics} return value.
- * The value is a String.
+ * The value is a {@code String}.
*/
- public static final String SOURCE = "android.media.audiorecord.source";
+ public static final String ENCODING = MM_PREFIX + "encoding";
+
+ /**
+ * Key to extract the source type for this track
+ * from the {@link AudioRecord#getMetrics} return value.
+ * The value is a {@code String}.
+ */
+ public static final String SOURCE = MM_PREFIX + "source";
/**
* Key to extract the estimated latency through the recording pipeline
* from the {@link AudioRecord#getMetrics} return value.
* This is in units of milliseconds.
- * The value is an integer.
+ * The value is an {@code int}.
+ * @deprecated Not properly supported in the past.
*/
- public static final String LATENCY = "android.media.audiorecord.latency";
+ @Deprecated
+ public static final String LATENCY = MM_PREFIX + "latency";
/**
* Key to extract the sink sample rate for this record track in Hz
* from the {@link AudioRecord#getMetrics} return value.
- * The value is an integer.
+ * The value is an {@code int}.
*/
- public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
+ public static final String SAMPLERATE = MM_PREFIX + "samplerate";
/**
* Key to extract the number of channels being recorded in this record track
* from the {@link AudioRecord#getMetrics} return value.
- * The value is an integer.
+ * The value is an {@code int}.
*/
- public static final String CHANNELS = "android.media.audiorecord.channels";
-
+ public static final String CHANNELS = MM_PREFIX + "channels";
}
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 7cfe0dd..a15d322 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -3580,41 +3580,49 @@
{
private MetricsConstants() {}
- /**
- * Key to extract the Stream Type for this track
- * from the {@link AudioTrack#getMetrics} return value.
- * The value is a String.
- */
- public static final String STREAMTYPE = "android.media.audiotrack.streamtype";
+ // MM_PREFIX is slightly different than TAG, used to avoid cut-n-paste errors.
+ private static final String MM_PREFIX = "android.media.audiotrack.";
/**
- * Key to extract the Content Type for this track
+ * Key to extract the stream type for this track
* from the {@link AudioTrack#getMetrics} return value.
- * The value is a String.
+ * This value may not exist in API level {@link android.os.Build.VERSION_CODES#P}.
+ * The value is a {@code String}.
*/
- public static final String CONTENTTYPE = "android.media.audiotrack.type";
+ public static final String STREAMTYPE = MM_PREFIX + "streamtype";
/**
- * Key to extract the Content Type for this track
+ * Key to extract the attribute content type for this track
* from the {@link AudioTrack#getMetrics} return value.
- * The value is a String.
+ * The value is a {@code String}.
*/
- public static final String USAGE = "android.media.audiotrack.usage";
+ public static final String CONTENTTYPE = MM_PREFIX + "type";
+
+ /**
+ * Key to extract the attribute usage for this track
+ * from the {@link AudioTrack#getMetrics} return value.
+ * The value is a {@code String}.
+ */
+ public static final String USAGE = MM_PREFIX + "usage";
/**
* Key to extract the sample rate for this track in Hz
* from the {@link AudioTrack#getMetrics} return value.
- * The value is an integer.
+ * The value is an {@code int}.
+ * @deprecated This does not work. Use {@link AudioTrack#getSampleRate()} instead.
*/
+ @Deprecated
public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
/**
- * Key to extract the channel mask information for this track
+ * Key to extract the native channel mask information for this track
* from the {@link AudioTrack#getMetrics} return value.
*
- * The value is a Long integer.
+ * The value is a {@code long}.
+ * @deprecated This does not work. Use {@link AudioTrack#getFormat()} and read from
+ * the returned format instead.
*/
+ @Deprecated
public static final String CHANNELMASK = "android.media.audiorecord.channelmask";
-
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
index 43c97df..52d7e2c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/PowerUtil.java
@@ -195,19 +195,12 @@
}
private static String getRegularTimeRemainingShortString(Context context, long drainTimeMs) {
- // Get the time of day we think device will die rounded to the nearest 15 min.
- final long roundedTimeOfDayMs =
- roundTimeToNearestThreshold(
- System.currentTimeMillis() + drainTimeMs,
- FIFTEEN_MINUTES_MILLIS);
+ // Get the time remaining rounded to the nearest 15 min
+ final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, FIFTEEN_MINUTES_MILLIS);
+ CharSequence timeString = StringUtil.formatElapsedTime(context, roundedTimeMs,
+ false /* withSeconds */);
- // convert the time to a properly formatted string.
- String skeleton = android.text.format.DateFormat.getTimeFormatString(context);
- DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);
- Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
- CharSequence timeString = fmt.format(date);
-
- return context.getString(R.string.power_discharge_by_only_short, timeString);
+ return context.getString(R.string.power_remaining_duration_only_short, timeString);
}
public static long convertUsToMs(long timeUs) {
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 53b3a7e..d4957c9 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -85,7 +85,7 @@
android:layout_marginBottom="@dimen/keyguard_lock_padding"
android:src="@*android:drawable/ic_lock_24dp"
android:contentDescription="@string/accessibility_unlock_button"
- android:scaleType="fitCenter" />
+ android:scaleType="center" />
<FrameLayout
android:id="@+id/overlay_container"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index bd9d3fb..7e0f3ae 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -174,7 +174,7 @@
android:clipToPadding="false">
<TextView
android:id="@+id/done"
- android:text="@string/inline_done_button"
+ android:text="@string/inline_ok_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
@@ -191,7 +191,7 @@
android:orientation="horizontal">
<TextView
android:id="@+id/deliver_silently"
- android:text="@string/inline_deliver_silently_button"
+ android:text="@string/inline_silent_button_silent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index cf1b4d1..9e9aada 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1580,6 +1580,9 @@
<!-- Notification Inline controls: button to dismiss the blocking helper [CHAR_LIMIT=20] -->
<string name="inline_done_button">Done</string>
+ <!-- Notification Inline controls: button to dismiss the blocking helper [CHAR_LIMIT=20] -->
+ <string name="inline_ok_button">OK</string>
+
<!-- Notification Inline controls: continue receiving notifications prompt, channel level -->
<string name="inline_keep_showing">Keep showing these notifications?</string>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 592b603..39a5842 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -355,15 +355,23 @@
if (mBatteryPercentView != null) {
if (mShowPercentMode == MODE_ESTIMATE && !mCharging) {
mBatteryController.getEstimatedTimeRemainingString((String estimate) -> {
- mBatteryPercentView.setText(estimate);
+ if (estimate != null) {
+ mBatteryPercentView.setText(estimate);
+ } else {
+ setPercentTextAtCurrentLevel();
+ }
});
} else {
- mBatteryPercentView.setText(
- NumberFormat.getPercentInstance().format(mLevel / 100f));
+ setPercentTextAtCurrentLevel();
}
}
}
+ private void setPercentTextAtCurrentLevel() {
+ mBatteryPercentView.setText(
+ NumberFormat.getPercentInstance().format(mLevel / 100f));
+ }
+
private void updateShowPercent() {
final boolean showing = mBatteryPercentView != null;
final boolean systemSetting = 0 != Settings.System
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 603b3b9..4addbb5 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -49,6 +49,7 @@
import android.util.Log;
import android.util.StatsLog;
import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import android.widget.ImageButton;
@@ -316,8 +317,25 @@
/**
* Lets activity view know it should be shown / populated.
*/
- public void populateActivityView() {
- mActivityView.setCallback(mStateCallback);
+ public void populateExpandedView() {
+ if (usingActivityView()) {
+ mActivityView.setCallback(mStateCallback);
+ } else {
+ // We're using notification template
+ ViewGroup parent = (ViewGroup) mNotifRow.getParent();
+ if (parent == this) {
+ // Already added
+ return;
+ } else if (parent != null) {
+ // Still in the shade... remove it
+ parent.removeView(mNotifRow);
+ }
+ if (mShowOnTop) {
+ addView(mNotifRow);
+ } else {
+ addView(mNotifRow, mUseFooter ? 0 : 1);
+ }
+ }
}
/**
@@ -376,14 +394,8 @@
} else {
// Hide activity view if we had it previously
mActivityView.setVisibility(GONE);
-
- // Use notification view
mNotifRow = mEntry.getRow();
- if (mShowOnTop) {
- addView(mNotifRow);
- } else {
- addView(mNotifRow, mUseFooter ? 0 : 1);
- }
+
}
updateView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 4869485..8f9f1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -807,7 +807,7 @@
mExpandedViewContainer.removeAllViews();
if (mExpandedBubble != null && mIsExpanded) {
mExpandedViewContainer.addView(mExpandedBubble.expandedView);
- mExpandedBubble.expandedView.populateActivityView();
+ mExpandedBubble.expandedView.populateExpandedView();
mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
}
}
@@ -817,8 +817,12 @@
mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
if (mIsExpanded) {
+ // First update the view so that it calculates a new height (ensuring the y position
+ // calculation is correct)
+ mExpandedBubble.expandedView.updateView();
final float y = getYPositionForExpandedView();
mExpandedViewContainer.setTranslationY(y);
+ // Then update the view so that ActivityView knows we translated
mExpandedBubble.expandedView.updateView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 6a8c19a..08cf606 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -15,7 +15,6 @@
package com.android.systemui.qs;
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
-import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
@@ -31,15 +30,12 @@
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.Rect;
import android.media.AudioManager;
-import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.AlarmClock;
-import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
import android.util.AttributeSet;
@@ -75,7 +71,6 @@
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -107,7 +102,6 @@
public static final int MAX_TOOLTIP_SHOWN_COUNT = 2;
private final Handler mHandler = new Handler();
- private final BatteryController mBatteryController;
private final NextAlarmController mAlarmController;
private final ZenModeController mZenController;
private final StatusBarIconController mStatusBarIconController;
@@ -162,9 +156,6 @@
};
private boolean mHasTopCutout = false;
- private final PercentSettingObserver mPercentSettingObserver =
- new PercentSettingObserver(new Handler(mContext.getMainLooper()));
-
/**
* Runnable for automatically fading out the long press tooltip (as if it were animating away).
*/
@@ -181,12 +172,11 @@
@Inject
public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
NextAlarmController nextAlarmController, ZenModeController zenModeController,
- BatteryController batteryController, StatusBarIconController statusBarIconController,
+ StatusBarIconController statusBarIconController,
ActivityStarter activityStarter, PrivacyItemController privacyItemController) {
super(context, attrs);
mAlarmController = nextAlarmController;
mZenController = zenModeController;
- mBatteryController = batteryController;
mStatusBarIconController = statusBarIconController;
mActivityStarter = activityStarter;
mPrivacyItemController = privacyItemController;
@@ -241,7 +231,9 @@
mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
// Don't need to worry about tuner settings for this icon
mBatteryRemainingIcon.setIgnoreTunerUpdates(true);
- updateShowPercent();
+ // QS will always show the estimate, and BatteryMeterView handles the case where
+ // it's unavailable or charging
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
}
private List<String> getIgnoredIconSlots() {
@@ -480,9 +472,6 @@
super.onAttachedToWindow();
mStatusBarIconController.addIconGroup(mIconManager);
requestApplyInsets();
- mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mPercentSettingObserver,
- ActivityManager.getCurrentUser());
}
@Override
@@ -521,7 +510,6 @@
public void onDetachedFromWindow() {
setListening(false);
mStatusBarIconController.removeIconGroup(mIconManager);
- mContext.getContentResolver().unregisterContentObserver(mPercentSettingObserver);
super.onDetachedFromWindow();
}
@@ -743,25 +731,4 @@
lp.rightMargin = sideMargins;
}
}
-
- private void updateShowPercent() {
- final boolean systemSetting = 0 != Settings.System
- .getIntForUser(getContext().getContentResolver(),
- SHOW_BATTERY_PERCENT, 0, ActivityManager.getCurrentUser());
-
- mBatteryRemainingIcon.setPercentShowMode(systemSetting
- ? BatteryMeterView.MODE_ESTIMATE : BatteryMeterView.MODE_ON);
- }
-
- private final class PercentSettingObserver extends ContentObserver {
- PercentSettingObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- super.onChange(selfChange, uri);
- updateShowPercent();
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index a9fe3b2..dfbb32e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -581,13 +581,12 @@
if (!updateMonitor.isUnlockingWithBiometricAllowed()) {
return;
}
- ColorStateList errorColorState = Utils.getColorError(mContext);
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
- errorColorState);
+ mInitialTextColorState);
} else if (updateMonitor.isScreenOn()) {
mLockIcon.setTransientBiometricsError(true);
- showTransientIndication(helpString, errorColorState);
+ showTransientIndication(helpString);
hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
mHandler.removeMessages(MSG_CLEAR_BIOMETRIC_MSG);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_BIOMETRIC_MSG),
@@ -605,7 +604,6 @@
if (shouldSuppressBiometricError(msgId, biometricSourceType, updateMonitor)) {
return;
}
- ColorStateList errorColorState = Utils.getColorError(mContext);
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
// When swiping up right after receiving a biometric error, the bouncer calls
// authenticate leading to the same message being shown again on the bouncer.
@@ -613,10 +611,10 @@
// generic.
if (mLastSuccessiveErrorMessage != msgId) {
mStatusBarKeyguardViewManager.showBouncerMessage(errString,
- errorColorState);
+ mInitialTextColorState);
}
} else if (updateMonitor.isScreenOn()) {
- showTransientIndication(errString, errorColorState);
+ showTransientIndication(errString);
// We want to keep this message around in case the screen was off
hideTransientIndicationDelayed(HIDE_DELAY_MS);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 4690aeb..7850035 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -328,22 +328,10 @@
if (mExpandedChild != null
&& mExpandedWrapper.getNotificationHeader() != null) {
NotificationHeaderView expandedHeader = mExpandedWrapper.getNotificationHeader();
- int expandedSize = expandedHeader.getMeasuredWidth()
- - expandedHeader.getPaddingEnd();
- int collapsedSize = contractedHeader.getMeasuredWidth()
- - expandedHeader.getPaddingEnd();
- if (expandedSize != collapsedSize) {
- int paddingEnd = contractedHeader.getMeasuredWidth() - expandedSize;
- contractedHeader.setPadding(
- contractedHeader.isLayoutRtl()
- ? paddingEnd
- : contractedHeader.getPaddingLeft(),
- contractedHeader.getPaddingTop(),
- contractedHeader.isLayoutRtl()
- ? contractedHeader.getPaddingLeft()
- : paddingEnd,
- contractedHeader.getPaddingBottom());
- contractedHeader.setShowWorkBadgeAtEnd(true);
+
+ int headerTextMargin = expandedHeader.getHeaderTextMarginEnd();
+ if (headerTextMargin != contractedHeader.getHeaderTextMarginEnd()) {
+ contractedHeader.setHeaderTextMarginEnd(headerTextMargin);
return true;
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 60015ef..64e76d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -43,18 +43,15 @@
private static final int STATE_LOCKED = 0;
private static final int STATE_LOCK_OPEN = 1;
- private static final int STATE_FACE_UNLOCK = 2;
- private static final int STATE_FINGERPRINT = 3;
- private static final int STATE_BIOMETRICS_ERROR = 4;
+ private static final int STATE_SCANNING_FACE = 2;
+ private static final int STATE_BIOMETRICS_ERROR = 3;
private int mLastState = 0;
private boolean mTransientBiometricsError;
private boolean mScreenOn;
private boolean mLastScreenOn;
- private Drawable mUserAvatarIcon;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
- private boolean mHasFingerPrintState;
private boolean mIsFaceUnlockState;
private int mDensity;
private boolean mPulsing;
@@ -77,7 +74,6 @@
@Override
public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
- mUserAvatarIcon = picture;
update();
}
@@ -110,10 +106,8 @@
public void update(boolean force) {
int state = getState();
- boolean anyFingerprintState = state == STATE_FINGERPRINT
- || state == STATE_BIOMETRICS_ERROR;
- mIsFaceUnlockState = state == STATE_FACE_UNLOCK;
- if (state != mLastState || mLastDozing == mDozing || mLastPulsing == mPulsing
+ mIsFaceUnlockState = state == STATE_SCANNING_FACE;
+ if (state != mLastState || mLastDozing != mDozing || mLastPulsing != mPulsing
|| mLastScreenOn != mScreenOn || force) {
int iconAnimRes = getAnimationResForTransition(mLastState, state, mLastPulsing,
mPulsing, mLastDozing, mDozing);
@@ -138,7 +132,6 @@
R.string.accessibility_scanning_face));
}
- mHasFingerPrintState = anyFingerprintState;
if (animation != null && isAnim) {
animation.forceAnimationOnUI();
animation.start();
@@ -178,7 +171,10 @@
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
- if (mHasFingerPrintState) {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning();
+ boolean unlockingAllowed = updateMonitor.isUnlockingWithBiometricAllowed();
+ if (fingerprintRunning && unlockingAllowed) {
AccessibilityNodeInfo.AccessibilityAction unlock
= new AccessibilityNodeInfo.AccessibilityAction(
AccessibilityNodeInfo.ACTION_CLICK,
@@ -201,21 +197,16 @@
private Drawable getIconForState(int state) {
int iconRes;
switch (state) {
- case STATE_FINGERPRINT:
case STATE_LOCKED:
- case STATE_FACE_UNLOCK:
+ // Scanning animation is a pulsing padlock. This means that the resting state is
+ // just a padlock.
+ case STATE_SCANNING_FACE:
+ // Error animation also starts and ands on the padlock.
+ case STATE_BIOMETRICS_ERROR:
iconRes = com.android.internal.R.drawable.ic_lock_24dp;
break;
case STATE_LOCK_OPEN:
- if (mUnlockMethodCache.isTrustManaged() && mUnlockMethodCache.isTrusted()
- && mUserAvatarIcon != null) {
- return mUserAvatarIcon;
- } else {
- iconRes = com.android.internal.R.drawable.ic_lock_open_24dp;
- }
- break;
- case STATE_BIOMETRICS_ERROR:
- iconRes = com.android.internal.R.drawable.ic_auth_error;
+ iconRes = com.android.internal.R.drawable.ic_lock_open_24dp;
break;
default:
throw new IllegalArgumentException();
@@ -224,22 +215,28 @@
return mContext.getDrawable(iconRes);
}
- private int getAnimationResForTransition(int oldState, int newState,
+ private static int getAnimationResForTransition(int oldState, int newState,
boolean wasPulsing, boolean pulsing,
boolean wasDozing, boolean dozing) {
- boolean isError = newState == STATE_BIOMETRICS_ERROR;
- boolean isUnlocked = newState == STATE_LOCK_OPEN;
- boolean isLocked = !isUnlocked;
- boolean wasUnlocked = oldState == STATE_LOCK_OPEN;
+ // Never animate when screen is off
+ if (dozing && !pulsing) {
+ return -1;
+ }
+
+ boolean isError = oldState != STATE_BIOMETRICS_ERROR && newState == STATE_BIOMETRICS_ERROR;
+ boolean justUnlocked = oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN;
+ boolean justLocked = oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED;
if (isError) {
return com.android.internal.R.anim.lock_to_error;
- } else if (isUnlocked) {
+ } else if (justUnlocked) {
return com.android.internal.R.anim.lock_unlock;
- } else if (wasUnlocked && isLocked && mScreenOn) {
+ } else if (justLocked) {
return com.android.internal.R.anim.lock_lock;
- } else if (isLocked && (!wasPulsing && pulsing || wasDozing && !dozing)) {
+ } else if (newState == STATE_SCANNING_FACE) {
+ return com.android.internal.R.anim.lock_scanning;
+ } else if (!wasPulsing && pulsing) {
return com.android.internal.R.anim.lock_in;
}
return -1;
@@ -247,17 +244,13 @@
private int getState() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
- boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning();
- boolean unlockingAllowed = updateMonitor.isUnlockingWithBiometricAllowed();
if (mTransientBiometricsError) {
return STATE_BIOMETRICS_ERROR;
} else if (mUnlockMethodCache.canSkipBouncer()) {
return STATE_LOCK_OPEN;
} else if (mUnlockMethodCache.isFaceUnlockRunning()
|| updateMonitor.isFaceDetectionRunning()) {
- return STATE_FACE_UNLOCK;
- } else if (fingerprintRunning && unlockingAllowed) {
- return STATE_FINGERPRINT;
+ return STATE_SCANNING_FACE;
} else {
return STATE_LOCKED;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 5e94152..111cdd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
+import android.annotation.Nullable;
+
import com.android.systemui.DemoMode;
import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
@@ -78,6 +80,6 @@
* The callback
* @param estimate the estimate
*/
- void onBatteryRemainingEstimateRetrieved(String estimate);
+ void onBatteryRemainingEstimateRetrieved(@Nullable String estimate);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 3fa3e1a..273fa55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -237,10 +237,10 @@
mFetchingEstimate = true;
Dependency.get(Dependency.BG_HANDLER).post(() -> {
- mEstimate = mEstimates.getEstimate();
+ // Only fetch the estimate if they are enabled
+ mEstimate = mEstimates.isHybridNotificationEnabled() ? mEstimates.getEstimate() : null;
mLastEstimateTimestamp = System.currentTimeMillis();
mFetchingEstimate = false;
-
Dependency.get(Dependency.MAIN_HANDLER).post(this::notifyEstimateFetchCallbacks);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index b561ac1..db2be0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -93,14 +93,28 @@
return null;
}
+ /**
+ * Adds {@code callback} to the controller. The controller will update the callback on state
+ * changes. It will immediately trigger the callback added to notify current state.
+ * @param callback
+ */
@Override
public void addCallback(Callback callback) {
synchronized (mCallbacks) {
if (callback == null || mCallbacks.contains(callback)) return;
if (DEBUG) Log.d(TAG, "addCallback " + callback);
mCallbacks.add(callback);
-
- updateWifiStateListeners(!mCallbacks.isEmpty());
+ if (mWifiManager != null) {
+ if (mCallbacks.size() == 1) {
+ mWifiManager.registerSoftApCallback(this, mMainHandler);
+ } else {
+ // mWifiManager#registerSoftApCallback triggers a call to onNumClientsChanged
+ // on the Main Handler. In order to always update the callback on added, we
+ // make this call when adding callbacks after the first.
+ mMainHandler.post(() ->
+ callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices));
+ }
+ }
}
}
@@ -110,27 +124,9 @@
if (DEBUG) Log.d(TAG, "removeCallback " + callback);
synchronized (mCallbacks) {
mCallbacks.remove(callback);
- updateWifiStateListeners(!mCallbacks.isEmpty());
- }
- }
-
- /**
- * Updates the wifi state receiver to either start or stop listening to get updates to the
- * hotspot status. Additionally starts listening to wifi manager state to track the number of
- * connected devices.
- *
- * @param shouldListen whether we should start listening to various wifi statuses
- */
- private void updateWifiStateListeners(boolean shouldListen) {
- if (mWifiManager == null) {
- return;
- }
- if (shouldListen) {
- mWifiManager.registerSoftApCallback(
- this,
- mMainHandler);
- } else {
- mWifiManager.unregisterSoftApCallback(this);
+ if (mCallbacks.isEmpty() && mWifiManager != null) {
+ mWifiManager.unregisterSoftApCallback(this);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
index 943d927..cf25a9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
@@ -177,6 +177,7 @@
}
@Test
+ @Ignore("Occasionally flakes, ignoring pending investigation.")
public void testChildRemoved() throws InterruptedException {
assertEquals(0, mLayout.getTransientViewCount());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
new file mode 100644
index 0000000..3e4c4d6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class HotspotControllerImplTest extends SysuiTestCase {
+
+ @Mock
+ private ConnectivityManager mConnectivityManager;
+ @Mock
+ private WifiManager mWifiManager;
+ @Mock
+ private HotspotController.Callback mCallback1;
+ @Mock
+ private HotspotController.Callback mCallback2;
+ private HotspotControllerImpl mController;
+ private TestableLooper mLooper;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLooper = TestableLooper.get(this);
+
+ mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
+ mContext.addMockSystemService(WifiManager.class, mWifiManager);
+
+ doAnswer((InvocationOnMock invocation) -> {
+ ((WifiManager.SoftApCallback) invocation.getArgument(0)).onNumClientsChanged(1);
+ return null;
+ }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class),
+ any(Handler.class));
+
+ mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper()));
+ }
+
+ @Test
+ public void testAddingTwoCallbacksRegistersToWifiManagerOnce() {
+ mController.addCallback(mCallback1);
+ mController.addCallback(mCallback2);
+
+ verify(mWifiManager, times(1)).registerSoftApCallback(eq(mController), any());
+ }
+
+ @Test
+ public void testAddingCallbacksDoesntUpdateAll() {
+ mController.addCallback(mCallback1);
+ mController.addCallback(mCallback2);
+
+ mLooper.processAllMessages();
+ // Each callback should be updated only once
+ verify(mCallback1, times(1)).onHotspotChanged(anyBoolean(), anyInt());
+ verify(mCallback2, times(1)).onHotspotChanged(anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void testRemovingTwoCallbacksUnegistersToWifiManagerOnce() {
+ mController.addCallback(mCallback1);
+ mController.addCallback(mCallback2);
+
+ mController.removeCallback(mCallback1);
+ mController.removeCallback(mCallback2);
+
+ verify(mWifiManager, times(1)).unregisterSoftApCallback(mController);
+ }
+
+ @Test
+ public void testDoNotUnregisterIfRemainingCallbacks() {
+ mController.addCallback(mCallback1);
+ mController.addCallback(mCallback2);
+
+ verify(mWifiManager, never()).unregisterSoftApCallback(any());
+ }
+
+}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9f7a940..52d2334 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -89,11 +89,11 @@
private ActivityManagerInternal mAm;
/**
- * Users disabled by {@link android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED}.
+ * Users disabled by {@link android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED}
*/
@GuardedBy("mLock")
@Nullable
- private SparseBooleanArray mDisabledUsers;
+ private SparseBooleanArray mDisabledBySettings;
/**
* Global kill-switch based on value defined by
@@ -130,18 +130,18 @@
mRequestsHistory = null;
}
- // Sets which services are disabled
+ // Sets which services are disabled by settings
final UserManager um = getContext().getSystemService(UserManager.class);
final List<UserInfo> users = um.getUsers();
for (int i = 0; i < users.size(); i++) {
final int userId = users.get(i).id;
- final boolean disabled = mDisabledByDeviceConfig || isDisabledBySettings(userId);
+ final boolean disabled = !isEnabledBySettings(userId);
if (disabled) {
- Slog.i(mTag, "user " + userId + " disabled by settings or device config");
- if (mDisabledUsers == null) {
- mDisabledUsers = new SparseBooleanArray(1);
+ Slog.i(mTag, "user " + userId + " disabled by settings");
+ if (mDisabledBySettings == null) {
+ mDisabledBySettings = new SparseBooleanArray(1);
}
- mDisabledUsers.put(userId, true);
+ mDisabledBySettings.put(userId, true);
}
}
}
@@ -187,7 +187,8 @@
protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) {
switch (property) {
case Settings.Secure.CONTENT_CAPTURE_ENABLED:
- setContentCaptureFeatureEnabledFromSettings(userId);
+ setContentCaptureFeatureEnabledBySettingsForUser(userId,
+ isEnabledBySettings(userId));
return;
default:
Slog.w(mTag, "Unexpected property (" + property + "); updating cache instead");
@@ -201,31 +202,13 @@
}
private boolean isDisabledBySettingsLocked(@UserIdInt int userId) {
- return mDisabledUsers != null && mDisabledUsers.get(userId);
+ return mDisabledBySettings != null && mDisabledBySettings.get(userId);
}
- private void setContentCaptureFeatureEnabledFromSettings(@UserIdInt int userId) {
- setContentCaptureFeatureEnabledForUser(userId, !isDisabledBySettings(userId));
- }
-
- private boolean isDisabledBySettings(@UserIdInt int userId) {
- final String property = Settings.Secure.CONTENT_CAPTURE_ENABLED;
- final String value = Settings.Secure.getStringForUser(getContext().getContentResolver(),
- property, userId);
- if (value == null) {
- if (verbose) {
- Slog.v(mTag, "isDisabledBySettings(): assuming false as '" + property
- + "' is not set");
- }
- return false;
- }
-
- try {
- return !Boolean.valueOf(value);
- } catch (Exception e) {
- Slog.w(mTag, "Invalid value for property " + property + ": " + value);
- }
- return false;
+ private boolean isEnabledBySettings(@UserIdInt int userId) {
+ final boolean enabled = Settings.Secure.getIntForUser(getContext().getContentResolver(),
+ Settings.Secure.CONTENT_CAPTURE_ENABLED, 1, userId) == 1 ? true : false;
+ return enabled;
}
private void onDeviceConfigChange(@NonNull String key, @Nullable String value) {
@@ -331,12 +314,13 @@
}
}
- private void setContentCaptureFeatureEnabledForUser(@UserIdInt int userId, boolean enabled) {
+ private void setContentCaptureFeatureEnabledBySettingsForUser(@UserIdInt int userId,
+ boolean enabled) {
synchronized (mLock) {
- if (mDisabledUsers == null) {
- mDisabledUsers = new SparseBooleanArray();
+ if (mDisabledBySettings == null) {
+ mDisabledBySettings = new SparseBooleanArray();
}
- final boolean alreadyEnabled = !mDisabledUsers.get(userId);
+ final boolean alreadyEnabled = !mDisabledBySettings.get(userId);
if (!(enabled ^ alreadyEnabled)) {
if (debug) {
Slog.d(mTag, "setContentCaptureFeatureEnabledForUser(): already " + enabled);
@@ -346,13 +330,14 @@
if (enabled) {
Slog.i(mTag, "setContentCaptureFeatureEnabled(): enabling service for user "
+ userId);
- mDisabledUsers.delete(userId);
+ mDisabledBySettings.delete(userId);
} else {
Slog.i(mTag, "setContentCaptureFeatureEnabled(): disabling service for user "
+ userId);
- mDisabledUsers.put(userId, true);
+ mDisabledBySettings.put(userId, true);
}
- updateCachedServiceLocked(userId, !enabled);
+ final boolean disabled = !enabled || mDisabledByDeviceConfig;
+ updateCachedServiceLocked(userId, disabled);
}
}
@@ -472,7 +457,7 @@
final String prefix2 = prefix + " ";
- pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers);
+ pw.print(prefix); pw.print("Users disabled by Settings: "); pw.println(mDisabledBySettings);
pw.print(prefix); pw.println("DeviceConfig Settings: ");
pw.print(prefix2); pw.print("disabled: "); pw.println(mDisabledByDeviceConfig);
pw.print(prefix2); pw.print("loggingLevel: "); pw.println(mDevCfgLoggingLevel);
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index 9df09b9..9185cb6 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -494,7 +494,7 @@
final long token = Binder.clearCallingIdentity();
try {
Settings.Secure.putStringForUser(getContext().getContentResolver(),
- Settings.Secure.CONTENT_CAPTURE_ENABLED, "false", mUserId);
+ Settings.Secure.CONTENT_CAPTURE_ENABLED, "0", mUserId);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index da89116..219e046 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3792,10 +3792,10 @@
* if it's really needed.
*/
@Override
- public void getLatestTetheringEntitlementValue(int type, ResultReceiver receiver,
+ public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
boolean showEntitlementUi, String callerPkg) {
ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTethering.getLatestTetheringEntitlementValue(type, receiver, showEntitlementUi);
+ mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
}
// Called when we lose the default network and have no replacement yet.
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 13ff30d..3b4b6f8 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1677,10 +1677,10 @@
}
/** Get the latest value of the tethering entitlement check. */
- public void getLatestTetheringEntitlementValue(int type, ResultReceiver receiver,
+ public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
boolean showEntitlementUi) {
if (receiver != null) {
- mEntitlementMgr.getLatestTetheringEntitlementValue(type, receiver, showEntitlementUi);
+ mEntitlementMgr.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
}
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
index 75aac10..65cc516 100644
--- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
+++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
@@ -291,7 +291,7 @@
}
/** Get the last value of the tethering entitlement check. */
- public void getLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver,
+ public void getLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver,
boolean showEntitlementUi) {
if (!isTetherProvisioningRequired()) {
receiver.send(TETHER_ERROR_NO_ERROR, null);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 15a00d5..b64b7c64 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -14698,14 +14698,10 @@
@Override
public void onReceive(Context context, Intent intent) {
// the duration to wait for rollback to be enabled, in millis
- long rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT;
- try {
- rollbackTimeout = Long.valueOf(
- DeviceConfig.getProperty(
- DeviceConfig.Rollback.NAMESPACE,
- DeviceConfig.Rollback.ENABLE_ROLLBACK_TIMEOUT));
- } catch (NumberFormatException ignore) {
- }
+ long rollbackTimeout = DeviceConfig.getLong(
+ DeviceConfig.Rollback.NAMESPACE,
+ DeviceConfig.Rollback.ENABLE_ROLLBACK_TIMEOUT,
+ DEFAULT_ENABLE_ROLLBACK_TIMEOUT);
final Message msg = mHandler.obtainMessage(
ENABLE_ROLLBACK_TIMEOUT);
msg.arg1 = enableRollbackToken;
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index e241ba6..d3e1a05 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -531,17 +531,10 @@
}
private void updateRollbackLifetimeDurationInMillis() {
- String strRollbackLifetimeInMillis = DeviceConfig.getProperty(
+ mRollbackLifetimeDurationInMillis = DeviceConfig.getLong(
DeviceConfig.Rollback.BOOT_NAMESPACE,
- DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS);
-
- try {
- mRollbackLifetimeDurationInMillis = (strRollbackLifetimeInMillis == null)
- ? DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS
- : Long.parseLong(strRollbackLifetimeInMillis);
- } catch (NumberFormatException e) {
- mRollbackLifetimeDurationInMillis = DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS;
- }
+ DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
+ DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS);
}
void onBootCompleted() {
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index 4cf2344..765e347 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -98,6 +98,7 @@
mBuffer.resetBuffer();
mEnabled = mEnabledLockFree = true;
}
+ log("trace.enable");
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 763ea62..a03d28b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -40,7 +40,6 @@
import android.view.IRecentsAnimationRunner;
import android.view.SurfaceControl;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -113,7 +112,6 @@
}
@Test
- @FlakyTest(bugId = 117117823)
public void testIncludedApps_expectTargetAndVisible() {
mWm.setRecentsAnimationController(mController);
final AppWindowToken homeAppWindow = createAppWindowToken(mDisplayContent,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 42a205a..b140da5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -100,7 +100,6 @@
}
@Test
- @FlakyTest(detail = "Promote to presubmit when shown to be stable.")
public void testTaskDescriptionChanged() throws Exception {
final Object[] params = new Object[2];
final CountDownLatch latch = new CountDownLatch(1);
@@ -133,7 +132,6 @@
}
@Test
- @FlakyTest(detail = "Promote to presubmit when shown to be stable.")
public void testActivityRequestedOrientationChanged() throws Exception {
final int[] params = new int[2];
final CountDownLatch latch = new CountDownLatch(1);
@@ -214,6 +212,7 @@
// Test for onTaskRemovalStarted.
assertEquals(1, taskRemovalStartedLatch.getCount());
+ assertEquals(1, taskRemovedLatch.getCount());
activity.finishAndRemoveTask();
waitForCallback(taskRemovalStartedLatch);
// onTaskRemovalStarted happens before the activity's window is removed.
@@ -221,7 +220,6 @@
assertEquals(id, params[0]);
// Test for onTaskRemoved.
- assertEquals(1, taskRemovedLatch.getCount());
waitForCallback(taskRemovedLatch);
assertEquals(id, params[0]);
waitForCallback(onDetachedFromWindowLatch);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index 8358fdd..e3691c6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -20,6 +20,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
@@ -124,7 +125,7 @@
public void trace_dumpsWindowManagerState_whenTracing() throws Exception {
mWindowTracing.startTrace(mock(PrintWriter.class));
mWindowTracing.logState("where");
- verify(mWmMock).writeToProtoLocked(any(), eq(WindowTraceLogLevel.TRIM));
+ verify(mWmMock, times(2)).writeToProtoLocked(any(), eq(WindowTraceLogLevel.TRIM));
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
index d685e8c..3944fad 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
@@ -226,7 +226,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, true);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
callbackTimeoutHelper(mCallbacklatch);
assertFalse(mEnMgr.everRunUiEntitlement);
@@ -242,7 +242,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, false);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
callbackTimeoutHelper(mCallbacklatch);
assertFalse(mEnMgr.everRunUiEntitlement);
// 3. No cache value and ui entitlement check is needed.
@@ -255,7 +255,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, true);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
assertTrue(mEnMgr.everRunUiEntitlement);
@@ -269,7 +269,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, false);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
callbackTimeoutHelper(mCallbacklatch);
assertFalse(mEnMgr.everRunUiEntitlement);
// 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed.
@@ -282,7 +282,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, true);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
mLooper.dispatchAll();
callbackTimeoutHelper(mCallbacklatch);
assertTrue(mEnMgr.everRunUiEntitlement);
@@ -296,7 +296,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_WIFI, receiver, true);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
callbackTimeoutHelper(mCallbacklatch);
assertFalse(mEnMgr.everRunUiEntitlement);
// 7. Test get value for other downstream type.
@@ -308,7 +308,7 @@
mCallbacklatch.countDown();
}
};
- mEnMgr.getLatestTetheringEntitlementValue(TETHERING_USB, receiver, false);
+ mEnMgr.getLatestTetheringEntitlementResult(TETHERING_USB, receiver, false);
callbackTimeoutHelper(mCallbacklatch);
assertFalse(mEnMgr.everRunUiEntitlement);
}
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index bc3a9a1..8bef221 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -141,6 +141,7 @@
"ResourceValues.cpp",
"SdkConstants.cpp",
"StringPool.cpp",
+ "trace/TraceBuffer.cpp",
"xml/XmlActionExecutor.cpp",
"xml/XmlDom.cpp",
"xml/XmlPullParser.cpp",
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index adf85b0..39eb987 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -37,6 +37,7 @@
#include "cmd/Link.h"
#include "cmd/Optimize.h"
#include "io/FileStream.h"
+#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "util/Util.h"
@@ -107,9 +108,12 @@
: Command("daemon", "m"), out_(out), diagnostics_(diagnostics) {
SetDescription("Runs aapt in daemon mode. Each subsequent line is a single parameter to the\n"
"command. The end of an invocation is signaled by providing an empty line.");
+ AddOptionalFlag("--trace_folder", "Generate systrace json trace fragment to specified folder.",
+ &trace_folder_);
}
- int Action(const std::vector<std::string>& /* args */) override {
+ int Action(const std::vector<std::string>& arguments) override {
+ TRACE_FLUSH_ARGS(trace_folder_ ? trace_folder_.value() : "", "daemon", arguments);
text::Printer printer(out_);
std::cout << "Ready" << std::endl;
@@ -150,6 +154,7 @@
private:
io::FileOutputStream* out_;
IDiagnostics* diagnostics_;
+ Maybe<std::string> trace_folder_;
};
} // namespace aapt
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index dbd0a0c..7c0619f 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -30,6 +30,7 @@
#include "NameMangler.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
+#include "trace/TraceBuffer.h"
#include "text/Unicode.h"
#include "util/Util.h"
@@ -79,6 +80,7 @@
}
ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) {
+ TRACE_CALL();
ResourceTablePackage* package = FindOrCreatePackage(name);
if (id && !package->id) {
package->id = id;
diff --git a/tools/aapt2/cmd/Command.cpp b/tools/aapt2/cmd/Command.cpp
index 4424a35..919b4c9 100644
--- a/tools/aapt2/cmd/Command.cpp
+++ b/tools/aapt2/cmd/Command.cpp
@@ -25,6 +25,7 @@
#include "android-base/utf8.h"
#include "androidfw/StringPiece.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
using android::base::StringPrintf;
@@ -178,6 +179,7 @@
}
int Command::Execute(const std::vector<StringPiece>& args, std::ostream* out_error) {
+ TRACE_NAME_ARGS("Command::Execute", args);
std::vector<std::string> file_args;
for (size_t i = 0; i < args.size(); i++) {
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index bec6c69..42dc74c 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -45,6 +45,7 @@
#include "io/StringStream.h"
#include "io/Util.h"
#include "io/ZipArchive.h"
+#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "util/Maybe.h"
#include "util/Util.h"
@@ -141,6 +142,7 @@
static bool CompileTable(IAaptContext* context, const CompileOptions& options,
const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
+ TRACE_CALL();
ResourceTable table;
{
auto fin = file->OpenInputStream();
@@ -286,6 +288,7 @@
static bool WriteHeaderAndDataToWriter(const StringPiece& output_path, const ResourceFile& file,
io::KnownSizeInputStream* in, IArchiveWriter* writer,
IDiagnostics* diag) {
+ TRACE_CALL();
// Start the entry so we can write the header.
if (!writer->StartEntry(output_path, 0)) {
diag->Error(DiagMessage(output_path) << "failed to open file");
@@ -352,6 +355,7 @@
static bool CompileXml(IAaptContext* context, const CompileOptions& options,
const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML");
}
@@ -451,6 +455,7 @@
static bool CompilePng(IAaptContext* context, const CompileOptions& options,
const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling PNG");
}
@@ -558,6 +563,7 @@
static bool CompileFile(IAaptContext* context, const CompileOptions& options,
const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
const std::string& output_path) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling file");
}
@@ -632,6 +638,7 @@
int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
CompileOptions& options) {
+ TRACE_CALL();
bool error = false;
// Iterate over the input files in a stable, platform-independent manner
@@ -707,6 +714,7 @@
}
int CompileCommand::Action(const std::vector<std::string>& args) {
+ TRACE_FLUSH(trace_folder_? trace_folder_.value() : "", "CompileCommand::Action");
CompileContext context(diagnostic_);
context.SetVerbose(options_.verbose);
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 9b32cb3..d3456b2 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -60,6 +60,8 @@
"Sets the visibility of the compiled resources to the specified\n"
"level. Accepted levels: public, private, default", &visibility_);
AddOptionalSwitch("-v", "Enables verbose logging", &options_.verbose);
+ AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.",
+ &trace_folder_);
}
int Action(const std::vector<std::string>& args) override;
@@ -68,6 +70,7 @@
IDiagnostics* diagnostic_;
CompileOptions options_;
Maybe<std::string> visibility_;
+ Maybe<std::string> trace_folder_;
};
int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index a7b8d25..f354bb6 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -67,6 +67,7 @@
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
#include "split/TableSplitter.h"
+#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "xml/XmlDom.h"
@@ -213,6 +214,7 @@
static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res,
const StringPiece& path, bool keep_raw_values, bool utf16,
OutputFormat format, IArchiveWriter* writer) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage(path) << "writing to archive (keep_raw_values="
<< (keep_raw_values ? "true" : "false")
@@ -250,6 +252,7 @@
// Inflates an XML file from the source path.
static std::unique_ptr<xml::XmlResource> LoadXml(const std::string& path, IDiagnostics* diag) {
+ TRACE_CALL();
FileInputStream fin(path);
if (fin.HadError()) {
diag->Error(DiagMessage(path) << "failed to load XML file: " << fin.GetError());
@@ -421,6 +424,7 @@
std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVersionXmlFile(
ResourceTable* table, FileOperation* file_op) {
+ TRACE_CALL();
xml::XmlResource* doc = file_op->xml_to_flatten.get();
const Source& src = doc->file.source;
@@ -489,6 +493,7 @@
};
bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archive_writer) {
+ TRACE_CALL();
bool error = false;
std::map<std::pair<ConfigDescription, StringPiece>, FileOperation> config_sorted_files;
@@ -806,6 +811,7 @@
// Creates a SymbolTable that loads symbols from the various APKs.
// Pre-condition: context_->GetCompilationPackage() needs to be set.
bool LoadSymbolsFromIncludePaths() {
+ TRACE_NAME("LoadSymbolsFromIncludePaths: #" + std::to_string(options_.include_paths.size()));
auto asset_source = util::make_unique<AssetManagerSymbolSource>();
for (const std::string& path : options_.include_paths) {
if (context_->IsVerbose()) {
@@ -891,6 +897,7 @@
}
Maybe<AppInfo> ExtractAppInfoFromManifest(xml::XmlResource* xml_res, IDiagnostics* diag) {
+ TRACE_CALL();
// Make sure the first element is <manifest> with package attribute.
xml::Element* manifest_el = xml::FindRootElement(xml_res->root.get());
if (manifest_el == nullptr) {
@@ -1041,6 +1048,7 @@
}
bool FlattenTable(ResourceTable* table, OutputFormat format, IArchiveWriter* writer) {
+ TRACE_CALL();
switch (format) {
case OutputFormat::kApk: {
BigBuffer buffer(1024);
@@ -1114,6 +1122,7 @@
}
bool GenerateJavaClasses() {
+ TRACE_CALL();
// The set of packages whose R class to call in the main classes onResourcesLoaded callback.
std::vector<std::string> packages_to_callback;
@@ -1197,6 +1206,7 @@
}
bool WriteManifestJavaFile(xml::XmlResource* manifest_xml) {
+ TRACE_CALL();
if (!options_.generate_java_class_path) {
return true;
}
@@ -1254,6 +1264,7 @@
}
bool WriteProguardFile(const Maybe<std::string>& out, const proguard::KeepSet& keep_set) {
+ TRACE_CALL();
if (!out) {
return true;
}
@@ -1278,6 +1289,7 @@
}
bool MergeStaticLibrary(const std::string& input, bool override) {
+ TRACE_CALL();
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(DiagMessage() << "merging static library " << input);
}
@@ -1328,6 +1340,7 @@
bool MergeExportedSymbols(const Source& source,
const std::vector<SourcedResourceName>& exported_symbols) {
+ TRACE_CALL();
// Add the exports of this file to the table.
for (const SourcedResourceName& exported_symbol : exported_symbols) {
ResourceName res_name = exported_symbol.name;
@@ -1353,6 +1366,7 @@
}
bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
+ TRACE_CALL();
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(DiagMessage()
<< "merging '" << compiled_file.name
@@ -1371,6 +1385,7 @@
// An io::IFileCollection is created from the ZIP file and added to the set of
// io::IFileCollections that are open.
bool MergeArchive(const std::string& input, bool override) {
+ TRACE_CALL();
if (context_->IsVerbose()) {
context_->GetDiagnostics()->Note(DiagMessage() << "merging archive " << input);
}
@@ -1418,6 +1433,7 @@
// All other file types are ignored. This is because these files could be coming from a zip,
// where we could have other files like classes.dex.
bool MergeFile(io::IFile* file, bool override) {
+ TRACE_CALL();
const Source& src = file->GetSource();
if (util::EndsWith(src.path, ".xml") || util::EndsWith(src.path, ".png")) {
@@ -1458,6 +1474,7 @@
while ((entry = reader.Next()) != nullptr) {
if (entry->Type() == ContainerEntryType::kResTable) {
+ TRACE_NAME(std::string("Process ResTable:") + file->GetSource().path);
pb::ResourceTable pb_table;
if (!entry->GetResTable(&pb_table)) {
context_->GetDiagnostics()->Error(DiagMessage(src) << "failed to read resource table: "
@@ -1478,6 +1495,7 @@
return false;
}
} else if (entry->Type() == ContainerEntryType::kResFile) {
+ TRACE_NAME(std::string("Process ResFile") + file->GetSource().path);
pb::internal::CompiledFile pb_compiled_file;
off64_t offset;
size_t len;
@@ -1551,6 +1569,7 @@
// to the IArchiveWriter.
bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
ResourceTable* table) {
+ TRACE_CALL();
const bool keep_raw_values = (context_->GetPackageType() == PackageType::kStaticLib)
|| options_.keep_raw_values;
bool result = FlattenXml(context_, *manifest, kAndroidManifestPath, keep_raw_values,
@@ -1632,6 +1651,7 @@
}
int Run(const std::vector<std::string>& input_files) {
+ TRACE_CALL();
// Load the AndroidManifest.xml
std::unique_ptr<xml::XmlResource> manifest_xml =
LoadXml(options_.manifest_path, context_->GetDiagnostics());
@@ -1839,6 +1859,7 @@
std::vector<ConfigDescription> excluded_configs;
for (auto& config_string : options_.exclude_configs_) {
+ TRACE_NAME("ConfigDescription::Parse");
ConfigDescription config_description;
if (!ConfigDescription::Parse(config_string, &config_description)) {
@@ -2038,6 +2059,7 @@
};
int LinkCommand::Action(const std::vector<std::string>& args) {
+ TRACE_FLUSH(trace_folder_ ? trace_folder_.value() : "", "LinkCommand::Action");
LinkContext context(diag_);
// Expand all argument-files passed into the command line. These start with '@'.
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 1fc149a..7c58385 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -25,6 +25,7 @@
#include "split/TableSplitter.h"
#include "format/binary/TableFlattener.h"
#include "link/ManifestFixer.h"
+#include "trace/TraceBuffer.h"
namespace aapt {
@@ -277,6 +278,8 @@
"Do not allow overlays with different visibility levels.",
&options_.strict_visibility);
AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
+ AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.",
+ &trace_folder_);
}
int Action(const std::vector<std::string>& args) override;
@@ -300,6 +303,7 @@
bool proto_format_ = false;
Maybe<std::string> stable_id_file_path_;
std::vector<std::string> split_args_;
+ Maybe<std::string> trace_folder_;
};
}// namespace aapt
diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp
index 33122dc..d396d81 100644
--- a/tools/aapt2/compile/Png.cpp
+++ b/tools/aapt2/compile/Png.cpp
@@ -27,6 +27,7 @@
#include "androidfw/ResourceTypes.h"
#include "Source.h"
+#include "trace/TraceBuffer.h"
#include "util/BigBuffer.h"
#include "util/Util.h"
@@ -1233,6 +1234,7 @@
bool Png::process(const Source& source, std::istream* input,
BigBuffer* outBuffer, const PngOptions& options) {
+ TRACE_CALL();
png_byte signature[kPngSignatureSize];
// Read the PNG signature first.
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
index 0346a19..1f4ea44d 100644
--- a/tools/aapt2/compile/PngCrunch.cpp
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -27,6 +27,8 @@
#include "android-base/logging.h"
#include "android-base/macros.h"
+#include "trace/TraceBuffer.h"
+
namespace aapt {
// Custom deleter that destroys libpng read and info structs.
@@ -142,6 +144,7 @@
}
std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) {
+ TRACE_CALL();
// Create a diagnostics that has the source information encoded.
SourcePathDiagnostics source_diag(source, context->GetDiagnostics());
@@ -480,6 +483,7 @@
bool WritePng(IAaptContext* context, const Image* image,
const NinePatch* nine_patch, io::OutputStream* out,
const PngOptions& options) {
+ TRACE_CALL();
// Create and initialize the write png_struct with the default error and
// warning handlers.
// The header version is also passed in to ensure that this was built against the same
diff --git a/tools/aapt2/compile/XmlIdCollector.cpp b/tools/aapt2/compile/XmlIdCollector.cpp
index 2199d00..5054115 100644
--- a/tools/aapt2/compile/XmlIdCollector.cpp
+++ b/tools/aapt2/compile/XmlIdCollector.cpp
@@ -22,6 +22,7 @@
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "text/Unicode.h"
+#include "trace/TraceBuffer.h"
#include "xml/XmlDom.h"
namespace aapt {
@@ -72,6 +73,7 @@
} // namespace
bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) {
+ TRACE_CALL();
xmlRes->file.exported_symbols.clear();
SourcePathDiagnostics source_diag(xmlRes->file.source, context->GetDiagnostics());
IdCollector collector(&xmlRes->file.exported_symbols, &source_diag);
diff --git a/tools/aapt2/format/Container.cpp b/tools/aapt2/format/Container.cpp
index d4b4571..f189048 100644
--- a/tools/aapt2/format/Container.cpp
+++ b/tools/aapt2/format/Container.cpp
@@ -19,6 +19,8 @@
#include "android-base/scopeguard.h"
#include "android-base/stringprintf.h"
+#include "trace/TraceBuffer.h"
+
using ::android::base::StringPrintf;
using ::google::protobuf::io::CodedInputStream;
using ::google::protobuf::io::CodedOutputStream;
@@ -171,6 +173,7 @@
}
bool ContainerReaderEntry::GetResTable(pb::ResourceTable* out_table) {
+ TRACE_CALL();
CHECK(type_ == ContainerEntryType::kResTable) << "reading a kResTable when the type is kResFile";
if (length_ > std::numeric_limits<int>::max()) {
reader_->error_ = StringPrintf("entry length %zu is too large", length_);
@@ -261,6 +264,7 @@
total_entry_count_(0u),
current_entry_count_(0u),
entry_(this) {
+ TRACE_CALL();
::google::protobuf::uint32 magic;
if (!coded_in_.ReadLittleEndian32(&magic)) {
std::ostringstream error;
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index d677317..aa578a2 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -32,6 +32,7 @@
#include "ValueVisitor.h"
#include "format/binary/ChunkWriter.h"
#include "format/binary/ResourceTypeExtensions.h"
+#include "trace/TraceBuffer.h"
#include "util/BigBuffer.h"
using namespace android;
@@ -238,6 +239,7 @@
}
bool FlattenPackage(BigBuffer* buffer) {
+ TRACE_CALL();
ChunkWriter pkg_writer(buffer);
ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
pkg_header->id = util::HostToDevice32(package_->id.value());
@@ -710,6 +712,7 @@
} // namespace
bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_CALL();
// We must do this before writing the resources, since the string pool IDs may change.
table->string_pool.Prune();
table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int {
diff --git a/tools/aapt2/io/Util.cpp b/tools/aapt2/io/Util.cpp
index 9751632..ce6d9352 100644
--- a/tools/aapt2/io/Util.cpp
+++ b/tools/aapt2/io/Util.cpp
@@ -18,6 +18,8 @@
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+#include "trace/TraceBuffer.h"
+
using ::android::StringPiece;
using ::google::protobuf::io::ZeroCopyOutputStream;
@@ -26,6 +28,7 @@
bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, const std::string& out_path,
uint32_t compression_flags, IArchiveWriter* writer) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive");
}
@@ -40,6 +43,7 @@
bool CopyFileToArchive(IAaptContext* context, io::IFile* file, const std::string& out_path,
uint32_t compression_flags, IArchiveWriter* writer) {
+ TRACE_CALL();
std::unique_ptr<io::IData> data = file->OpenAsData();
if (!data) {
context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file");
@@ -57,6 +61,7 @@
bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
const std::string& out_path, uint32_t compression_flags,
IArchiveWriter* writer) {
+ TRACE_CALL();
if (context->IsVerbose()) {
context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive");
}
@@ -83,6 +88,7 @@
}
bool Copy(OutputStream* out, InputStream* in) {
+ TRACE_CALL();
const void* in_buffer;
size_t in_len;
while (in->Next(&in_buffer, &in_len)) {
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 427dc92..f6aaa12 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -20,6 +20,7 @@
#include "ziparchive/zip_archive.h"
#include "Source.h"
+#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "util/Util.h"
@@ -93,6 +94,7 @@
std::unique_ptr<ZipFileCollection> ZipFileCollection::Create(
const StringPiece& path, std::string* out_error) {
+ TRACE_CALL();
constexpr static const int32_t kEmptyArchive = -6;
std::unique_ptr<ZipFileCollection> collection =
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 52e168e..05ba8f0 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -281,6 +281,15 @@
AddClass(node->line_number, result.value(), "");
}
}
+
+ attr = node->FindAttribute(xml::kSchemaAndroid, "zygotePreloadName");
+ if (attr) {
+ Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value);
+ if (result) {
+ AddClass(node->line_number, result.value(), "");
+ }
+ }
+
if (main_dex_only_) {
xml::Attribute* default_process = node->FindAttribute(xml::kSchemaAndroid, "process");
if (default_process) {
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index da24907..559b07a 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -42,6 +42,7 @@
android:appComponentFactory="com.foo.BarAppComponentFactory"
android:backupAgent="com.foo.BarBackupAgent"
android:name="com.foo.BarApplication"
+ android:zygotePreloadName="com.foo.BarZygotePreload"
>
<activity android:name="com.foo.BarActivity"/>
<service android:name="com.foo.BarService"/>
@@ -63,6 +64,7 @@
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarReceiver { <init>(); }"));
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarProvider { <init>(); }"));
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarInstrumentation { <init>(); }"));
+ EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarZygotePreload { <init>(); }"));
actual = GetKeepSetString(set, /** minimal_rules */ true);
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarAppComponentFactory { <init>(); }"));
@@ -73,6 +75,7 @@
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarReceiver { <init>(); }"));
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarProvider { <init>(); }"));
EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarInstrumentation { <init>(); }"));
+ EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarZygotePreload { <init>(); }"));
}
TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) {
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index 960c7d4..73b9254 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -23,6 +23,7 @@
#include "ResourceTable.h"
#include "SdkConstants.h"
#include "ValueVisitor.h"
+#include "trace/TraceBuffer.h"
using android::ConfigDescription;
@@ -70,6 +71,7 @@
}
bool AutoVersioner::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_NAME("AutoVersioner::Consume");
for (auto& package : table->packages) {
for (auto& type : package->types) {
if (type->type != ResourceType::kStyle) {
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 582a5b8..b0a2055 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -21,6 +21,7 @@
#include "android-base/logging.h"
#include "ResourceUtils.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlActionExecutor.h"
#include "xml/XmlDom.h"
@@ -451,6 +452,7 @@
}
bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) {
+ TRACE_CALL();
xml::Element* root = xml::FindRootElement(doc->root.get());
if (!root || !root->namespace_uri.empty() || root->name != "manifest") {
context->GetDiagnostics()->Error(DiagMessage(doc->file.source)
diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp
index c1a95ee..793740a 100644
--- a/tools/aapt2/link/ProductFilter.cpp
+++ b/tools/aapt2/link/ProductFilter.cpp
@@ -17,6 +17,7 @@
#include "link/Linkers.h"
#include "ResourceTable.h"
+#include "trace/TraceBuffer.h"
namespace aapt {
@@ -81,6 +82,7 @@
}
bool ProductFilter::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_NAME("ProductFilter::Consume");
bool error = false;
for (auto& pkg : table->packages) {
for (auto& type : pkg->types) {
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index c2340ba..28f09aa 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -27,6 +27,7 @@
#include "link/Linkers.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlUtil.h"
@@ -353,6 +354,7 @@
}
bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_NAME("ReferenceLinker::Consume");
EmptyDeclStack decl_stack;
bool error = false;
for (auto& package : table->packages) {
diff --git a/tools/aapt2/link/ResourceExcluder.cpp b/tools/aapt2/link/ResourceExcluder.cpp
index 2555995..b3b9dc4 100644
--- a/tools/aapt2/link/ResourceExcluder.cpp
+++ b/tools/aapt2/link/ResourceExcluder.cpp
@@ -20,6 +20,7 @@
#include "DominatorTree.h"
#include "ResourceTable.h"
+#include "trace/TraceBuffer.h"
using android::ConfigDescription;
@@ -65,6 +66,7 @@
} // namespace
bool ResourceExcluder::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_NAME("ResourceExcluder::Consume");
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index cc9fed5..e937517 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -21,6 +21,7 @@
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
+#include "trace/TraceBuffer.h"
#include "ValueVisitor.h"
#include "util/Util.h"
@@ -38,6 +39,7 @@
}
bool TableMerger::Merge(const Source& src, ResourceTable* table, bool overlay) {
+ TRACE_CALL();
// We allow adding new resources if this is not an overlay, or if the options allow overlays
// to add new resources.
return MergeImpl(src, table, overlay, options_.auto_add_overlay || !overlay /*allow_new*/);
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index 160ff92..d68f7dd 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -25,6 +25,7 @@
#include "link/ReferenceLinker.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
#include "xml/XmlDom.h"
@@ -151,6 +152,7 @@
} // namespace
bool XmlReferenceLinker::Consume(IAaptContext* context, xml::XmlResource* resource) {
+ TRACE_NAME("XmlReferenceLinker::Consume");
CallSite callsite{resource->file.name.package};
std::string out_name = resource->file.name.entry;
diff --git a/tools/aapt2/optimize/ResourceDeduper.cpp b/tools/aapt2/optimize/ResourceDeduper.cpp
index ee2dfbc..78ebcb9 100644
--- a/tools/aapt2/optimize/ResourceDeduper.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper.cpp
@@ -20,6 +20,7 @@
#include "DominatorTree.h"
#include "ResourceTable.h"
+#include "trace/TraceBuffer.h"
using android::ConfigDescription;
@@ -110,6 +111,7 @@
} // namespace
bool ResourceDeduper::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_CALL();
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
diff --git a/tools/aapt2/optimize/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp
index f985604..cd791bd 100644
--- a/tools/aapt2/optimize/VersionCollapser.cpp
+++ b/tools/aapt2/optimize/VersionCollapser.cpp
@@ -20,6 +20,7 @@
#include <vector>
#include "ResourceTable.h"
+#include "trace/TraceBuffer.h"
using android::ConfigDescription;
@@ -144,6 +145,7 @@
}
bool VersionCollapser::Consume(IAaptContext* context, ResourceTable* table) {
+ TRACE_NAME("VersionCollapser::Consume");
const int min_sdk = context->GetMinSdkVersion();
for (auto& package : table->packages) {
for (auto& type : package->types) {
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 78e0074..61a8fbb 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -30,6 +30,7 @@
#include "Resource.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
using ::android::ApkAssets;
@@ -217,6 +218,7 @@
}
bool AssetManagerSymbolSource::AddAssetPath(const StringPiece& path) {
+ TRACE_CALL();
if (std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path.data())) {
apk_assets_.push_back(std::move(apk));
@@ -233,6 +235,7 @@
}
std::map<size_t, std::string> AssetManagerSymbolSource::GetAssignedPackageIds() const {
+ TRACE_CALL();
std::map<size_t, std::string> package_map;
asset_manager_.ForEachPackage([&package_map](const std::string& name, uint8_t id) -> bool {
package_map.insert(std::make_pair(id, name));
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 24cd5ba..6a67271 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -27,6 +27,7 @@
#include "androidfw/ConfigDescription.h"
#include "ResourceTable.h"
+#include "trace/TraceBuffer.h"
#include "util/Util.h"
using ::android::ConfigDescription;
@@ -154,6 +155,7 @@
}
}
bool TableSplitter::VerifySplitConstraints(IAaptContext* context) {
+ TRACE_CALL();
bool error = false;
for (size_t i = 0; i < split_constraints_.size(); i++) {
if (split_constraints_[i].configs.size() == 0) {
diff --git a/tools/aapt2/trace/TraceBuffer.cpp b/tools/aapt2/trace/TraceBuffer.cpp
new file mode 100644
index 0000000..b4b31d9
--- /dev/null
+++ b/tools/aapt2/trace/TraceBuffer.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#include "TraceBuffer.h"
+
+#include <chrono>
+#include <sstream>
+#include <unistd.h>
+#include <vector>
+
+#include <inttypes.h>
+
+#include "android-base/utf8.h"
+
+#include "util/Files.h"
+
+namespace aapt {
+namespace tracebuffer {
+
+namespace {
+
+constexpr char kBegin = 'B';
+constexpr char kEnd = 'E';
+
+struct TracePoint {
+ pid_t tid;
+ int64_t time;
+ std::string tag;
+ char type;
+};
+
+std::vector<TracePoint> traces;
+
+int64_t GetTime() noexcept {
+ auto now = std::chrono::steady_clock::now();
+ return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
+}
+
+} // namespace anonymous
+
+void AddWithTime(const std::string& tag, char type, int64_t time) noexcept {
+ TracePoint t = {getpid(), time, tag, type};
+ traces.emplace_back(t);
+}
+
+void Add(const std::string& tag, char type) noexcept {
+ AddWithTime(tag, type, GetTime());
+}
+
+
+
+
+void Flush(const std::string& basePath) {
+ TRACE_CALL();
+ if (basePath.empty()) {
+ return;
+ }
+
+ std::stringstream s;
+ s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json";
+ FILE* f = android::base::utf8::fopen(s.str().c_str(), "a");
+ if (f == nullptr) {
+ return;
+ }
+
+ for(const TracePoint& trace : traces) {
+ fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", "
+ "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
+ }
+ fclose(f);
+ traces.clear();
+}
+
+} // namespace tracebuffer
+
+void BeginTrace(const std::string& tag) {
+ tracebuffer::Add(tag, tracebuffer::kBegin);
+}
+
+void EndTrace() {
+ tracebuffer::Add("", tracebuffer::kEnd);
+}
+
+Trace::Trace(const std::string& tag) {
+ tracebuffer::Add(tag, tracebuffer::kBegin);
+}
+
+Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) {
+ std::stringstream s;
+ s << tag;
+ s << " ";
+ for (auto& arg : args) {
+ s << arg.to_string();
+ s << " ";
+ }
+ tracebuffer::Add(s.str(), tracebuffer::kBegin);
+}
+
+Trace::~Trace() {
+ tracebuffer::Add("", tracebuffer::kEnd);
+}
+
+FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag)
+ : basepath_(basepath) {
+ tracebuffer::Add(tag, tracebuffer::kBegin);
+}
+
+FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
+ const std::vector<android::StringPiece>& args) : basepath_(basepath) {
+ std::stringstream s;
+ s << tag;
+ s << " ";
+ for (auto& arg : args) {
+ s << arg.to_string();
+ s << " ";
+ }
+ tracebuffer::Add(s.str(), tracebuffer::kBegin);
+}
+
+FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
+ const std::vector<std::string>& args) : basepath_(basepath){
+ std::stringstream s;
+ s << tag;
+ s << " ";
+ for (auto& arg : args) {
+ s << arg;
+ s << " ";
+ }
+ tracebuffer::Add(s.str(), tracebuffer::kBegin);
+}
+
+FlushTrace::~FlushTrace() {
+ tracebuffer::Add("", tracebuffer::kEnd);
+ tracebuffer::Flush(basepath_);
+}
+
+} // namespace aapt
+
diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h
new file mode 100644
index 0000000..8618e0e
--- /dev/null
+++ b/tools/aapt2/trace/TraceBuffer.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef AAPT_TRACEBUFFER_H
+#define AAPT_TRACEBUFFER_H
+
+#include <string>
+#include <vector>
+
+#include <androidfw/StringPiece.h>
+
+namespace aapt {
+
+// Record timestamps for beginning and end of a task and generate systrace json fragments.
+// This is an in-process ftrace which has the advantage of being platform independent.
+// These methods are NOT thread-safe since aapt2 is not multi-threaded.
+
+// Convenience RIAA object to automatically finish an event when object goes out of scope.
+class Trace {
+public:
+ Trace(const std::string& tag);
+ Trace(const std::string& tag, const std::vector<android::StringPiece>& args);
+ ~Trace();
+};
+
+// Manual markers.
+void BeginTrace(const std::string& tag);
+void EndTrace();
+
+// A master trace is required to flush events to disk. Events are formatted in systrace
+// json format.
+class FlushTrace {
+public:
+ explicit FlushTrace(const std::string& basepath, const std::string& tag);
+ explicit FlushTrace(const std::string& basepath, const std::string& tag,
+ const std::vector<android::StringPiece>& args);
+ explicit FlushTrace(const std::string& basepath, const std::string& tag,
+ const std::vector<std::string>& args);
+ ~FlushTrace();
+private:
+ std::string basepath_;
+};
+
+#define TRACE_CALL() Trace __t(__func__)
+#define TRACE_NAME(tag) Trace __t(tag)
+#define TRACE_NAME_ARGS(tag, args) Trace __t(tag, args)
+
+#define TRACE_FLUSH(basename, tag) FlushTrace __t(basename, tag)
+#define TRACE_FLUSH_ARGS(basename, tag, args) FlushTrace __t(basename, tag, args)
+} // namespace aapt
+#endif //AAPT_TRACEBUFFER_H
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index acd07c2..9a725fa 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -26,6 +26,7 @@
#include "android-base/logging.h"
#include "ResourceUtils.h"
+#include "trace/TraceBuffer.h"
#include "XmlPullParser.h"
#include "util/Util.h"
@@ -264,6 +265,7 @@
}
std::unique_ptr<XmlResource> Inflate(const void* data, size_t len, std::string* out_error) {
+ TRACE_CALL();
// We import the android namespace because on Windows NO_ERROR is a macro, not
// an enum, which causes errors when qualifying it with android::
using namespace android;